Version 2.5.0-dev.1.0

Merge commit '33a5745c495f6a12af9d0fea2441a962ab63a540' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dac2a39..d3d7263 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,40 +6,48 @@
 
 ### Core libraries
 
-* As part of (Issue [36900][]), the following methods and properties across
-  various core libraries, which used to declare a return type of `List<int>`,
-  were updated to declare a return type of `Uint8List`:
+* **Breaking change** [#36900](https://github.com/dart-lang/sdk/issues/36900):
+  The following methods and
+  properties across various core libraries, which used to declare a return type
+  of `List<int>`, were updated to declare a return type of `Uint8List`:
 
-  * `Utf8Codec.encode()` (and `Utf8Encoder.convert()`)
   * `BytesBuilder.takeBytes()`
   * `BytesBuilder.toBytes()`
+  * `Datagram.data`
   * `File.readAsBytes()` (`Future<Uint8List>`)
   * `File.readAsBytesSync()`
+  * `InternetAddress.rawAddress`
   * `RandomAccessFile.read()` (`Future<Uint8List>`)
   * `RandomAccessFile.readSync()`
-  * `InternetAddress.rawAddress`
   * `RawSocket.read()`
+  * `Utf8Codec.encode()` (and `Utf8Encoder.convert()`)
 
-  In addition, the following typed lists were updated to have their `sublist()`
+  In addition, the following methods and classes were updated to return or
+  implement `Stream<Uint8List>` rather than `Stream<List<int>>`:
+
+  * `File.openRead()`
+  * `HttpRequest`
+  * `HttpClientResponse`
+
+  Finally, the following typed lists were updated to have their `sublist()`
   methods declare a return type that is the same as the source list:
 
-  * `Uint8List.sublist()` → `Uint8List`
   * `Int8List.sublist()` → `Int8List`
-  * `Uint8ClampedList.sublist()` → `Uint8ClampedList`
   * `Int16List.sublist()` → `Int16List`
-  * `Uint16List.sublist()` → `Uint16List`
   * `Int32List.sublist()` → `Int32List`
-  * `Uint32List.sublist()` → `Uint32List`
   * `Int64List.sublist()` → `Int64List`
-  * `Uint64List.sublist()` → `Uint64List`
+  * `Int32x4List.sublist()` → `Int32x4List`
   * `Float32List.sublist()` → `Float32List`
   * `Float64List.sublist()` → `Float64List`
   * `Float32x4List.sublist()` → `Float32x4List`
-  * `Int32x4List.sublist()` → `Int32x4List`
   * `Float64x2List.sublist()` → `Float64x2List`
+  * `Uint8List.sublist()` → `Uint8List`
+  * `Uint8ClampedList.sublist()` → `Uint8ClampedList`
+  * `Uint16List.sublist()` → `Uint16List`
+  * `Uint32List.sublist()` → `Uint32List`
+  * `Uint64List.sublist()` → `Uint64List`
 
-  [36900]: https://github.com/dart-lang/sdk/issues/36900
-
+  
 #### `dart:core`
 
 * Update `Uri` class to support [RFC6874](https://tools.ietf.org/html/rfc6874):
@@ -52,8 +60,9 @@
 
 #### `dart:io`
 
-* **Breaking Change:** The `Cookie` class's constructor's `name` and `value`
-  optional positional parameters are now mandatory (Issue [37192][]). The
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192): 
+  The `Cookie` class's constructor's `name` and `value`
+  optional positional parameters are now mandatory. The
   signature changes from:
 
       Cookie([String name, String value])
@@ -69,18 +78,27 @@
   Since code could not previously correctly omit the parameters, this is not
   really a breaking change.
 
-* **Breaking Change:** The `Cookie` class's `name` and `value` setters now
+* **Breaking change** [#37192](https://github.com/dart-lang/sdk/issues/37192): 
+  The `Cookie` class's `name` and `value` setters now
   validates that the strings are made from the allowed character set and are not
-  null (Issue [37192][]). The constructor already made these checks and this
+  null. The constructor already made these checks and this
   fixes the loophole where the setters didn't also validate.
 
-[37192]: https://github.com/dart-lang/sdk/issues/37192
-
 ### Dart VM
 
 ### Tools
 
-## 2.4.0 - 2019-06-24
+#### Pub
+
+ * Clean-up invalid git repositories in cache when fetching from git.
+
+#### Linter
+
+The Linter was updated to `0.1.93`, which includes the following changes:
+
+* new lint: `avoid_print`
+
+## 2.4.0 - 2019-06-27
 
 ### Core libraries
 
@@ -113,28 +131,29 @@
   [33327]: https://github.com/dart-lang/sdk/issues/33327
   [35804]: https://github.com/dart-lang/sdk/issues/35804
 
-* The `HttpClientResponse` interface has been extended with the addition of a
+* **Breaking change** [#36971](https://github.com/dart-lang/sdk/issues/36971): 
+  The `HttpClientResponse` interface has been extended with the addition of a
   new `compressionState` getter, which specifies whether the body of a
   response was compressed when it was received and whether it has been
-  automatically uncompressed via `HttpClient.autoUncompress` (Issue [36971][]).
+  automatically uncompressed via `HttpClient.autoUncompress`.
 
   As part of this change, a corresponding new enum was added to `dart:io`:
   `HttpClientResponseCompressionState`.
 
-  [36971]: https://github.com/dart-lang/sdk/issues/36971
-
-  * **Breaking change**: For those implementing the `HttpClientResponse`
-    interface, this is a breaking change, as implementing classes will need to
-    implement the new getter.
+  For those implementing the `HttpClientResponse`
+  interface, this is a breaking change, as implementing classes will need to
+  implement the new getter.
 
 #### `dart:async`
 
-* **Breaking change:** The `await for` allowed `null` as a stream due to a bug
+* **Breaking change** [#36382](https://github.com/dart-lang/sdk/issues/36382): 
+  The `await for` allowed `null` as a stream due to a bug
   in `StreamIterator` class. This bug has now been fixed.
 
 #### `dart:core`
 
-* **Breaking change:** The `RegExp` interface has been extended with two new
+* **Breaking change** [#36171](https://github.com/dart-lang/sdk/issues/36171): 
+  The `RegExp` interface has been extended with two new
   constructor named parameters:
 
   * `unicode:` (`bool`, default: `false`), for Unicode patterns
@@ -157,8 +176,9 @@
 
 ### Language
 
-*   **Breaking change:** Covariance of type variables used in super-interfaces
-    is now enforced (issue [35097][]).  For example, the following code was
+*   **Breaking change** [#35097](https://github.com/dart-lang/sdk/issues/35097):
+    Covariance of type variables used in super-interfaces
+    is now enforced. For example, the following code was
     previously accepted and will now be rejected:
 
 ```dart
@@ -169,8 +189,6 @@
 * The identifier `async` can now be used in asynchronous and generator
   functions.
 
-[35097]: https://github.com/dart-lang/sdk/issues/35097
-
 ### Dart for the Web
 
 #### Dart Dev Compiler (DDC)
diff --git a/DEPS b/DEPS
index e7731b9..3cbb976 100644
--- a/DEPS
+++ b/DEPS
@@ -85,7 +85,7 @@
   "fixnum_tag": "0.10.9",
   "glob_tag": "1.1.7",
   "html_tag" : "0.14.0+1",
-  "http_io_rev": "773f4bc73ef572e2c37e879b065c3b406d75e8fd",
+  "http_io_rev": "0b05781c273a040ef521b5f7771dbc0356305872",
   "http_multi_server_tag" : "2.0.5",
   "http_parser_tag" : "3.1.3",
   "http_retry_tag": "0.1.1",
@@ -96,7 +96,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.91",
+  "linter_tag": "0.1.93",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.0.3",
@@ -109,14 +109,14 @@
   "package_config_tag": "1.0.5",
   "package_resolver_tag": "1.0.10",
   "path_tag": "1.6.2",
-  "pedantic_tag": "v1.7.0",
+  "pedantic_tag": "v1.8.0",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "1.3.6",
   "protobuf_rev": "7d34c9e4e552a4f66acce32e4344ae27756a1949",
-  "pub_rev": "ecd5b413271f2699f8cd9e23aa4eebb5030c964f",
+  "pub_rev": "df0f72daaa724e29ed6075e0fb5549a6d6dc5daf",
   "pub_semver_tag": "1.4.2",
   "quiver-dart_tag": "2.0.0+1",
-  "resource_rev": "2.1.5",
+  "resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
   "root_certificates_rev": "16ef64be64c7dfdff2b9f4b910726e635ccc519e",
   "shelf_static_rev": "v0.2.8",
   "shelf_packages_handler_tag": "1.0.4",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 520d015..0a39483 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -17,13 +17,15 @@
 
 
 def _CheckFormat(input_api, identification, extension, windows,
-    hasFormatErrors):
+    hasFormatErrors, should_skip = lambda path : False):
   local_root = input_api.change.RepositoryRoot()
   upstream = input_api.change._upstream
   unformatted_files = []
   for git_file in input_api.AffectedTextFiles():
     if git_file.LocalPath().startswith("pkg/front_end/testcases/"):
       continue
+    if should_skip(git_file.LocalPath()):
+      continue
     filename = git_file.AbsoluteLocalPath()
     if filename.endswith(extension) and hasFormatErrors(filename=filename):
       old_version_has_errors = False
@@ -147,8 +149,12 @@
     process.communicate(input=contents)
     return process.returncode != 0
 
+  def should_skip(path):
+      return (path.startswith("pkg/status_file/test/data/")
+              or path.startswith("pkg/front_end/"))
+
   unformatted_files = _CheckFormat(input_api, "status file", ".status",
-      windows, HasFormatErrors)
+      windows, HasFormatErrors, should_skip)
 
   if unformatted_files:
     normalize = os.path.join(local_root, 'pkg', 'status_file', 'bin',
diff --git a/README.md b/README.md
index 195667d..288dac5 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@
 [repo]: https://github.com/dart-lang/sdk
 [lang]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html
 [tools]: https://www.dartlang.org/tools/
-[codelab]: https://www.dartlang.org/codelabs/darrrt/
+[codelab]: https://dart.dev/codelabs
 [dartbug]: http://dartbug.com
 [contrib]: https://github.com/dart-lang/sdk/wiki/Contributing
 [pubsite]: https://pub.dev
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index 9fb946f..9a3fb87 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -263,7 +263,7 @@
 // http://crbug.com/380554
 "deadlock:g_type_add_interface_static\n"
 
-// http:://crbug.com/386385
+// http://crbug.com/386385
 "race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n"
 
 // http://crbug.com/388730
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a1be95e..f9b7421 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -121,6 +121,7 @@
   }
   logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}');
   return inputRaw
+      .cast<List<int>>()
       .transform(systemEncoding.decoder)
       .transform(new LineSplitter())
       .transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap));
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index 9326583..1705c38 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -111,6 +111,20 @@
   _DartUnitFoldingComputerVisitor(this._computer);
 
   @override
+  void visitAssertInitializer(AssertInitializer node) {
+    _computer._addRegion(node.leftParenthesis.end, node.rightParenthesis.offset,
+        FoldingKind.INVOCATION);
+    super.visitAssertInitializer(node);
+  }
+
+  @override
+  void visitAssertStatement(AssertStatement node) {
+    _computer._addRegion(node.leftParenthesis.end, node.rightParenthesis.offset,
+        FoldingKind.INVOCATION);
+    super.visitAssertStatement(node);
+  }
+
+  @override
   void visitBlockFunctionBody(BlockFunctionBody node) {
     _computer._addRegion(node.block.leftBracket.end,
         node.block.rightBracket.offset, FoldingKind.FUNCTION_BODY);
@@ -147,6 +161,14 @@
   }
 
   @override
+  void visitExtensionDeclaration(ExtensionDeclaration node) {
+    _computer._addRegionForAnnotations(node.metadata);
+    _computer._addRegion(
+        node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
+    super.visitExtensionDeclaration(node);
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _computer._addRegionForAnnotations(node.metadata);
     super.visitFieldDeclaration(node);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index a0e1d15..6754fbb 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -122,6 +122,8 @@
   ErrorOr<void> handleUnknownMessage(IncomingMessage message) {
     // Silently drop non-requests.
     if (message is! RequestMessage) {
+      server.instrumentationService
+          .logInfo('Ignoring ${message.method} message while initializing');
       return success();
     }
     return error(
@@ -142,6 +144,8 @@
   FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
     // Silently drop non-requests.
     if (message is! RequestMessage) {
+      server.instrumentationService
+          .logInfo('Ignoring ${message.method} message while uninitialized');
       return success();
     }
     return error(ErrorCodes.ServerNotInitialized,
@@ -159,6 +163,8 @@
   FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
     // Silently drop non-requests.
     if (message is! RequestMessage) {
+      server.instrumentationService
+          .logInfo('Ignoring ${message.method} message while shutting down');
       return success();
     }
     return error(ErrorCodes.InvalidRequest,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
index 46ab686..aff08f1 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -118,7 +118,6 @@
     final doc = params.textDocument;
     final path = pathOfDocItem(doc);
     return path.mapResult((path) {
-      server.addPriorityFile(path);
       // We don't get a VersionedTextDocumentIdentifier with a didOpen but we
       // do get the necessary info to create one.
       server.documentVersions[path] = new VersionedTextDocumentIdentifier(
@@ -161,6 +160,8 @@
         }
       }
 
+      server.addPriorityFile(path);
+
       return success();
     });
   }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 0588482..c24de75 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -234,7 +234,7 @@
       _addLocalSuggestion_includeTypeNameSuggestions(
           declaration.documentationComment,
           declaration.name,
-          declaration.functionType.returnType,
+          declaration.functionType?.returnType,
           protocol.ElementKind.FUNCTION_TYPE_ALIAS,
           isAbstract: true,
           isDeprecated: isDeprecated(declaration));
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index e46f525..52641ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -232,4 +232,6 @@
       'dart.assist.surround.tryFinally', 29, "Surround with 'try-finally'");
   static const SURROUND_WITH_WHILE = const AssistKind(
       'dart.assist.surround.while', 24, "Surround with 'while'");
+  static const USE_CURLY_BRACES =
+      const AssistKind('USE_CURLY_BRACES', 30, "Use curly braces");
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index b465c69..32ec6cd 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -149,6 +149,7 @@
     await _addProposal_splitAndCondition();
     await _addProposal_splitVariableDeclaration();
     await _addProposal_surroundWith();
+    await _addProposal_useCurlyBraces();
 
     if (experimentStatus.control_flow_collections) {
       await _addProposal_convertConditionalExpressionToIfElement();
@@ -971,7 +972,8 @@
       return;
     }
     ConstructorElement element = creation.staticElement;
-    if (element.name != 'fromIterable' ||
+    if (element == null ||
+        element.name != 'fromIterable' ||
         element.enclosingElement != typeProvider.mapType.element) {
       _coverageMarker();
       return;
@@ -3748,6 +3750,12 @@
           selectedStatements.add(selectedNode);
         }
       }
+      // we want only statements in blocks
+      for (var statement in selectedStatements) {
+        if (statement.parent is! Block) {
+          return;
+        }
+      }
       // we want only statements
       if (selectedStatements.isEmpty ||
           selectedStatements.length != selectedNodes.length) {
@@ -3940,6 +3948,132 @@
     }
   }
 
+  Future<void> _addProposal_useCurlyBraces() async {
+    Future<void> doStatement(DoStatement node) async {
+      var body = node.body;
+      if (body is Block) return;
+
+      var prefix = utils.getLinePrefix(node.offset);
+      var indent = prefix + utils.getIndent(1);
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.endStart(node.doKeyword, body),
+          ' {$eol$indent',
+        );
+        builder.addSimpleReplacement(
+          range.endStart(body, node.whileKeyword),
+          '$eol$prefix} ',
+        );
+      });
+
+      _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+    }
+
+    Future<void> forStatement(ForStatement node) async {
+      var body = node.body;
+      if (body is Block) return;
+
+      var prefix = utils.getLinePrefix(node.offset);
+      var indent = prefix + utils.getIndent(1);
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.endStart(node.rightParenthesis, body),
+          ' {$eol$indent',
+        );
+        builder.addSimpleInsertion(body.end, '$eol$prefix}');
+      });
+
+      _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+    }
+
+    Future<void> ifStatement(IfStatement node, Statement thenOrElse) async {
+      var prefix = utils.getLinePrefix(node.offset);
+      var indent = prefix + utils.getIndent(1);
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        var thenStatement = node.thenStatement;
+        if (thenStatement is! Block &&
+            (thenOrElse == null || thenOrElse == thenStatement)) {
+          builder.addSimpleReplacement(
+            range.endStart(node.rightParenthesis, thenStatement),
+            ' {$eol$indent',
+          );
+          if (node.elseKeyword != null) {
+            builder.addSimpleReplacement(
+              range.endStart(thenStatement, node.elseKeyword),
+              '$eol$prefix} ',
+            );
+          } else {
+            builder.addSimpleInsertion(thenStatement.end, '$eol$prefix}');
+          }
+        }
+
+        var elseStatement = node.elseStatement;
+        if (elseStatement != null &&
+            elseStatement is! Block &&
+            (thenOrElse == null || thenOrElse == elseStatement)) {
+          builder.addSimpleReplacement(
+            range.endStart(node.elseKeyword, elseStatement),
+            ' {$eol$indent',
+          );
+          builder.addSimpleInsertion(elseStatement.end, '$eol$prefix}');
+        }
+      });
+
+      _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+    }
+
+    Future<void> whileStatement(WhileStatement node) async {
+      var body = node.body;
+      if (body is Block) return;
+
+      var prefix = utils.getLinePrefix(node.offset);
+      var indent = prefix + utils.getIndent(1);
+
+      var changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (builder) {
+        builder.addSimpleReplacement(
+          range.endStart(node.rightParenthesis, body),
+          ' {$eol$indent',
+        );
+        builder.addSimpleInsertion(body.end, '$eol$prefix}');
+      });
+
+      _addAssistFromBuilder(changeBuilder, DartAssistKind.USE_CURLY_BRACES);
+    }
+
+    var statement = this.node.thisOrAncestorOfType<Statement>();
+    var parent = statement?.parent;
+
+    if (statement is DoStatement) {
+      return doStatement(statement);
+    } else if (parent is DoStatement) {
+      return doStatement(parent);
+    } else if (statement is ForStatement) {
+      return forStatement(statement);
+    } else if (parent is ForStatement) {
+      return forStatement(parent);
+    } else if (statement is IfStatement) {
+      if (statement.elseKeyword != null &&
+          range.token(statement.elseKeyword).contains(selectionOffset)) {
+        return ifStatement(statement, statement.elseStatement);
+      } else {
+        return ifStatement(statement, null);
+      }
+    } else if (parent is IfStatement) {
+      return ifStatement(parent, statement);
+    } else if (statement is WhileStatement) {
+      return whileStatement(statement);
+    } else if (parent is WhileStatement) {
+      return whileStatement(parent);
+    }
+  }
+
   /**
    * Return `true` if all of the parameters in the given list of [parameters]
    * have an explicit type annotation.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index dc43fd4..616949d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -3276,7 +3276,7 @@
       var changeBuilder = _newDartChangeBuilder();
       await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
         builder.addSimpleReplacement(
-            range.token((node as DefaultFormalParameter).separator), '=');
+            range.token((node as DefaultFormalParameter).separator), ' =');
       });
       _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_COLON_WITH_EQUALS);
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index f850b80..1886f88 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -381,7 +381,7 @@
         hashCode: (Token t) => t.lexeme.hashCode);
     expr.accept(new _TokenLocalElementVisitor(map));
     // map and join tokens
-    return tokens.map((Token token) {
+    var result = tokens.map((Token token) {
       String tokenString = token.lexeme;
       // append token's Element id
       Element element = map[token];
@@ -394,6 +394,7 @@
       // done
       return tokenString;
     }).join(_TOKEN_SEPARATOR);
+    return result + _TOKEN_SEPARATOR;
   }
 
   /**
@@ -693,7 +694,7 @@
       int endTokenIndex =
           countMatches(nodeSource.substring(0, lastIndex), _TOKEN_SEPARATOR);
       Token startToken = nodeTokens[startTokenIndex];
-      Token endToken = nodeTokens[endTokenIndex];
+      Token endToken = nodeTokens[endTokenIndex - 1];
       // add occurrence range
       int start = nodeOffset + startToken.offset;
       int end = nodeOffset + endToken.end;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 164d553..8bb80c3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -69,21 +69,49 @@
 
   @override
   Future<SourceChange> createChange() async {
-    var changeBuilder = new DartChangeBuilder(driver.currentSession);
-    final element = resolvedUnit.unit.declaredElement;
+    final DartChangeBuilder changeBuilder =
+        new DartChangeBuilder(driver.currentSession);
+    final CompilationUnitElement element = resolvedUnit.unit.declaredElement;
     if (element == null) {
       return changeBuilder.sourceChange;
     }
-    final library = element.library;
+    final LibraryElement libraryElement = element.library;
 
     // If this element is a library, update outgoing references inside the file.
-    if (element == library.definingCompilationUnit) {
-      await changeBuilder.addFileEdit(library.source.fullName, (builder) {
-        final oldDir = pathContext.dirname(oldFile);
-        final newDir = pathContext.dirname(newFile);
-        _updateUriReferences(builder, library.imports, oldDir, newDir);
-        _updateUriReferences(builder, library.exports, oldDir, newDir);
-        _updateUriReferences(builder, library.parts, oldDir, newDir);
+    if (element == libraryElement.definingCompilationUnit) {
+      // Handle part-of directives in this library
+      final ResolvedLibraryResult libraryResult = await driver.currentSession
+          .getResolvedLibraryByElement(libraryElement);
+      for (ResolvedUnitResult result in libraryResult.units) {
+        if (result.isPart) {
+          Iterable<PartOfDirective> partOfs = result.unit.directives
+              .whereType<PartOfDirective>()
+              .where(
+                  (po) => po.uri != null && _isRelativeUri(po.uri.stringValue));
+          if (partOfs.isNotEmpty) {
+            await changeBuilder.addFileEdit(
+                result.unit.declaredElement.source.fullName, (builder) {
+              partOfs.forEach((po) {
+                final oldDir = pathContext.dirname(oldFile);
+                final newDir = pathContext.dirname(newFile);
+                String newLocation =
+                    pathContext.join(newDir, pathos.basename(newFile));
+                String newUri = _getRelativeUri(newLocation, oldDir);
+                builder.addSimpleReplacement(
+                    new SourceRange(po.uri.offset, po.uri.length), "'$newUri'");
+              });
+            });
+          }
+        }
+      }
+
+      await changeBuilder.addFileEdit(libraryElement.source.fullName,
+          (builder) {
+        final String oldDir = pathContext.dirname(oldFile);
+        final String newDir = pathContext.dirname(newFile);
+        _updateUriReferences(builder, libraryElement.imports, oldDir, newDir);
+        _updateUriReferences(builder, libraryElement.exports, oldDir, newDir);
+        _updateUriReferences(builder, libraryElement.parts, oldDir, newDir);
       });
     } else {
       // Otherwise, we need to update any relative part-of references.
diff --git a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart b/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
index 6005964..baa3443 100644
--- a/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
+++ b/pkg/analysis_server/test/integration/diagnostic/get_server_port_test.dart
@@ -31,7 +31,7 @@
     HttpClientRequest request = await client
         .getUrl(Uri.parse('http://localhost:${result.port}/status'));
     HttpClientResponse response = await request.close();
-    String responseBody = await utf8.decodeStream(response);
+    String responseBody = await utf8.decodeStream(response.cast<List<int>>());
     expect(responseBody, contains('<title>Analysis Server</title>'));
   }
 }
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 0b90316..0b73ad4 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -34,7 +34,7 @@
     HttpClientRequest request = await client
         .getUrl(Uri.parse('http://localhost:${server.port}/status'));
     final response = await request.close();
-    final responseBody = await utf8.decodeStream(response);
+    final responseBody = await utf8.decodeStream(response.cast<List<int>>());
     expect(responseBody, contains('<title>Analysis Server</title>'));
   }
 
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 7b147df..648b7ed 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -93,6 +93,14 @@
     await openFile(nestedFileUri, '');
     expect(server.contextManager.includedPaths, equals([projectFolderPath]));
 
+    // Ensure the file was cached in each driver. This happens as a result of
+    // adding to priority files, but if that's done before the file is in an
+    // analysis root it will not occur.
+    // https://github.com/dart-lang/sdk/issues/37338
+    server.driverMap.values.forEach((driver) {
+      expect(driver.getCachedResult(nestedFilePath), isNotNull);
+    });
+
     // Closing the file should remove it.
     await closeFile(nestedFileUri);
     expect(server.contextManager.includedPaths, equals([]));
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 07e7073..b2e9543 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -180,6 +180,7 @@
       engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
       engine.ElementKind.ERROR: ElementKind.UNKNOWN,
       engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
+      engine.ElementKind.EXTENSION: ElementKind.UNKNOWN,
       engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
@@ -258,9 +259,6 @@
   String correction = null;
 
   @override
-  bool isStaticOnly;
-
-  @override
   int length;
 
   MockAnalysisError(
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 4fbe052..b726924 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -2921,6 +2921,17 @@
     assertSuggestFunctionTypeAlias('F', 'void');
   }
 
+  test_functionTypeAlias_genericTypeAlias_incomplete() async {
+    addTestSource(r'''
+typedef F = int;
+main() {
+  ^
+}
+''');
+    await computeSuggestions();
+    assertSuggestFunctionTypeAlias('F', 'dynamic');
+  }
+
   test_functionTypeAlias_old() async {
     addTestSource(r'''
 typedef void F();
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 157d574..5725680 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -734,6 +734,36 @@
     expect(refactoring.isAvailable(), isTrue);
   }
 
+  test_occurrences_differentName_samePrefix() async {
+    await indexTestUnit('''
+void main(A a) {
+  if (a.foo != 1) {
+  } else if (a.foo2 != 2) {
+  }
+}
+
+class A {
+  int foo;
+  int foo2;
+}
+''');
+    _createRefactoringWithSuffix('a.foo', ' != 1');
+    // apply refactoring
+    await _assertSuccessfulRefactoring('''
+void main(A a) {
+  var res = a.foo;
+  if (res != 1) {
+  } else if (a.foo2 != 2) {
+  }
+}
+
+class A {
+  int foo;
+  int foo2;
+}
+''');
+  }
+
   test_occurrences_differentVariable() async {
     await indexTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 6f6fe1f..69260ef 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -345,6 +345,98 @@
 ''');
   }
 
+  test_renaming_part_that_uses_uri_in_part_of_2() async {
+    // If the file is a part in a library, and the part-of directive uses a URI
+    // rather than a library name, that will need updating too (if the relative
+    // path to the parent changes).
+    String pathA = convertPath('/home/test/000/1111/a.dart');
+    testFile = convertPath('/home/test/000/1111/test.dart');
+    addSource(pathA, '''
+part of 'test.dart';
+''');
+    await resolveTestUnit('''
+part 'a.dart';
+''');
+    // perform refactoring
+    _createRefactoring('/home/test/000/1111/22/test.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pathA, '''
+part of '22/test.dart';
+''');
+    assertFileChangeResult(testFile, '''
+part '../a.dart';
+''');
+  }
+
+  test_renaming_part_that_uses_uri_in_part_of_3() async {
+    // If the file is a part in a library, and the part-of directive uses a URI
+    // rather than a library name, that will need updating too (if the relative
+    // path to the parent changes).
+    String pathA = convertPath('/home/test/000/1111/a.dart');
+    testFile = convertPath('/home/test/000/1111/test.dart');
+    addSource(pathA, '''
+part of 'test.dart';
+''');
+    await resolveTestUnit('''
+part 'a.dart';
+''');
+    // perform refactoring
+    _createRefactoring('/home/test/000/1111/test2.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pathA, '''
+part of 'test2.dart';
+''');
+    assertFileChangeResult(testFile, '''
+part 'a.dart';
+''');
+  }
+
+  test_renaming_part_that_uses_uri_in_part_of_4() async {
+    // If the file is a part in a library, and the part-of directive uses a URI
+    // rather than a library name, that will need updating too (if the relative
+    // path to the parent changes).
+    String pathA = convertPath('/home/test/000/1111/a.dart');
+    testFile = convertPath('/home/test/000/1111/test.dart');
+    addSource(pathA, '''
+part 'test.dart';
+''');
+    await resolveTestUnit('''
+part of 'a.dart';
+''');
+    // perform refactoring
+    _createRefactoring('/home/test/000/1111/22/test.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pathA, '''
+part '22/test.dart';
+''');
+    assertFileChangeResult(testFile, '''
+part of '../a.dart';
+''');
+  }
+
+  test_renaming_part_that_uses_uri_in_part_of_5() async {
+    // If the file is a part in a library, and the part-of directive uses a URI
+    // rather than a library name, that will need updating too (if the relative
+    // path to the parent changes).
+    String pathA = convertPath('/home/test/000/1111/a.dart');
+    testFile = convertPath('/home/test/000/1111/test.dart');
+    addSource(pathA, '''
+part 'test.dart';
+''');
+    await resolveTestUnit('''
+part of 'a.dart';
+''');
+    // perform refactoring
+    _createRefactoring('/home/test/000/1111/test2.dart');
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pathA, '''
+part 'test2.dart';
+''');
+    assertFileChangeResult(testFile, '''
+part of 'a.dart';
+''');
+  }
+
   Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
       {String expectedMessage}) async {
     RefactoringStatus status = await refactoring.checkAllConditions();
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index 3f2d2ae..c4a5fff 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -78,6 +78,32 @@
     _compareRegions(regions, content);
   }
 
+  test_assertInitializer() async {
+    String content = '''
+class C {/*1:INC*/
+  C() : assert(/*2:INC*/
+    true,
+    ''
+  /*2:INC:INVOCATION*/);
+/*1:INC:CLASS_BODY*/}
+''';
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_assertStatement() async {
+    String content = '''
+main() {/*1:INC*/
+  assert(/*2:INC*/
+    true,
+    ''
+  /*2:INC:INVOCATION*/);
+/*1:INC:FUNCTION_BODY*/}
+''';
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
   test_class() async {
     String content = """
 // Content before
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
index 597c353..0a53680 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -187,4 +187,14 @@
 }
 ''');
   }
+
+  test_undefinedConstructor() async {
+    verifyNoTestUnitErrors = false;
+    await resolveTestUnit('''
+f() {
+  return new Unde/*caret*/fined();
+}
+''');
+    await assertNoAssist();
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
index 52f5125..365995d 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
@@ -19,6 +19,18 @@
   @override
   AssistKind get kind => DartAssistKind.SURROUND_WITH_BLOCK;
 
+  test_notStatementInBlock() async {
+    await resolveTestUnit('''
+main() {
+  while (true)
+// start
+    print(0);
+// end
+}
+''');
+    await assertNoAssist();
+  }
+
   test_twoStatements() async {
     await resolveTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index 7a7f079..b26ffb7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -78,6 +78,7 @@
 import 'surround_with_try_catch_test.dart' as surround_with_try_catch;
 import 'surround_with_try_finally_test.dart' as surround_with_try_finally;
 import 'surround_with_while_test.dart' as surround_with_while;
+import 'use_curly_braces_test.dart' as use_curly_braces;
 
 main() {
   defineReflectiveSuite(() {
@@ -147,5 +148,6 @@
     surround_with_try_catch.main();
     surround_with_try_finally.main();
     surround_with_while.main();
+    use_curly_braces.main();
   }, name: 'assist');
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
new file mode 100644
index 0000000..f3e6589
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/use_curly_braces_test.dart
@@ -0,0 +1,443 @@
+// Copyright (c) 2019, 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:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UseCurlyBracesTest);
+  });
+}
+
+@reflectiveTest
+class UseCurlyBracesTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.USE_CURLY_BRACES;
+
+  test_do_block() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/do {
+    print(0);
+  } while (true);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_do_body_middle() async {
+    await resolveTestUnit('''
+main() {
+  do print/*caret*/(0); while (true);
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_do_body_start() async {
+    await resolveTestUnit('''
+main() {
+  do /*caret*/print(0); while (true);
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_do_condition() async {
+    await resolveTestUnit('''
+main() {
+  do print(0); while (/*caret*/true);
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_do_end() async {
+    await resolveTestUnit('''
+main() {
+  do print(0); while (true);/*caret*/
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_do_keyword_do() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/do print(0); while (true);
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_do_keyword_while() async {
+    await resolveTestUnit('''
+main() {
+  do print(0); /*caret*/while (true);
+}
+''');
+    await assertHasAssist('''
+main() {
+  do {
+    print(0);
+  } while (true);
+}
+''');
+  }
+
+  test_for_body_end() async {
+    await resolveTestUnit('''
+main() {
+  for (;;) print(0);/*caret*/
+}
+''');
+    await assertHasAssist('''
+main() {
+  for (;;) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_for_body_middle() async {
+    await resolveTestUnit('''
+main() {
+  for (;;) print/*caret*/(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  for (;;) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_for_body_start() async {
+    await resolveTestUnit('''
+main() {
+  for (;;) /*caret*/print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  for (;;) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_for_condition() async {
+    await resolveTestUnit('''
+main() {
+  for (/*caret*/;;) print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  for (;;) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_for_keyword() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/for (;;) print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  for (;;) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_for_keyword_block() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/for (;;) {
+    print(0);
+  }
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_if_else_keyword() async {
+    await resolveTestUnit('''
+main(int a) {
+  if (a == 0)
+    print(0);
+  /*caret*/else print(1);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0)
+    print(0);
+  else {
+    print(1);
+  }
+}
+''');
+  }
+
+  test_if_else_statement() async {
+    await resolveTestUnit('''
+main(int a) {
+  if (a == 0)
+    print(0);
+  else /*caret*/print(1);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0)
+    print(0);
+  else {
+    print(1);
+  }
+}
+''');
+  }
+
+  test_if_keyword_blockBoth() async {
+    await resolveTestUnit('''
+main(int a) {
+  /*caret*/if (a == 0) {
+    print(0);
+  } else {
+    print(1);
+  }
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_if_keyword_blockElse() async {
+    await resolveTestUnit('''
+main(int a) {
+  /*caret*/if (a == 0) print(0);
+  else {
+    print(1);
+  }
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0) {
+    print(0);
+  } else {
+    print(1);
+  }
+}
+''');
+  }
+
+  test_if_keyword_blockThen() async {
+    await resolveTestUnit('''
+main(int a) {
+  /*caret*/if (a == 0) {
+    print(0);
+  }
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_if_keyword_withElse() async {
+    await resolveTestUnit('''
+main(int a) {
+  /*caret*/if (a == 0)
+    print(0);
+  else print(1);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0) {
+    print(0);
+  } else {
+    print(1);
+  }
+}
+''');
+  }
+
+  test_if_keyword_withoutElse() async {
+    await resolveTestUnit('''
+main(int a) {
+  /*caret*/if (a == 0)
+    print(0);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_if_then_withElse() async {
+    await resolveTestUnit('''
+main(int a) {
+  if (a == 0)
+    /*caret*/print(0);
+  else print(1);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0) {
+    print(0);
+  } else print(1);
+}
+''');
+  }
+
+  test_if_then_withoutElse() async {
+    await resolveTestUnit('''
+main(int a) {
+  if (a == 0) /*caret*/print(0);
+}
+''');
+    await assertHasAssist('''
+main(int a) {
+  if (a == 0) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_body_end() async {
+    await resolveTestUnit('''
+main() {
+  while (true) print(0);/*caret*/
+}
+''');
+    await assertHasAssist('''
+main() {
+  while (true) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_body_middle() async {
+    await resolveTestUnit('''
+main() {
+  while (true) print/*caret*/(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  while (true) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_body_start() async {
+    await resolveTestUnit('''
+main() {
+  while (true) /*caret*/print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  while (true) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_condition() async {
+    await resolveTestUnit('''
+main() {
+  while (/*caret*/true) print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  while (true) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_keyword() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/while (true) print(0);
+}
+''');
+    await assertHasAssist('''
+main() {
+  while (true) {
+    print(0);
+  }
+}
+''');
+  }
+
+  test_while_keyword_block() async {
+    await resolveTestUnit('''
+main() {
+  /*caret*/while (true) {
+    print(0);
+  }
+}
+''');
+    await assertNoAssist();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
index 375a662..85e0bb6 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_colon_with_equals_test.dart
@@ -32,7 +32,7 @@
     await assertHasFix('''
 void f1({int a}) { }    
 
-f1({a/*LINT*/= 1}) => null;
+f1({a/*LINT*/ = 1}) => null;
 ''');
   }
 }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f0d1b34a..0f4bb38 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,32 @@
-## 0.36.4-dev (not yet published)
+## 0.37.0
+* Removed deprecated getter `DartType.isUndefined`.
+* Removed deprecated class `SdkLibrariesReader`.
+* Removed deprecated method `InstanceCreationExpressionImpl.canBeConst`.
+* The `AstFactory.compilationUnit` method now uses named parameters.  Clients
+  that prepared for this change by switching to `AstFactory.compilationUnit2`
+  should now switch back to `AstFactory.compilationUnit`.
+* Removed `AstNode.getAncestor`.  Please use `AstNode.thisOrAncestorMatching` or
+  `AstNode.thisOrAncestorOfType`.
+* Removed deprecated getter `TypeSystem.isStrong`, and its override
+  `Dart2TypeSystem.isStrong`.
+* Removed the deprecated getter `AnalysisError.isStaticOnly` and the deprecated
+  setters `AnalysisError.isStaticOnly` and `AnalysisError.offset`.
+* Removed the `abstract` setter in `ClassElementImpl`, `EnumElementImpl`,
+  `MethodElementImpl`, and `PropertyAccessorElementImpl`.  `isAbstract` should
+  be used instead.
+* Removed methods `AstVisitor.ForStatement2`, `ListLiteral.elements2`,
+  `SetOrMapLiteral.elements2`, `AstFactory.forStatement2`, and
+  `NodeLintRegistry.addForStatement2`, as well as class `ForStatement2`.  Use
+  the variants with out the "2" suffix instead.
+* Changed the signature and behavior of `parseFile` to match `parseFile2`.
+  Clients that switched to using `parseFile2` when `parseFile` was deprecated
+  should now switch back to `parseFile`.
+* Removed Parser setters `enableControlFlowCollections`, `enableNonNullable`,
+  `enableSpreadCollections`, and `enableTripleShift`, and the method
+  `configureFeatures`.  Made the `featureSet` parameter of the Parser
+  constructor a required parameter.
+
+## 0.36.4
 * Deprecated the `isNonNullableUnit` parameter of the `TypeResolverVisitor`
   constructor.  TypeResolverVisitor should now be configured using the
   `featureSet` parameter.
@@ -21,6 +49,16 @@
 * Changed the return type of `ClassTypeAlias.declaredElement` to `ClassElement`.
   There is no functional change; it has always returned an instance of
   `ClassElement`.
+* Deprecated `parseFile`.  Please use `parseFile2` instead--in addition to
+  supporting the same `featureSet` and `throwIfDiagnostics` parameters as
+  `parseString`, it is much more efficient than `parseFile`.
+* Added more specific deprecation notices to `package:analyzer/analyzer.dart` to
+  direct clients to suitable replacements.
+* Deprecated the enable flags `bogus-disabled` and `bogus-enabled`.  Clients
+  should not be relying on the presence of these flags.
+* Deprecated the constructor parameter
+  ConstantEvaluationEngine.forAnalysisDriver, which no longer has any effect.
+* Deprecated ElementImpl.RIGHT_ARROW.
 
 ## 0.36.3
 * Deprecated `AstFactory.compilationUnit`.  In a future analyzer release, this
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 0e8a271..3d473b7 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -39,7 +39,14 @@
 /// [suppressErrors] is `true`, in which case any errors are discarded.
 ///
 /// If [parseFunctionBodies] is [false] then only function signatures will be
-/// parsed.
+/// parsed.  (Currently broken; function bodies are always parsed).
+///
+/// Deprecated - please use the `parseString` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseString` does not support the `parseFunctionBodies` option;
+/// callers that don't require function bodies should simply ignore them.
+@Deprecated('Please use parseString instead')
 CompilationUnit parseCompilationUnit(String contents,
     {String name,
     bool suppressErrors: false,
@@ -58,7 +65,14 @@
 /// [suppressErrors] is `true`, in which case any errors are discarded.
 ///
 /// If [parseFunctionBodies] is [false] then only function signatures will be
-/// parsed.
+/// parsed.  (Currently broken; function bodies are always parsed).
+///
+/// Deprecated - please use the `parseFile2` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseFile2` does not support the `parseFunctionBodies` option;
+/// callers that don't require function bodies should simply ignore them.
+@Deprecated('Please use parseFile2 instead')
 CompilationUnit parseDartFile(String path,
     {bool suppressErrors: false,
     bool parseFunctionBodies: true,
@@ -83,6 +97,7 @@
 }
 
 /// Parses the script tag and directives in a string of Dart code into an AST.
+/// (Currently broken; the entire file is parsed).
 ///
 /// Stops parsing when the first non-directive is encountered. The rest of the
 /// string will not be parsed.
@@ -92,6 +107,13 @@
 ///
 /// Throws an [AnalyzerErrorGroup] if any errors occurred, unless
 /// [suppressErrors] is `true`, in which case any errors are discarded.
+///
+/// Deprecated - please use the `parseString` function
+/// (from package:analyzer/dart/analysis/utilities.dart) instead.
+///
+/// Note that `parseString` parses the whole file; callers that only require
+/// directives should simply ignore the rest of the parse result.
+@Deprecated('Please use parseString instead')
 CompilationUnit parseDirectives(String contents,
     {String name, bool suppressErrors: false, FeatureSet featureSet}) {
   // TODO(paulberry): make featureSet a required parameter.
@@ -112,6 +134,7 @@
 }
 
 /// Converts an AST node representing a string literal into a [String].
+@Deprecated('Please use StringLiteral.stringValue instead')
 String stringLiteralToString(StringLiteral literal) {
   return literal.stringValue;
 }
diff --git a/pkg/analyzer/lib/dart/analysis/utilities.dart b/pkg/analyzer/lib/dart/analysis/utilities.dart
index 7b96945..f4f7dff 100644
--- a/pkg/analyzer/lib/dart/analysis/utilities.dart
+++ b/pkg/analyzer/lib/dart/analysis/utilities.dart
@@ -23,14 +23,69 @@
 ///
 /// If a [resourceProvider] is given, it will be used to access the file system.
 ///
-/// Note that if more than one file is going to be parsed then this function is
-/// inefficient. Clients should instead use [AnalysisContextCollection] to
-/// create one or more contexts and use those contexts to parse the files.
-ParsedUnitResult parseFile(
-    {@required String path, ResourceProvider resourceProvider}) {
-  AnalysisContext context =
-      _createAnalysisContext(path: path, resourceProvider: resourceProvider);
-  return context.currentSession.getParsedUnit(path);
+/// [featureSet] determines what set of features will be assumed by the parser.
+/// This parameter is required because the analyzer does not yet have a
+/// performant way of computing the correct feature set for a single file to be
+/// parsed.  Callers that need the feature set to be strictly correct must
+/// create an [AnalysisContextCollection], query it to get an [AnalysisContext],
+/// query it to get an [AnalysisSession], and then call `getParsedUnit`.
+///
+/// Callers that don't need the feature set to be strictly correct can pass in
+/// `FeatureSet.fromEnableFlags([])` to enable the default set of features; this
+/// is much more performant than using an analysis session, because it doesn't
+/// require the analyzer to process the SDK.
+///
+/// If [throwIfDiagnostics] is `true` (the default), then if any diagnostics are
+/// produced because of syntactic errors in the [content] an `ArgumentError`
+/// will be thrown. If the parameter is `false`, then the caller can check the
+/// result to see whether there are any errors.
+ParseStringResult parseFile(
+    {@required String path,
+    ResourceProvider resourceProvider,
+    @required FeatureSet featureSet,
+    bool throwIfDiagnostics: true}) {
+  if (featureSet == null) {
+    throw ArgumentError('A non-null feature set must be provided.');
+  }
+  resourceProvider ??= PhysicalResourceProvider.INSTANCE;
+  var content = (resourceProvider.getResource(path) as File).readAsStringSync();
+  return parseString(
+      content: content,
+      featureSet: featureSet,
+      throwIfDiagnostics: throwIfDiagnostics);
+}
+
+/// Return the result of parsing the file at the given [path].
+///
+/// If a [resourceProvider] is given, it will be used to access the file system.
+///
+/// [featureSet] determines what set of features will be assumed by the parser.
+/// This parameter is required because the analyzer does not yet have a
+/// performant way of computing the correct feature set for a single file to be
+/// parsed.  Callers that need the feature set to be strictly correct must
+/// create an [AnalysisContextCollection], query it to get an [AnalysisContext],
+/// query it to get an [AnalysisSession], and then call `getParsedUnit`.
+///
+/// Callers that don't need the feature set to be strictly correct can pass in
+/// `FeatureSet.fromEnableFlags([])` to enable the default set of features; this
+/// is much more performant than using an analysis session, because it doesn't
+/// require the analyzer to process the SDK.
+///
+/// If [throwIfDiagnostics] is `true` (the default), then if any diagnostics are
+/// produced because of syntactic errors in the [content] an `ArgumentError`
+/// will be thrown. If the parameter is `false`, then the caller can check the
+/// result to see whether there are any errors.
+@Deprecated('Use parseFile')
+ParseStringResult parseFile2(
+    {@required String path,
+    ResourceProvider resourceProvider,
+    @required FeatureSet featureSet,
+    bool throwIfDiagnostics: true}) {
+  return parseFile(
+      path: path,
+      resourceProvider: resourceProvider,
+      featureSet: featureSet,
+      throwIfDiagnostics: throwIfDiagnostics);
 }
 
 /// Returns the result of parsing the given [content] as a compilation unit.
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index a7b03cd..6db198d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -378,12 +378,6 @@
   /// Return the token before [target] or `null` if it cannot be found.
   Token findPrevious(Token target);
 
-  /// Return the most immediate ancestor of this node for which the [predicate]
-  /// returns `true`, or `null` if there is no such ancestor. Note that this
-  /// node will never be returned.
-  @deprecated
-  E getAncestor<E extends AstNode>(Predicate<AstNode> predicate);
-
   /// Return the value of the property with the given [name], or `null` if this
   /// node does not have a property with the given name.
   E getProperty<E>(String name);
@@ -502,6 +496,8 @@
 
   R visitExtensionDeclaration(ExtensionDeclaration node);
 
+  R visitExtensionOverride(ExtensionOverride node);
+
   R visitFieldDeclaration(FieldDeclaration node);
 
   R visitFieldFormalParameter(FieldFormalParameter node);
@@ -520,9 +516,6 @@
 
   R visitForStatement(ForStatement node);
 
-  @Deprecated('Replaced by visitForStatement')
-  R visitForStatement2(ForStatement2 node);
-
   R visitFunctionDeclaration(FunctionDeclaration node);
 
   R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
@@ -2148,6 +2141,35 @@
   TypeParameterList get typeParameters;
 }
 
+/// An override to force resolution to choose a member from a specific
+/// extension.
+///
+///    extensionOverride ::=
+///        [Identifier] [TypeArgumentList]? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExtensionOverride implements Expression {
+  /// Return the list of arguments to the override. In valid code this will
+  /// contain a single argument, which evaluates to the object being extended.
+  ArgumentList get argumentList;
+
+  /// Return the name of the extension being selected.
+  Identifier get extensionName;
+
+  /// Return the type arguments to be applied to the extension, or `null` if no
+  /// type arguments were provided.
+  TypeArgumentList get typeArguments;
+
+  /// Return the actual type arguments to be applied to the extension, either
+  /// explicitly specified in [typeArguments], or inferred.
+  ///
+  /// If the AST has been resolved, never returns `null`, returns an empty list
+  /// if the extension does not have type parameters.
+  ///
+  /// Return `null` if the AST structure has not been resolved.
+  List<DartType> get typeArgumentTypes;
+}
+
 /// The declaration of one or more fields of the same type.
 ///
 ///    fieldDeclaration ::=
@@ -2540,26 +2562,6 @@
   Token get rightParenthesis;
 }
 
-/// A for or for-each statement.
-///
-///    forStatement ::=
-///        'for' '(' forLoopParts ')' [Statement]
-///
-///    forLoopParts ::=
-///       [VariableDeclaration] ';' [Expression]? ';' expressionList?
-///     | [Expression]? ';' [Expression]? ';' expressionList?
-///     | [DeclaredIdentifier] 'in' [Expression]
-///     | [SimpleIdentifier] 'in' [Expression]
-///
-/// This is the class that is used to represent a for loop when either the
-/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
-/// If neither of those experiments are enabled, then either `ForStatement` or
-/// `ForEachStatement` will be used.
-///
-/// Clients may not extend, implement or mix-in this class.
-@Deprecated('Replaced by ForStatement')
-abstract class ForStatement2 extends ForStatement {}
-
 /// A node representing the body of a function or method.
 ///
 ///    functionBody ::=
@@ -3653,10 +3655,6 @@
   /// Return the syntactic elements used to compute the elements of the list.
   NodeList<CollectionElement> get elements;
 
-  /// Return the syntactic elements used to compute the elements of the list.
-  @Deprecated('Replaced by elements')
-  NodeList<CollectionElement> get elements2;
-
   /// Return the left square bracket.
   Token get leftBracket;
 
@@ -4529,11 +4527,6 @@
   /// map.
   NodeList<CollectionElement> get elements;
 
-  /// Return the syntactic elements used to compute the elements of the set or
-  /// map.
-  @Deprecated('Replaced by elements')
-  NodeList<CollectionElement> get elements2;
-
   /// Return `true` if this literal represents a map literal.
   ///
   /// This getter will always return `false` if [isSet] returns `true`.
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 2796e1a..d8cffd0 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -151,19 +151,21 @@
   /// can be `null` if the reference is not to a constructor.
   CommentReference commentReference(Token newKeyword, Identifier identifier);
 
-  /// Returns a newly created compilation unit to have the given directives
-  /// and declarations. The [scriptTag] can be `null` if there is no script tag
-  /// in the compilation unit. The list of [directives] can be `null` if there
-  /// are no directives in the compilation unit. The list of [declarations] can
-  /// be `null` if there are no declarations in the compilation unit.
-  @Deprecated('Use compilationUnit2')
+  /// Returns a newly created compilation unit to have the given directives and
+  /// declarations.  The [scriptTag] can be `null` (or omitted) if there is no
+  /// script tag in the compilation unit.  The list of [declarations] can be
+  /// `null` (or omitted) if there are no directives in the compilation unit.
+  /// The list of `declarations` can be `null` (or omitted) if there are no
+  /// declarations in the compilation unit.  The [featureSet] can be `null` if
+  /// the set of features for this compilation unit is not known (this
+  /// restricts what analysis can be done of the compilation unit).
   CompilationUnit compilationUnit(
-      Token beginToken,
+      {@required Token beginToken,
       ScriptTag scriptTag,
       List<Directive> directives,
       List<CompilationUnitMember> declarations,
-      Token endToken,
-      [FeatureSet featureSet]);
+      @required Token endToken,
+      @required FeatureSet featureSet});
 
   /// Returns a newly created compilation unit to have the given directives and
   /// declarations.  The [scriptTag] can be `null` (or omitted) if there is no
@@ -173,6 +175,7 @@
   /// declarations in the compilation unit.  The [featureSet] can be `null` if
   /// the set of features for this compilation unit is not known (this
   /// restricts what analysis can be done of the compilation unit).
+  @Deprecated('Use compilationUnit')
   CompilationUnit compilationUnit2(
       {@required Token beginToken,
       ScriptTag scriptTag,
@@ -339,7 +342,7 @@
   /// Returns a newly created extends clause.
   ExtendsClause extendsClause(Token extendsKeyword, TypeName superclass);
 
-  /// Return a newly created extention declaration. The list of [typeParameters]
+  /// Return a newly created extension declaration. The list of [typeParameters]
   /// can be `null` if there are no type parameters.
   ExtensionDeclaration extensionDeclaration(
       {Comment comment,
@@ -353,6 +356,13 @@
       List<ClassMember> members,
       Token rightBracket});
 
+  /// Return a newly created extension override. The list of [typeArguments]
+  /// can be `null` if there are no type arguments.
+  ExtensionOverride extensionOverride(
+      {@required Identifier extensionName,
+      TypeArgumentList typeArguments,
+      @required ArgumentList argumentList});
+
   /// Returns a newly created field declaration. Either or both of the [comment]
   /// and [metadata] can be `null` if the declaration does not have the
   /// corresponding attribute. The [staticKeyword] can be `null` if the field is
@@ -470,16 +480,6 @@
       Token rightParenthesis,
       Statement body});
 
-  /// Returns a newly created for statement.
-  @Deprecated('Replaced by forStatement')
-  ForStatement forStatement2(
-      {Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopParts forLoopParts,
-      Token rightParenthesis,
-      Statement body});
-
   /// Returns a newly created function declaration. Either or both of the
   /// [comment] and [metadata] can be `null` if the function does not have the
   /// corresponding attribute. The [externalKeyword] can be `null` if the
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 1d89813..7aae724 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -22,7 +22,6 @@
 import 'dart:collection';
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart' show UIAsCodeVisitorMixin;
 
 /// An AST visitor that will recursively visit all of the nodes in an AST
 /// structure, similar to [GeneralizingAstVisitor]. This visitor uses a
@@ -128,9 +127,7 @@
 /// invoked and will cause the children of the visited node to not be visited.
 ///
 /// Clients may extend this class.
-class GeneralizingAstVisitor<R>
-    with UIAsCodeVisitorMixin<R>
-    implements AstVisitor<R> {
+class GeneralizingAstVisitor<R> implements AstVisitor<R> {
   @override
   R visitAdjacentStrings(AdjacentStrings node) => visitStringLiteral(node);
 
@@ -281,6 +278,9 @@
       visitCompilationUnitMember(node);
 
   @override
+  R visitExtensionOverride(ExtensionOverride node) => visitExpression(node);
+
+  @override
   R visitFieldDeclaration(FieldDeclaration node) => visitClassMember(node);
 
   @override
@@ -605,9 +605,7 @@
 /// visited.
 ///
 /// Clients may extend this class.
-class RecursiveAstVisitor<R>
-    with UIAsCodeVisitorMixin<R>
-    implements AstVisitor<R> {
+class RecursiveAstVisitor<R> implements AstVisitor<R> {
   @override
   R visitAdjacentStrings(AdjacentStrings node) {
     node.visitChildren(this);
@@ -849,6 +847,12 @@
   }
 
   @override
+  R visitExtensionOverride(ExtensionOverride node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitFieldDeclaration(FieldDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -1336,9 +1340,7 @@
 /// a whole structure) and that only need to visit a small number of node types.
 ///
 /// Clients may extend this class.
-class SimpleAstVisitor<R>
-    with UIAsCodeVisitorMixin<R>
-    implements AstVisitor<R> {
+class SimpleAstVisitor<R> implements AstVisitor<R> {
   @override
   R visitAdjacentStrings(AdjacentStrings node) => null;
 
@@ -1460,6 +1462,9 @@
   R visitExtensionDeclaration(ExtensionDeclaration node) => null;
 
   @override
+  R visitExtensionOverride(ExtensionOverride node) => null;
+
+  @override
   R visitFieldDeclaration(FieldDeclaration node) => null;
 
   @override
@@ -1713,9 +1718,7 @@
 /// want to catch when any other visit methods have been invoked.
 ///
 /// Clients may extend this class.
-class ThrowingAstVisitor<R>
-    with UIAsCodeVisitorMixin<R>
-    implements AstVisitor<R> {
+class ThrowingAstVisitor<R> implements AstVisitor<R> {
   @override
   R visitAdjacentStrings(AdjacentStrings node) => _throw(node);
 
@@ -1838,6 +1841,9 @@
   R visitExtensionDeclaration(ExtensionDeclaration node) => _throw(node);
 
   @override
+  R visitExtensionOverride(ExtensionOverride node) => _throw(node);
+
+  @override
   R visitFieldDeclaration(FieldDeclaration node) => _throw(node);
 
   @override
@@ -2097,7 +2103,7 @@
 /// An AST visitor that captures visit call timings.
 ///
 /// Clients may not extend, implement or mix-in this class.
-class TimedAstVisitor<T> with UIAsCodeVisitorMixin<T> implements AstVisitor<T> {
+class TimedAstVisitor<T> implements AstVisitor<T> {
   /// The base visitor whose visit methods will be timed.
   final AstVisitor<T> _baseVisitor;
 
@@ -2430,6 +2436,14 @@
   }
 
   @override
+  T visitExtensionOverride(ExtensionOverride node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitExtensionOverride(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitFieldDeclaration(FieldDeclaration node) {
     stopwatch.start();
     T result = _baseVisitor.visitFieldDeclaration(node);
@@ -3082,9 +3096,7 @@
 /// visited.
 ///
 /// Clients may extend this class.
-class UnifyingAstVisitor<R>
-    with UIAsCodeVisitorMixin<R>
-    implements AstVisitor<R> {
+class UnifyingAstVisitor<R> implements AstVisitor<R> {
   @override
   R visitAdjacentStrings(AdjacentStrings node) => visitNode(node);
 
@@ -3208,6 +3220,9 @@
   R visitExtensionDeclaration(ExtensionDeclaration node) => visitNode(node);
 
   @override
+  R visitExtensionOverride(ExtensionOverride node) => visitNode(node);
+
+  @override
   R visitFieldDeclaration(FieldDeclaration node) => visitNode(node);
 
   @override
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index ba10def..9559ff3 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -373,6 +373,10 @@
   /// unit.
   List<ClassElement> get enums;
 
+  /// Return a list containing all of the extensions contained in this
+  /// compilation unit.
+  List<ExtensionElement> get extensions;
+
   /// Return a list containing all of the top-level functions contained in this
   /// compilation unit.
   List<FunctionElement> get functions;
@@ -818,6 +822,9 @@
   static const ElementKind EXPORT =
       const ElementKind('EXPORT', 5, "export directive");
 
+  static const ElementKind EXTENSION =
+      const ElementKind('EXTENSION', 24, "extension");
+
   static const ElementKind FIELD = const ElementKind('FIELD', 6, "field");
 
   static const ElementKind FUNCTION =
@@ -957,6 +964,8 @@
 
   R visitExportElement(ExportElement element);
 
+  R visitExtensionElement(ExtensionElement element);
+
   R visitFieldElement(FieldElement element);
 
   R visitFieldFormalParameterElement(FieldFormalParameterElement element);
@@ -1046,6 +1055,40 @@
   LibraryElement get exportedLibrary;
 }
 
+/// An element that represents an extension.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExtensionElement implements Element {
+  /// Return a list containing all of the accessors (getters and setters)
+  /// declared in this extension.
+  List<PropertyAccessorElement> get accessors;
+
+  /// Return the type that is extended by this extension.
+  DartType get extendedType;
+
+  /// Return a list containing all of the methods declared in this extension.
+  List<MethodElement> get methods;
+
+  /// Return a list containing all of the type parameters declared by this
+  /// extension.
+  List<TypeParameterElement> get typeParameters;
+
+  /// Return the element representing the getter with the given [name] that is
+  /// declared in this extension, or `null` if this extension does not declare a
+  /// getter with the given name.
+  PropertyAccessorElement /*?*/ getGetter(String name);
+
+  /// Return the element representing the method with the given [name] that is
+  /// declared in this extension, or `null` if this extension does not declare a
+  /// method with the given name.
+  MethodElement /*?*/ getMethod(String name);
+
+  /// Return the element representing the setter with the given [name] that is
+  /// declared in this extension, or `null` if this extension does not declare a
+  /// setter with the given name.
+  PropertyAccessorElement /*?*/ getSetter(String name);
+}
+
 /// A field defined within a type.
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -1266,6 +1309,8 @@
   /// Return `true` if this library is part of the SDK.
   bool get isInSdk;
 
+  bool get isNonNullableByDefault;
+
   /// Return a list containing the strongly connected component in the
   /// import/export graph in which the current library resides.
   List<LibraryElement> get libraryCycle;
@@ -1299,8 +1344,6 @@
   /// included using the `part` directive.
   List<CompilationUnitElement> get units;
 
-  bool get isNonNullableByDefault;
-
   /// Return a list containing all of the imports that share the given [prefix],
   /// or an empty array if there are no such imports.
   List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
@@ -1453,7 +1496,8 @@
   bool get isRequiredPositional;
 
   /// Return the kind of this parameter.
-  @deprecated
+  @Deprecated('Use the getters isOptionalNamed, isOptionalPositional, '
+      'isRequiredNamed, and isRequiredPositional')
   ParameterKind get parameterKind;
 
   /// Return a list containing all of the parameters defined by this parameter.
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 7c2812a..f54f8c4 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -81,11 +81,6 @@
   /// Return `true` if this type represents the type 'Object'.
   bool get isObject;
 
-  /// Return `true` if this type represents a typename that couldn't be
-  /// resolved.
-  @deprecated
-  bool get isUndefined;
-
   /// Return `true` if this type represents the type 'void'.
   bool get isVoid;
 
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index fc6d4a6..f1543ad 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -101,6 +101,9 @@
   R visitExportElement(ExportElement element) => visitElement(element);
 
   @override
+  R visitExtensionElement(ExtensionElement element) => visitElement(element);
+
+  @override
   R visitFieldElement(FieldElement element) =>
       visitPropertyInducingElement(element);
 
@@ -213,6 +216,12 @@
   }
 
   @override
+  R visitExtensionElement(ExtensionElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitFieldElement(FieldElement element) {
     element.visitChildren(this);
     return null;
@@ -329,6 +338,9 @@
   R visitExportElement(ExportElement element) => null;
 
   @override
+  R visitExtensionElement(ExtensionElement element) => null;
+
+  @override
   R visitFieldElement(FieldElement element) => null;
 
   @override
@@ -400,6 +412,9 @@
   R visitExportElement(ExportElement element) => _throw(element);
 
   @override
+  R visitExtensionElement(ExtensionElement element) => _throw(element);
+
+  @override
   R visitFieldElement(FieldElement element) => _throw(element);
 
   @override
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 7c1fa00..e15ffd3 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -235,9 +235,10 @@
   CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
   CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
   CompileTimeErrorCode.NON_SYNC_FACTORY,
+  CompileTimeErrorCode.NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
   CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+  CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD,
   CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
-  CompileTimeErrorCode.NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
   CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
   CompileTimeErrorCode.NOT_MAP_SPREAD,
   CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
@@ -605,7 +606,6 @@
   StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
   StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
   StaticTypeWarningCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
-  StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
   StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
   StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT,
   StaticTypeWarningCode.UNDEFINED_FUNCTION,
@@ -796,8 +796,15 @@
    */
   final ErrorCode errorCode;
 
+  /**
+   * The message describing the problem.
+   */
   DiagnosticMessage _problemMessage;
 
+  /**
+   * The context messages associated with the problem. This list will be empty
+   * if there are no context messages.
+   */
   List<DiagnosticMessage> _contextMessages;
 
   /**
@@ -819,7 +826,8 @@
    * [contextMessages] are provided, they will be recorded with the error.
    */
   AnalysisError(this.source, int offset, int length, this.errorCode,
-      [List<Object> arguments, List<DiagnosticMessage> contextMessages]) {
+      [List<Object> arguments,
+      List<DiagnosticMessage> contextMessages = const []]) {
     String message = formatList(errorCode.message, arguments);
     String correctionTemplate = errorCode.correction;
     if (correctionTemplate != null) {
@@ -837,15 +845,17 @@
    * Initialize a newly created analysis error with given values.
    */
   AnalysisError.forValues(this.source, int offset, int length, this.errorCode,
-      String message, this._correction) {
+      String message, this._correction,
+      {List<DiagnosticMessage> contextMessages = const []}) {
     _problemMessage = new DiagnosticMessageImpl(
         filePath: source?.fullName,
         length: length,
         message: message,
         offset: offset);
+    _contextMessages = contextMessages;
   }
 
-  List<DiagnosticMessage> get contextMessages => _contextMessages ?? const [];
+  List<DiagnosticMessage> get contextMessages => _contextMessages;
 
   /**
    * Return the template used to create the correction to be displayed for this
@@ -866,18 +876,6 @@
   }
 
   /**
-   * Return `true` if this error can be shown to be a non-issue because of the
-   * result of type propagation.
-   */
-  @Deprecated(
-      'Type propagation is no longer performed, so this will never be true')
-  bool get isStaticOnly => false;
-
-  @Deprecated(
-      'Type propagation is no longer performed, so this can never be true')
-  void set isStaticOnly(bool value) {}
-
-  /**
    * The number of characters from the offset to the end of the source which
    * encompasses the compilation error.
    */
@@ -895,13 +893,6 @@
    */
   int get offset => _problemMessage.offset;
 
-  /**
-   * The character offset from the beginning of the source (zero based) where
-   * the error occurred.
-   */
-  @Deprecated('Set the offset when the error is created')
-  set offset(int offset) {}
-
   @override
   DiagnosticMessage get problemMessage => _problemMessage;
 
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index e593f13..f483397 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -70,6 +70,7 @@
   static const String TAG_ERROR = 'Err';
   static const String TAG_EXCEPTION = 'Ex';
   static const String TAG_FILE_READ = 'Read';
+  static const String TAG_INFO = 'Info';
   static const String TAG_LOG_ENTRY = 'Log';
   static const String TAG_NOTIFICATION = 'Noti';
   static const String TAG_PERFORMANCE = 'Perf';
@@ -164,6 +165,11 @@
   }
 
   /**
+   * Log unstructured text information for debugging purposes.
+   */
+  void logInfo(String message) => _log(TAG_INFO, message);
+
+  /**
    * Log that a log entry that was written to the analysis engine's log. The log
    * entry has the given [level] and [message], and was created at the given
    * [time].
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index ead50fe5..fb120f5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -29,6 +29,7 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/diagnostic/diagnostic.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show
@@ -94,7 +95,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 83;
+  static const int DATA_VERSION = 85;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
@@ -1717,13 +1718,25 @@
         AnalysisEngine.instance.instrumentationService
             .logError('No error code for "$error" in "$file"');
       } else {
+        List<DiagnosticMessageImpl> contextMessages;
+        if (error.contextMessages.isNotEmpty) {
+          contextMessages = <DiagnosticMessageImpl>[];
+          for (var message in error.contextMessages) {
+            contextMessages.add(DiagnosticMessageImpl(
+                filePath: message.filePath,
+                length: message.length,
+                message: message.message,
+                offset: message.offset));
+          }
+        }
         errors.add(new AnalysisError.forValues(
             file.source,
             error.offset,
             error.length,
             errorCode,
             error.message,
-            error.correction.isEmpty ? null : error.correction));
+            error.correction.isEmpty ? null : error.correction,
+            contextMessages: contextMessages ?? const []));
       }
     }
     return errors;
@@ -1814,14 +1827,26 @@
         ? indexUnit(resolvedUnit)
         : new AnalysisDriverUnitIndexBuilder();
     return new AnalysisDriverResolvedUnitBuilder(
-            errors: errors
-                .map((error) => new AnalysisDriverUnitErrorBuilder(
-                    offset: error.offset,
-                    length: error.length,
-                    uniqueName: error.errorCode.uniqueName,
-                    message: error.message,
-                    correction: error.correction))
-                .toList(),
+            errors: errors.map((error) {
+              List<DiagnosticMessageBuilder> contextMessages;
+              if (error.contextMessages != null) {
+                contextMessages = <DiagnosticMessageBuilder>[];
+                for (var message in error.contextMessages) {
+                  contextMessages.add(DiagnosticMessageBuilder(
+                      filePath: message.filePath,
+                      length: message.length,
+                      message: message.message,
+                      offset: message.offset));
+                }
+              }
+              return new AnalysisDriverUnitErrorBuilder(
+                  offset: error.offset,
+                  length: error.length,
+                  uniqueName: error.errorCode.uniqueName,
+                  message: error.message,
+                  correction: error.correction,
+                  contextMessages: contextMessages);
+            }).toList(),
             index: index)
         .toBuffer();
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index abd0bd5..0a2ac39 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -182,7 +182,7 @@
   static const bool constant_update_2018 = false;
 
   /// Expiration status of the experiment "control-flow-collections"
-  static const bool control_flow_collections = true;
+  static const bool control_flow_collections = false;
 
   /// Expiration status of the experiment "extension-methods"
   static const bool extension_methods = false;
@@ -194,7 +194,7 @@
   static const bool set_literals = true;
 
   /// Expiration status of the experiment "spread-collections"
-  static const bool spread_collections = true;
+  static const bool spread_collections = false;
 
   /// Expiration status of the experiment "triple-shift"
   static const bool triple_shift = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 665f248..f93cdc2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -686,7 +686,7 @@
 
   CompilationUnit _createEmptyCompilationUnit(FeatureSet featureSet) {
     var token = new Token.eof(0);
-    return astFactory.compilationUnit2(
+    return astFactory.compilationUnit(
         beginToken: token, endToken: token, featureSet: featureSet)
       ..lineInfo = new LineInfo(const <int>[0]);
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 1c23029..51debbd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -533,9 +533,8 @@
     }
   }
 
-  void recordUriReference(Element element, UriBasedDirective directive) {
-    recordRelation(
-        element, IndexRelationKind.IS_REFERENCED_BY, directive.uri, true);
+  void recordUriReference(Element element, StringLiteral uri) {
+    recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, uri, true);
   }
 
   @override
@@ -603,7 +602,7 @@
   @override
   visitExportDirective(ExportDirective node) {
     ExportElement element = node.element;
-    recordUriReference(element?.exportedLibrary, node);
+    recordUriReference(element?.exportedLibrary, node.uri);
     super.visitExportDirective(node);
   }
 
@@ -632,7 +631,7 @@
   @override
   visitImportDirective(ImportDirective node) {
     ImportElement element = node.element;
-    recordUriReference(element?.importedLibrary, node);
+    recordUriReference(element?.importedLibrary, node.uri);
     super.visitImportDirective(node);
   }
 
@@ -686,7 +685,7 @@
   visitPartDirective(PartDirective node) {
     CompilationUnitElement element = node.element;
     if (element?.source != null) {
-      recordUriReference(element, node);
+      recordUriReference(element, node.uri);
     }
     super.visitPartDirective(node);
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index ba3be49..a52b70d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/inheritance_override.dart';
@@ -76,6 +77,7 @@
   final Map<FileState, IgnoreInfo> _fileToIgnoreInfo = {};
   final Map<FileState, RecordingErrorListener> _errorListeners = {};
   final Map<FileState, ErrorReporter> _errorReporters = {};
+  final Map<FileState, FlowAnalysisResult> _fileToFlowAnalysisResult = {};
   final List<UsedImportedElements> _usedImportedElementsList = [];
   final List<UsedLocalElements> _usedLocalElementsList = [];
   final Map<FileState, List<PendingError>> _fileToPendingErrors = {};
@@ -411,7 +413,8 @@
     // Use the ErrorVerifier to compute errors.
     //
     ErrorVerifier errorVerifier = new ErrorVerifier(
-        errorReporter, _libraryElement, _typeProvider, _inheritance, false);
+        errorReporter, _libraryElement, _typeProvider, _inheritance, false,
+        flowAnalysisResult: _fileToFlowAnalysisResult[file]);
     unit.accept(errorVerifier);
   }
 
@@ -698,9 +701,16 @@
     // Nothing for RESOLVED_UNIT9?
     // Nothing for RESOLVED_UNIT10?
 
+    FlowAnalysisHelper flowAnalysisHelper;
+    if (unit.featureSet.isEnabled(Feature.non_nullable)) {
+      flowAnalysisHelper = FlowAnalysisHelper(_context.typeSystem, unit);
+      _fileToFlowAnalysisResult[file] = flowAnalysisHelper.result;
+      flowAnalysisHelper.result.putIntoNode(unit);
+    }
+
     unit.accept(new ResolverVisitor(
         _inheritance, _libraryElement, source, _typeProvider, errorListener,
-        featureSet: unit.featureSet));
+        featureSet: unit.featureSet, flowAnalysisHelper: flowAnalysisHelper));
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
index dfbaf6a..6fce596 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_api_signature.dart
@@ -105,6 +105,7 @@
       signature.addInt(variableList.variables.length);
       for (var variable in variableList.variables) {
         addTokens(variable.beginToken, variable.name.endToken);
+        signature.addBool(variable.initializer != null);
         addToken(variable.endToken.next); // `,` or `;`
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index f327523..31c1d5e 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -17,7 +17,6 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/constant/constant_verifier.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -807,11 +806,6 @@
       util.findPrevious(beginToken, target) ?? parent?.findPrevious(target);
 
   @override
-  @deprecated
-  E getAncestor<E extends AstNode>(Predicate<AstNode> predicate) =>
-      thisOrAncestorMatching(predicate);
-
-  @override
   E getProperty<E>(String name) {
     if (_propertyMap == null) {
       return null;
@@ -3935,6 +3929,85 @@
   }
 }
 
+/// An override to force resolution to choose a member from a specific
+/// extension.
+///
+///    extensionOverride ::=
+///        [Identifier] [TypeArgumentList]? [ArgumentList]
+class ExtensionOverrideImpl extends ExpressionImpl
+    implements ExtensionOverride {
+  /// The list of arguments to the override. In valid code this will contain a
+  /// single argument, which evaluates to the object being extended.
+  ArgumentListImpl _argumentList;
+
+  /// The name of the extension being selected.
+  IdentifierImpl _extensionName;
+
+  /// The type arguments to be applied to the extension, or `null` if no type
+  /// arguments were provided.
+  TypeArgumentListImpl _typeArguments;
+
+  ExtensionOverrideImpl(IdentifierImpl extensionName,
+      TypeArgumentListImpl typeArguments, ArgumentListImpl argumentList) {
+    _extensionName = _becomeParentOf(extensionName);
+    _typeArguments = _becomeParentOf(typeArguments);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList as ArgumentListImpl);
+  }
+
+  @override
+  Token get beginToken => _extensionName?.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(_extensionName)
+    ..add(_typeArguments)
+    ..add(_argumentList);
+
+  @override
+  Token get endToken => _argumentList?.endToken;
+
+  @override
+  Identifier get extensionName => _extensionName;
+
+  void set extensionName(Identifier extensionName) {
+    _extensionName = _becomeParentOf(extensionName as IdentifierImpl);
+  }
+
+  @override
+  Precedence get precedence => Precedence.postfix;
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments as TypeArgumentListImpl);
+  }
+
+  @override
+  // TODO(brianwilkerson) Either implement this getter or remove it if it isn't
+  //  needed.
+  List<DartType> get typeArgumentTypes => null;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) {
+    return visitor.visitExtensionOverride(this);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _extensionName?.accept(visitor);
+    _typeArguments?.accept(visitor);
+    _argumentList?.accept(visitor);
+  }
+}
+
 /// The declaration of one or more fields of the same type.
 ///
 ///    fieldDeclaration ::=
@@ -4646,12 +4719,20 @@
   }
 }
 
-@Deprecated('Replaced by ForStatementImpl')
-class ForStatement2Impl extends ForStatementImpl implements ForStatement2 {
+class ForStatementImpl extends StatementImpl
+    with ForMixin
+    implements ForStatement {
+  /// The body of the loop.
+  StatementImpl _body;
+
   /// Initialize a newly created for statement.
-  ForStatement2Impl(Token awaitKeyword, Token forKeyword, Token leftParenthesis,
-      ForLoopPartsImpl forLoopParts, Token rightParenthesis, StatementImpl body)
-      : super._() {
+  ForStatementImpl(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopPartsImpl forLoopParts,
+      Token rightParenthesis,
+      StatementImpl body) {
     this.awaitKeyword = awaitKeyword;
     this.forKeyword = forKeyword;
     this.leftParenthesis = leftParenthesis;
@@ -4660,26 +4741,6 @@
     _body = _becomeParentOf(body);
   }
 
-  @override
-  E accept<E>(AstVisitor<E> visitor) => visitor.visitForStatement2(this);
-}
-
-abstract class ForStatementImpl extends StatementImpl
-    with ForMixin
-    implements ForStatement {
-  /// The body of the loop.
-  StatementImpl _body;
-
-  /// Initialize a newly created for statement.
-  factory ForStatementImpl(
-      Token awaitKeyword,
-      Token forKeyword,
-      Token leftParenthesis,
-      ForLoopPartsImpl forLoopParts,
-      Token rightParenthesis,
-      // ignore: deprecated_member_use_from_same_package
-      StatementImpl body) = ForStatement2Impl;
-
   ForStatementImpl._();
 
   Statement get body => _body;
@@ -6110,88 +6171,6 @@
   E accept<E>(AstVisitor<E> visitor) =>
       visitor.visitInstanceCreationExpression(this);
 
-  /// Return `true` if it would be valid for this instance creation expression
-  /// to have a keyword of `const`. It is valid if
-  ///
-  /// * the invoked constructor is a `const` constructor,
-  /// * all of the arguments are, or could be, constant expressions, and
-  /// * the evaluation of the constructor would not produce an exception.
-  ///
-  /// Note that this method will return `false` if the AST has not been resolved
-  /// because without resolution it cannot be determined whether the constructor
-  /// is a `const` constructor.
-  ///
-  /// Also note that this method can cause constant evaluation to occur, which
-  /// can be computationally expensive.
-  ///
-  /// Deprecated: Use `LinterContext.canBeConst` instead.
-  @deprecated
-  bool canBeConst() {
-    //
-    // Verify that the invoked constructor is a const constructor.
-    //
-    ConstructorElement element = staticElement;
-    if (element == null || !element.isConst) {
-      return false;
-    }
-    //
-    // Verify that all of the arguments are, or could be, constant expressions.
-    //
-    for (Expression argument in argumentList.arguments) {
-      argument = argument.unParenthesized;
-      if (argument is NamedExpression) {
-        argument = (argument as NamedExpression).expression.unParenthesized;
-      }
-      if (argument is InstanceCreationExpression) {
-        if (!argument.isConst) {
-          return false;
-        }
-      } else if (argument is TypedLiteral) {
-        if (!argument.isConst) {
-          return false;
-        }
-      } else if (argument is LiteralImpl) {
-        if (argument is StringInterpolation) {
-          return false;
-        } else if (argument is AdjacentStrings) {
-          for (StringLiteral string in (argument as AdjacentStrings).strings) {
-            if (string is StringInterpolation) {
-              return false;
-            }
-          }
-        }
-      } else if (argument is Identifier) {
-        Element element = argument.staticElement;
-        if (element is PropertyAccessorElement && !element.variable.isConst) {
-          return false;
-        } else if (element is VariableElement && !element.isConst) {
-          return false;
-        }
-      } else {
-        return false;
-      }
-    }
-    //
-    // Verify that the evaluation of the constructor would not produce an
-    // exception.
-    //
-    Token oldKeyword = keyword;
-    ConstantAnalysisErrorListener listener =
-        new ConstantAnalysisErrorListener();
-    try {
-      keyword = new KeywordToken(Keyword.CONST, offset);
-      LibraryElement library = element.library;
-      AnalysisContext context = library.context;
-      ErrorReporter errorReporter = new ErrorReporter(listener, element.source);
-      accept(new ConstantVerifier(errorReporter, library, context.typeProvider,
-          context.declaredVariables,
-          featureSet: FeatureSet.fromEnableFlags([])));
-    } finally {
-      keyword = oldKeyword;
-    }
-    return !listener.hasConstError;
-  }
-
   @override
   void visitChildren(AstVisitor visitor) {
     _constructorName?.accept(visitor);
@@ -6827,10 +6806,6 @@
   NodeList<CollectionElement> get elements => _elements;
 
   @override
-  @Deprecated('Replaced by elements')
-  NodeList<CollectionElement> get elements2 => _elements;
-
-  @override
   Token get endToken => rightBracket;
 
   @override
@@ -8748,10 +8723,6 @@
   NodeList<CollectionElement> get elements => _elements;
 
   @override
-  @Deprecated('Replaced by elements')
-  NodeList<CollectionElement> get elements2 => _elements;
-
-  @override
   Token get endToken => rightBracket;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 1cd13f3..f542bd2 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -179,18 +179,18 @@
       new CommentReferenceImpl(newKeyword, identifier);
 
   @override
-  @deprecated
   CompilationUnit compilationUnit(
-          Token beginToken,
+          {Token beginToken,
           ScriptTag scriptTag,
           List<Directive> directives,
           List<CompilationUnitMember> declarations,
           Token endToken,
-          [FeatureSet featureSet]) =>
+          FeatureSet featureSet}) =>
       new CompilationUnitImpl(beginToken, scriptTag, directives, declarations,
           endToken, featureSet);
 
   @override
+  @deprecated
   CompilationUnit compilationUnit2(
           {Token beginToken,
           ScriptTag scriptTag,
@@ -394,6 +394,13 @@
           rightBracket);
 
   @override
+  ExtensionOverride extensionOverride(
+          {@required Identifier extensionName,
+          TypeArgumentList typeArguments,
+          @required ArgumentList argumentList}) =>
+      ExtensionOverrideImpl(extensionName, typeArguments, argumentList);
+
+  @override
   FieldDeclaration fieldDeclaration(
           Comment comment,
           List<Annotation> metadata,
@@ -522,23 +529,6 @@
   }
 
   @override
-  @Deprecated('Replaced by forStatement')
-  ForStatement forStatement2(
-          {Token awaitKeyword,
-          Token forKeyword,
-          Token leftParenthesis,
-          ForLoopParts forLoopParts,
-          Token rightParenthesis,
-          Statement body}) =>
-      forStatement(
-          awaitKeyword: awaitKeyword,
-          forKeyword: forKeyword,
-          leftParenthesis: leftParenthesis,
-          forLoopParts: forLoopParts,
-          rightParenthesis: rightParenthesis,
-          body: body);
-
-  @override
   FunctionDeclaration functionDeclaration(
           Comment comment,
           List<Annotation> metadata,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 807d3c6..f1a7574 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -30,9 +30,7 @@
  * will only clone the structure, it will not preserve any resolution results or
  * properties associated with the nodes.
  */
-class AstCloner
-    with UIAsCodeVisitorMixin<AstNode>
-    implements AstVisitor<AstNode> {
+class AstCloner implements AstVisitor<AstNode> {
   /**
    * A flag indicating whether tokens should be cloned while cloning an AST
    * structure.
@@ -285,7 +283,7 @@
 
   @override
   CompilationUnit visitCompilationUnit(CompilationUnit node) {
-    CompilationUnit clone = astFactory.compilationUnit2(
+    CompilationUnit clone = astFactory.compilationUnit(
         beginToken: cloneToken(node.beginToken),
         scriptTag: cloneNode(node.scriptTag),
         directives: cloneNodeList(node.directives),
@@ -464,6 +462,13 @@
           rightBracket: cloneToken(node.rightBracket));
 
   @override
+  ExtensionOverride visitExtensionOverride(ExtensionOverride node) =>
+      astFactory.extensionOverride(
+          extensionName: cloneNode(node.extensionName),
+          typeArguments: cloneNode(node.typeArguments),
+          argumentList: cloneNode(node.argumentList));
+
+  @override
   FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
       astFactory.fieldDeclaration2(
           comment: cloneNode(node.documentationComment),
@@ -1128,9 +1133,7 @@
  * An AstVisitor that compares the structure of two AstNodes to see whether they
  * are equal.
  */
-class AstComparator
-    with UIAsCodeVisitorMixin<bool>
-    implements AstVisitor<bool> {
+class AstComparator implements AstVisitor<bool> {
   /**
    * The AST node with which the node being visited is to be compared. This is
    * only valid at the beginning of each visit method (until [isEqualNodes] is
@@ -1608,6 +1611,14 @@
   }
 
   @override
+  bool visitExtensionOverride(ExtensionOverride node) {
+    ExtensionOverride other = _other as ExtensionOverride;
+    return isEqualNodes(node.extensionName, other.extensionName) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualNodes(node.argumentList, other.argumentList);
+  }
+
+  @override
   bool visitFieldDeclaration(FieldDeclaration node) {
     FieldDeclaration other = _other as FieldDeclaration;
     return isEqualNodes(
@@ -2477,9 +2488,7 @@
  * results.
  */
 @deprecated
-class IncrementalAstCloner
-    with UIAsCodeVisitorMixin<AstNode>
-    implements AstVisitor<AstNode> {
+class IncrementalAstCloner implements AstVisitor<AstNode> {
   /**
    * The node to be replaced during the cloning process.
    */
@@ -2674,7 +2683,7 @@
 
   @override
   CompilationUnit visitCompilationUnit(CompilationUnit node) {
-    CompilationUnitImpl copy = astFactory.compilationUnit2(
+    CompilationUnitImpl copy = astFactory.compilationUnit(
         beginToken: _mapToken(node.beginToken),
         scriptTag: _cloneNode(node.scriptTag),
         directives: _cloneNodeList(node.directives),
@@ -2862,6 +2871,13 @@
           rightBracket: _mapToken(node.rightBracket));
 
   @override
+  ExtensionOverride visitExtensionOverride(ExtensionOverride node) =>
+      astFactory.extensionOverride(
+          extensionName: _cloneNode(node.extensionName),
+          typeArguments: _cloneNode(node.typeArguments),
+          argumentList: _cloneNode(node.argumentList));
+
+  @override
   FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
       astFactory.fieldDeclaration2(
           comment: _cloneNode(node.documentationComment),
@@ -3825,7 +3841,7 @@
 /**
  * An object that will replace one child node in an AST node with another node.
  */
-class NodeReplacer with UIAsCodeVisitorMixin<bool> implements AstVisitor<bool> {
+class NodeReplacer implements AstVisitor<bool> {
   /**
    * The node being replaced.
    */
@@ -4300,6 +4316,22 @@
   }
 
   @override
+  bool visitExtensionOverride(ExtensionOverride node) {
+    if (identical(node.extensionName, _oldNode)) {
+      (node as ExtensionOverrideImpl).extensionName = _newNode as Identifier;
+      return true;
+    } else if (identical(node.typeArguments, _oldNode)) {
+      (node as ExtensionOverrideImpl).typeArguments =
+          _newNode as TypeArgumentList;
+      return true;
+    } else if (identical(node.argumentList, _oldNode)) {
+      (node as ExtensionOverrideImpl).argumentList = _newNode as ArgumentList;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitFieldDeclaration(FieldDeclaration node) {
     if (identical(node.fields, _oldNode)) {
       node.fields = _newNode as VariableDeclarationList;
@@ -5187,9 +5219,7 @@
  * another as long as the structures of the corresponding children of a pair of
  * nodes are the same.
  */
-class ResolutionCopier
-    with UIAsCodeVisitorMixin<bool>
-    implements AstVisitor<bool> {
+class ResolutionCopier implements AstVisitor<bool> {
   /**
    * The AST node with which the node being visited is to be compared. This is
    * only valid at the beginning of each visit method (until [isEqualNodes] is
@@ -5673,6 +5703,15 @@
   }
 
   @override
+  bool visitExtensionOverride(ExtensionOverride node) {
+    ExtensionOverride toNode = this._toNode as ExtensionOverride;
+    return _and(
+        _isEqualNodes(node.extensionName, toNode.extensionName),
+        _isEqualNodes(node.typeArguments, toNode.typeArguments),
+        _isEqualNodes(node.argumentList, toNode.argumentList));
+  }
+
+  @override
   bool visitFieldDeclaration(FieldDeclaration node) {
     FieldDeclaration toNode = this._toNode as FieldDeclaration;
     return _and(
@@ -6896,9 +6935,7 @@
  * This class has been deprecated. Use the class ToSourceVisitor2 instead.
  */
 @deprecated
-class ToSourceVisitor
-    with UIAsCodeVisitorMixin<void>
-    implements AstVisitor<void> {
+class ToSourceVisitor implements AstVisitor<void> {
   /**
    * The writer to which the source is to be written.
    */
@@ -7258,6 +7295,13 @@
   }
 
   @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    _visitNode(node.extensionName);
+    _visitNode(node.typeArguments);
+    _visitNode(node.argumentList);
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
     _visitTokenWithSuffix(node.staticKeyword, " ");
@@ -8057,9 +8101,7 @@
  * A visitor used to write a source representation of a visited AST node (and
  * all of it's children) to a sink.
  */
-class ToSourceVisitor2
-    with UIAsCodeVisitorMixin<void>
-    implements AstVisitor<void> {
+class ToSourceVisitor2 implements AstVisitor<void> {
   /**
    * The sink to which the source is to be written.
    */
@@ -8560,6 +8602,13 @@
   }
 
   @override
+  void visitExtensionOverride(ExtensionOverride node) {
+    safelyVisitNode(node.extensionName);
+    safelyVisitNode(node.typeArguments);
+    safelyVisitNode(node.argumentList);
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
     safelyVisitTokenWithSuffix(node.staticKeyword, " ");
@@ -9240,13 +9289,3 @@
     }
   }
 }
-
-/// Mixin allowing visitor classes to forward the visit method for
-/// `ForStatement2` to `ForStatement`
-mixin UIAsCodeVisitorMixin<R> implements AstVisitor<R> {
-  @override
-  @deprecated
-  R visitForStatement2(ForStatement2 node) {
-    return visitForStatement(node);
-  }
-}
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 8086e2c..caa0877 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -1332,6 +1332,7 @@
     variableName.staticElement = element;
     element.isConst = isConst;
     element.isFinal = isFinal;
+    element.isLate = node.isLate;
     buildVariableInitializer(element, initializerNode);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 199de05..e323a01 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -479,12 +479,6 @@
       this._unlinkedClass, CompilationUnitElementImpl enclosingUnit)
       : super.forSerialized(enclosingUnit);
 
-  /// Set whether this class is abstract.
-  @Deprecated('Use isAbstract instead')
-  void set abstract(bool isAbstract) {
-    this.isAbstract = isAbstract;
-  }
-
   @override
   List<PropertyAccessorElement> get accessors {
     if (_accessors != null) return _accessors;
@@ -1618,6 +1612,10 @@
   /// A list containing all of the enums contained in this compilation unit.
   List<ClassElement> _enums;
 
+  /// A list containing all of the extensions contained in this compilation
+  /// unit.
+  List<ExtensionElement> _extensions;
+
   /// A list containing all of the top-level functions contained in this
   /// compilation unit.
   List<FunctionElement> _functions;
@@ -1774,6 +1772,32 @@
   }
 
   @override
+  List<ExtensionElement> get extensions {
+    if (_extensions != null) {
+      return _extensions;
+    }
+
+    if (linkedNode != null) {
+      // TODO(brianwilkerson) Implement this.
+    } else if (_unlinkedUnit != null) {
+      return _extensions = _unlinkedUnit.extensions
+          .map((e) => ExtensionElementImpl.forSerialized(e, this))
+          .toList(growable: false);
+    }
+
+    return _extensions ?? const <ExtensionElement>[];
+  }
+
+  /// Set the extensions contained in this compilation unit to the given
+  /// [extensions].
+  void set extensions(List<ExtensionElement> extensions) {
+    for (ExtensionElement extension in extensions) {
+      (extension as ExtensionElementImpl).enclosingElement = this;
+    }
+    this._extensions = extensions;
+  }
+
+  @override
   List<FunctionElement> get functions {
     if (_functions != null) return _functions;
 
@@ -4036,12 +4060,6 @@
       this._unlinkedEnum, CompilationUnitElementImpl enclosingUnit)
       : super.forSerialized(enclosingUnit);
 
-  /// Set whether this class is abstract.
-  @Deprecated('This setter will be removed')
-  void set abstract(bool isAbstract) {
-    _assertNotResynthesized(_unlinkedEnum);
-  }
-
   @override
   List<PropertyAccessorElement> get accessors {
     if (_accessors == null) {
@@ -4907,6 +4925,267 @@
   }
 }
 
+/// A concrete implementation of an [ExtensionElement].
+class ExtensionElementImpl extends ElementImpl implements ExtensionElement {
+  /// The unlinked representation of the extension in the summary.
+  final /* UnlinkedExtension */ _unlinkedExtension;
+
+  /// A list containing all of the type parameters declared by this extension.
+  List<TypeParameterElement> _typeParameters;
+
+  /// The type being extended.
+  DartType _extendedType;
+
+  /// A list containing all of the accessors (getters and setters) contained in
+  /// this extension.
+  List<PropertyAccessorElement> _accessors;
+
+  /// A list containing all of the methods contained in this extension.
+  List<MethodElement> _methods;
+
+  /// Initialize a newly created extension element to have the given [name] at
+  /// the given [offset] in the file that contains the declaration of this
+  /// element.
+  ExtensionElementImpl(String name, int nameOffset)
+      : _unlinkedExtension = null,
+        super(name, nameOffset);
+
+  /// Initialize a newly created extension element to have the given [name].
+  ExtensionElementImpl.forNode(Identifier name)
+      : _unlinkedExtension = null,
+        super.forNode(name);
+
+  /// Initialize using the given serialized information.
+  ExtensionElementImpl.forSerialized(
+      this._unlinkedExtension, CompilationUnitElementImpl enclosingUnit)
+      : super.forSerialized(enclosingUnit);
+
+  @override
+  List<PropertyAccessorElement> get accessors {
+    if (_accessors != null) {
+      return _accessors;
+    }
+
+    if (linkedNode != null) {
+      if (linkedNode is ExtensionDeclaration) {
+        // TODO(brianwilkerson) Implement this.
+//        _createPropertiesAndAccessors();
+//        assert(_accessors != null);
+//        return _accessors;
+      } else {
+        return _accessors = const [];
+      }
+    } else if (_unlinkedExtension != null) {
+      // TODO(brianwilkerson) Implement this.
+//      _resynthesizePropertyAccessors();
+    }
+
+    return _accessors ??= const <PropertyAccessorElement>[];
+  }
+
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    _assertNotResynthesized(_unlinkedExtension);
+    for (PropertyAccessorElement accessor in accessors) {
+      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+    }
+    _accessors = accessors;
+  }
+
+  @override
+  DartType get extendedType {
+    if (_extendedType != null) {
+      return _extendedType;
+    }
+
+    if (linkedNode != null) {
+      // TODO(brianwilkerson) Implement this.
+//      var context = enclosingUnit.linkedContext;
+//      return _extendedType = context.getExtendedType(linkedNode)?.type;
+    } else if (_unlinkedExtension != null) {
+      return _extendedType = enclosingUnit.resynthesizerContext
+          .resolveTypeRef(this, _unlinkedExtension.extendedType);
+    }
+
+    return _extendedType;
+  }
+
+  void set extendedType(DartType extendedType) {
+    _assertNotResynthesized(_unlinkedExtension);
+    _extendedType = extendedType;
+  }
+
+  @override
+  ElementKind get kind => ElementKind.EXTENSION;
+
+  @override
+  List<MethodElement> get methods {
+    if (_methods != null) {
+      return _methods;
+    }
+
+    if (linkedNode != null) {
+      // TODO(brianwilkerson) Implement this.
+//      var context = enclosingUnit.linkedContext;
+//      var containerRef = reference.getChild('@method');
+//      return _methods = context
+//          .getMethods(linkedNode)
+//          .where((node) => node.propertyKeyword == null)
+//          .map((node) {
+//        var name = node.name.name;
+//        var reference = containerRef.getChild(name);
+//        if (reference.hasElementFor(node)) {
+//          return reference.element as MethodElement;
+//        }
+//        return MethodElementImpl.forLinkedNode(this, reference, node);
+//      }).toList();
+    } else if (_unlinkedExtension != null) {
+      // TODO(brianwilkerson) Implement this.
+//      var unlinkedExecutables = _unlinkedExtension.executables;
+//
+//      var length = unlinkedExecutables.length;
+//      if (length == 0) {
+//        return _methods = const <MethodElement>[];
+//      }
+//
+//      var count = 0;
+//      for (var i = 0; i < length; i++) {
+//        var e = unlinkedExecutables[i];
+//        if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+//          count++;
+//        }
+//      }
+//      if (count == 0) {
+//        return _methods = const <MethodElement>[];
+//      }
+//
+//      var methods = new List<MethodElement>(count);
+//      var index = 0;
+//      for (var i = 0; i < length; i++) {
+//        var e = unlinkedExecutables[i];
+//        if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+//          methods[index++] = new MethodElementImpl.forSerialized(e, this);
+//        }
+//      }
+//      return _methods = methods;
+    }
+    return _methods = const <MethodElement>[];
+  }
+
+  /// Set the methods contained in this extension to the given [methods].
+  void set methods(List<MethodElement> methods) {
+    _assertNotResynthesized(_unlinkedExtension);
+    for (MethodElement method in methods) {
+      (method as MethodElementImpl).enclosingElement = this;
+    }
+    _methods = methods;
+  }
+
+  @override
+  String get name {
+    if (linkedNode != null) {
+      return reference.name;
+    }
+    if (_unlinkedExtension != null) {
+      return _unlinkedExtension.name;
+    }
+    return super.name;
+  }
+
+  @override
+  int get nameOffset {
+    if (linkedNode != null) {
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
+    }
+
+    int offset = super.nameOffset;
+    if (offset == 0 && _unlinkedExtension != null) {
+      return _unlinkedExtension.nameOffset;
+    }
+    return offset;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters {
+    if (_typeParameters != null) {
+      return _typeParameters;
+    }
+
+    if (linkedNode != null) {
+      var typeParameters = linkedContext.getTypeParameters2(linkedNode);
+      if (typeParameters == null) {
+        return _typeParameters = const [];
+      }
+      var containerRef = reference.getChild('@typeParameter');
+      return _typeParameters =
+          typeParameters.typeParameters.map<TypeParameterElement>((node) {
+        var reference = containerRef.getChild(node.name.name);
+        if (reference.hasElementFor(node)) {
+          return reference.element as TypeParameterElement;
+        }
+        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+      }).toList();
+    } else if (_unlinkedExtension != null) {
+      List<UnlinkedTypeParam> unlinkedParams =
+          _unlinkedExtension?.typeParameters;
+      if (unlinkedParams != null) {
+        int numTypeParameters = unlinkedParams.length;
+        _typeParameters = new List<TypeParameterElement>(numTypeParameters);
+        for (int i = 0; i < numTypeParameters; i++) {
+          _typeParameters[i] = new TypeParameterElementImpl.forSerialized(
+              unlinkedParams[i], this);
+        }
+      }
+    }
+
+    return _typeParameters ?? const <TypeParameterElement>[];
+  }
+
+  /// Set the type parameters defined by this extension to the given
+  /// [typeParameters].
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    _assertNotResynthesized(_unlinkedExtension);
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  T accept<T>(ElementVisitor<T> visitor) {
+    return visitor.visitExtensionElement(this);
+  }
+
+  @override
+  PropertyAccessorElement getGetter(String getterName) {
+    int length = accessors.length;
+    for (int i = 0; i < length; i++) {
+      PropertyAccessorElement accessor = accessors[i];
+      if (accessor.isGetter && accessor.name == getterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+
+  @override
+  MethodElement getMethod(String methodName) {
+    int length = methods.length;
+    for (int i = 0; i < length; i++) {
+      MethodElement method = methods[i];
+      if (method.name == methodName) {
+        return method;
+      }
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement getSetter(String setterName) {
+    return AbstractClassElementImpl.getSetterFromAccessors(
+        setterName, accessors);
+  }
+}
+
 /// A concrete implementation of a [FieldElement].
 class FieldElementImpl extends PropertyInducingElementImpl
     implements FieldElement {
@@ -7162,15 +7441,17 @@
 
   @override
   bool get isLate {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.isLate(linkedNode);
-    }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.isLate;
     }
     return hasModifier(Modifier.LATE);
   }
 
+  /// Set whether this variable is late.
+  void set isLate(bool isLate) {
+    setModifier(Modifier.LATE, isLate);
+  }
+
   @override
   bool get isPotentiallyMutatedInClosure => true;
 
@@ -7230,12 +7511,6 @@
       UnlinkedExecutable serializedExecutable, ClassElementImpl enclosingClass)
       : super.forSerialized(serializedExecutable, enclosingClass);
 
-  /// Set whether this method is abstract.
-  @Deprecated('Use isAbstract instead')
-  void set abstract(bool isAbstract) {
-    this.isAbstract = isAbstract;
-  }
-
   @override
   String get displayName {
     String displayName = super.displayName;
@@ -8942,12 +9217,6 @@
     isSynthetic = true;
   }
 
-  /// Set whether this accessor is abstract.
-  @Deprecated('Use isAbstract instead')
-  void set abstract(bool isAbstract) {
-    this.isAbstract = isAbstract;
-  }
-
   @override
   PropertyAccessorElement get correspondingGetter {
     if (isGetter || variable == null) {
@@ -9514,7 +9783,7 @@
 
   /// Initialize using the given serialized information.
   TypeParameterElementImpl.forSerialized(
-      this._unlinkedTypeParam, TypeParameterizedElementMixin enclosingElement)
+      this._unlinkedTypeParam, ElementImpl enclosingElement)
       : super.forSerialized(enclosingElement);
 
   /// Initialize a newly created synthetic type parameter element to have the
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 67f745c..597c39a 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -214,6 +214,9 @@
   List<ClassElement> get enums => actualElement.enums;
 
   @override
+  List<ExtensionElement> get extensions => actualElement.extensions;
+
+  @override
   List<FunctionElement> get functions => actualElement.functions;
 
   @override
@@ -894,9 +897,6 @@
   LibraryElement get actualElement => super.actualElement as LibraryElement;
 
   @override
-  bool get isNonNullableByDefault => actualElement.isNonNullableByDefault;
-
-  @override
   CompilationUnitElement get definingCompilationUnit =>
       actualElement.definingCompilationUnit;
 
@@ -940,6 +940,9 @@
   bool get isInSdk => actualElement.isInSdk;
 
   @override
+  bool get isNonNullableByDefault => actualElement.isNonNullableByDefault;
+
+  @override
   ElementKind get kind => ElementKind.LIBRARY;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 27dd52e..90c8f23 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1212,14 +1212,18 @@
       variables1.add(variable1);
       variables2.add(variable2);
       variablesFresh.add(variableFresh);
+
       DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
       DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
       bound1 = bound1.substitute2(variablesFresh, variables1);
       bound2 = bound2.substitute2(variablesFresh, variables2);
-      pFresh.bound = bound2;
       if (!relation(bound2, bound1, p2, p1)) {
         return null;
       }
+
+      if (!bound2.isDynamic) {
+        pFresh.bound = bound2;
+      }
     }
     return variablesFresh;
   }
@@ -2838,9 +2842,6 @@
   bool get isObject => false;
 
   @override
-  bool get isUndefined => false;
-
-  @override
   bool get isVoid => false;
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index ab41831..99d3f9e 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -40,6 +40,9 @@
   List<ClassElement> get enums => wrappedUnit.enums;
 
   @override
+  List<ExtensionElement> get extensions => wrappedUnit.extensions;
+
+  @override
   List<FunctionElement> get functions => wrappedUnit.functions;
 
   @override
@@ -187,11 +190,12 @@
   int get uriOffset => wrappedUnit.uriOffset;
 
   @override
-  T accept<T>(ElementVisitor<T> visitor) => wrappedUnit.accept(visitor);
+  T accept<T>(ElementVisitor<T> visitor) => wrappedUnit
+      .accept(visitor); // ignore: deprecated_member_use_from_same_package
 
   @override
-  String computeDocumentationComment() => wrappedUnit
-      .computeDocumentationComment(); // ignore: deprecated_member_use_from_same_package
+  String computeDocumentationComment() =>
+      wrappedUnit.computeDocumentationComment();
 
   @deprecated
   @override
@@ -426,9 +430,6 @@
   AnalysisContext get context => wrappedLib.context;
 
   @override
-  bool get isNonNullableByDefault => wrappedLib.isNonNullableByDefault;
-
-  @override
   CompilationUnitElement get definingCompilationUnit =>
       wrappedLib.definingCompilationUnit;
 
@@ -541,6 +542,9 @@
   bool get isJS => hasJS;
 
   @override
+  bool get isNonNullableByDefault => wrappedLib.isNonNullableByDefault;
+
+  @override
   bool get isOverride => hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
index b711bcb..237c3ab 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
@@ -2,15 +2,17 @@
 // 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.
 
-/// Sets of variables that are potentially assigned in a statement.
+/// Sets of local variables that are potentially assigned in a statement.
+///
+/// These statements are loops, `switch`, and `try` statements.
 class AssignedVariables<Statement, Element> {
   final emptySet = Set<Element>();
 
-  /// Mapping from a [Statement] representing a loop to the set of variables
-  /// that are potentially assigned in that loop.
+  /// Mapping from a [Statement] to the set of local variables that are
+  /// potentially assigned in that statement.
   final Map<Statement, Set<Element>> _map = {};
 
-  /// The stack of nested nodes.
+  /// The stack of nested statements.
   final List<Set<Element>> _stack = [];
 
   AssignedVariables();
@@ -21,12 +23,12 @@
     return _map[statement] ?? emptySet;
   }
 
-  void beginLoop() {
+  void beginStatement() {
     var set = Set<Element>.identity();
     _stack.add(set);
   }
 
-  void endLoop(Statement node) {
+  void endStatement(Statement node) {
     _map[node] = _stack.removeLast();
   }
 
@@ -41,10 +43,6 @@
   final _ElementSet<Element> _emptySet;
   final _State<Element, Type> _identity;
 
-  /// The output list of variables that were read before they were written.
-  /// TODO(scheglov) use _ElementSet?
-  final List<Element> readBeforeWritten = [];
-
   /// The [NodeOperations], used to manipulate expressions.
   final NodeOperations<Expression> nodeOperations;
 
@@ -126,6 +124,17 @@
     _current = _current.add(variable, assigned: assigned);
   }
 
+  void booleanLiteral(Expression expression, bool value) {
+    _condition = expression;
+    if (value) {
+      _conditionTrue = _current;
+      _conditionFalse = _identity;
+    } else {
+      _conditionTrue = _identity;
+      _conditionFalse = _current;
+    }
+  }
+
   void conditional_elseBegin(Expression conditionalExpression,
       Expression thenExpression, bool isBool) {
     var afterThen = _current;
@@ -223,12 +232,6 @@
     _current = _join(falseCondition, breakState);
   }
 
-  void falseLiteral(Expression expression) {
-    _condition = expression;
-    _conditionTrue = _identity;
-    _conditionFalse = _current;
-  }
-
   void forEachStatement_bodyBegin(Set<Element> loopAssigned) {
     _stack.add(_current);
     _current = _current.removePromotedAll(loopAssigned);
@@ -352,6 +355,11 @@
     _current = trueCondition;
   }
 
+  /// Return whether the [variable] is definitely assigned in the current state.
+  bool isAssigned(Element variable) {
+    return !_current.notAssigned.contains(variable);
+  }
+
   void isExpression_end(
       Expression isExpression, Element variable, bool isNot, Type type) {
     if (functionBody.isPotentiallyMutatedInClosure(variable)) {
@@ -368,12 +376,12 @@
     }
   }
 
-  /// Return `true` if the [variable] is known to be be nullable.
+  /// Return `true` if the [variable] is known to be be non-nullable.
   bool isNonNullable(Element variable) {
     return !_current.notNonNullable.contains(variable);
   }
 
-  /// Return `true` if the [variable] is known to be be non-nullable.
+  /// Return `true` if the [variable] is known to be be nullable.
   bool isNullable(Element variable) {
     return !_current.notNullable.contains(variable);
   }
@@ -452,20 +460,6 @@
     return _current.promoted[variable];
   }
 
-  /// Register read of the given [variable] in the current state.
-  void read(Element variable) {
-    if (_current.notAssigned.contains(variable)) {
-      // Add to the list of violating variables, if not there yet.
-      for (var i = 0; i < readBeforeWritten.length; ++i) {
-        var violatingVariable = readBeforeWritten[i];
-        if (identical(violatingVariable, variable)) {
-          return;
-        }
-      }
-      readBeforeWritten.add(variable);
-    }
-  }
-
   /// The [notPromoted] set contains all variables that are potentially
   /// assigned in other cases that might target this with `continue`, so
   /// these variables might have different types and are "un-promoted" from
@@ -494,12 +488,6 @@
     _stack.add(_current); // afterExpression
   }
 
-  void trueLiteral(Expression expression) {
-    _condition = expression;
-    _conditionTrue = _current;
-    _conditionFalse = _identity;
-  }
-
   void tryCatchStatement_bodyBegin() {
     _stack.add(_current);
     // Tail of the stack: beforeBody
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
new file mode 100644
index 0000000..79d3217
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -0,0 +1,514 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
+
+/// The helper for performing flow analysis during resolution.
+///
+/// It contains related precomputed data, result, and non-trivial pieces of
+/// code that are independent from visiting AST during resolution, so can
+/// be extracted.
+class FlowAnalysisHelper {
+  static final _trueLiteral = astFactory.booleanLiteral(null, true);
+
+  /// The reused instance for creating new [FlowAnalysis] instances.
+  final NodeOperations<Expression> _nodeOperations;
+
+  /// The reused instance for creating new [FlowAnalysis] instances.
+  final _TypeSystemTypeOperations _typeOperations;
+
+  /// Precomputed sets of potentially assigned variables.
+  final AssignedVariables<Statement, VariableElement> assignedVariables;
+
+  /// The result for post-resolution stages of analysis.
+  final FlowAnalysisResult result = FlowAnalysisResult();
+
+  /// The current flow, when resolving a function body, or `null` otherwise.
+  FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
+
+  int _blockFunctionBodyLevel = 0;
+
+  factory FlowAnalysisHelper(TypeSystem typeSystem, AstNode node) {
+    var assignedVariables = AssignedVariables<Statement, VariableElement>();
+    node.accept(_AssignedVariablesVisitor(assignedVariables));
+
+    return FlowAnalysisHelper._(
+      _NodeOperations(),
+      _TypeSystemTypeOperations(typeSystem),
+      assignedVariables,
+    );
+  }
+
+  FlowAnalysisHelper._(
+    this._nodeOperations,
+    this._typeOperations,
+    this.assignedVariables,
+  );
+
+  LocalVariableTypeProvider get localVariableTypeProvider {
+    return _LocalVariableTypeProvider(this);
+  }
+
+  VariableElement assignmentExpression(AssignmentExpression node) {
+    if (flow == null) return null;
+
+    var left = node.leftHandSide;
+
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        return element;
+      }
+    }
+
+    return null;
+  }
+
+  void assignmentExpression_afterRight(
+      VariableElement localElement, Expression right) {
+    if (localElement == null) return;
+
+    flow.write(
+      localElement,
+      isNull: _isNull(right),
+      isNonNull: _isNonNull(right),
+    );
+  }
+
+  void binaryExpression_bangEq(
+    BinaryExpression node,
+    Expression left,
+    Expression right,
+  ) {
+    if (flow == null) return;
+
+    if (right is NullLiteral) {
+      if (left is SimpleIdentifier) {
+        var element = left.staticElement;
+        if (element is VariableElement) {
+          flow.conditionNotEqNull(node, element);
+        }
+      }
+    } else if (left is NullLiteral) {
+      if (right is SimpleIdentifier) {
+        var element = right.staticElement;
+        if (element is VariableElement) {
+          flow.conditionNotEqNull(node, element);
+        }
+      }
+    }
+  }
+
+  void binaryExpression_eqEq(
+    BinaryExpression node,
+    Expression left,
+    Expression right,
+  ) {
+    if (flow == null) return;
+
+    if (right is NullLiteral) {
+      if (left is SimpleIdentifier) {
+        var element = left.staticElement;
+        if (element is VariableElement) {
+          flow.conditionEqNull(node, element);
+        }
+      }
+    } else if (left is NullLiteral) {
+      if (right is SimpleIdentifier) {
+        var element = right.staticElement;
+        if (element is VariableElement) {
+          flow.conditionEqNull(node, element);
+        }
+      }
+    }
+  }
+
+  void blockFunctionBody_enter(BlockFunctionBody node) {
+    _blockFunctionBodyLevel++;
+
+    if (_blockFunctionBodyLevel > 1) {
+      assert(flow != null);
+      return;
+    }
+
+    flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
+      _nodeOperations,
+      _typeOperations,
+      _FunctionBodyAccess(node),
+    );
+
+    var parameters = _enclosingExecutableParameters(node);
+    if (parameters != null) {
+      for (var parameter in parameters.parameters) {
+        flow.add(parameter.declaredElement, assigned: true);
+      }
+    }
+  }
+
+  void blockFunctionBody_exit(BlockFunctionBody node) {
+    _blockFunctionBodyLevel--;
+
+    if (_blockFunctionBodyLevel > 0) {
+      return;
+    }
+
+    if (!flow.isReachable) {
+      result.functionBodiesThatDontComplete.add(node);
+    }
+
+    flow.verifyStackEmpty();
+    flow = null;
+  }
+
+  void breakStatement(BreakStatement node) {
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleBreak(target);
+  }
+
+  /// Mark the [node] as unreachable if it is not covered by another node that
+  /// is already known to be unreachable.
+  void checkUnreachableNode(AstNode node) {
+    if (flow == null) return;
+    if (flow.isReachable) return;
+
+    // Ignore the [node] if it is fully covered by the last unreachable.
+    if (result.unreachableNodes.isNotEmpty) {
+      var last = result.unreachableNodes.last;
+      if (node.offset >= last.offset && node.end <= last.end) return;
+    }
+
+    result.unreachableNodes.add(node);
+  }
+
+  void continueStatement(ContinueStatement node) {
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleContinue(target);
+  }
+
+  void forStatement_bodyBegin(ForStatement node, Expression condition) {
+    flow.forStatement_bodyBegin(node, condition ?? _trueLiteral);
+  }
+
+  void forStatement_conditionBegin(ForStatement node, Expression condition) {
+    if (condition != null) {
+      var assigned = assignedVariables[node];
+      flow.forStatement_conditionBegin(assigned);
+    } else {
+      flow.booleanLiteral(_trueLiteral, true);
+    }
+  }
+
+  void isExpression(IsExpression node) {
+    if (flow == null) return;
+
+    var expression = node.expression;
+    var typeAnnotation = node.type;
+
+    if (expression is SimpleIdentifier) {
+      var element = expression.staticElement;
+      if (element is VariableElement) {
+        flow.isExpression_end(
+          node,
+          element,
+          node.notOperator != null,
+          typeAnnotation.type,
+        );
+      }
+    }
+  }
+
+  bool isPotentiallyNonNullableLocalReadBeforeWrite(SimpleIdentifier node) {
+    if (flow == null) return false;
+
+    if (node.inDeclarationContext()) return false;
+    if (!node.inGetterContext()) return false;
+
+    var element = node.staticElement;
+    if (element is LocalVariableElement) {
+      if (element.isLate) return false;
+
+      var typeSystem = _typeOperations.typeSystem;
+      if (typeSystem.isPotentiallyNonNullable(element.type)) {
+        return !flow.isAssigned(element);
+      }
+    }
+
+    return false;
+  }
+
+  void simpleIdentifier(SimpleIdentifier node) {
+    if (flow == null) return;
+
+    var element = node.staticElement;
+    var isLocalVariable = element is LocalVariableElement;
+    if (isLocalVariable || element is ParameterElement) {
+      if (node.inGetterContext() && !node.inDeclarationContext()) {
+        if (flow.isNullable(element)) {
+          result.nullableNodes.add(node);
+        }
+
+        if (flow.isNonNullable(element)) {
+          result.nonNullableNodes.add(node);
+        }
+      }
+    }
+  }
+
+  void variableDeclarationStatement(VariableDeclarationStatement node) {
+    var variables = node.variables.variables;
+    for (var i = 0; i < variables.length; ++i) {
+      var variable = variables[i];
+      flow.add(variable.declaredElement,
+          assigned: variable.initializer != null);
+    }
+  }
+
+  FormalParameterList _enclosingExecutableParameters(FunctionBody node) {
+    var parent = node.parent;
+    if (parent is ConstructorDeclaration) {
+      return parent.parameters;
+    }
+    if (parent is FunctionExpression) {
+      return parent.parameters;
+    }
+    if (parent is MethodDeclaration) {
+      return parent.parameters;
+    }
+    return null;
+  }
+
+  /// Return the target of the `break` or `continue` statement with the
+  /// [element] label. The [element] might be `null` (when the statement does
+  /// not specify a label), so the default enclosing target is returned.
+  AstNode _getLabelTarget(AstNode node, LabelElement element) {
+    for (; node != null; node = node.parent) {
+      if (node is DoStatement ||
+          node is ForStatement ||
+          node is SwitchStatement ||
+          node is WhileStatement) {
+        if (element == null) {
+          return node;
+        }
+        var parent = node.parent;
+        if (parent is LabeledStatement) {
+          for (var nodeLabel in parent.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+      if (element != null && node is SwitchStatement) {
+        for (var member in node.members) {
+          for (var nodeLabel in member.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  static bool _isNonNull(Expression node) {
+    if (node is NullLiteral) return false;
+
+    return node is Literal;
+  }
+
+  static bool _isNull(Expression node) {
+    return node is NullLiteral;
+  }
+}
+
+/// The result of performing flow analysis on a unit.
+class FlowAnalysisResult {
+  static const _astKey = 'FlowAnalysisResult';
+
+  /// The list of identifiers, resolved to a local variable or a parameter,
+  /// where the variable is known to be nullable.
+  final List<SimpleIdentifier> nullableNodes = [];
+
+  /// The list of identifiers, resolved to a local variable or a parameter,
+  /// where the variable is known to be non-nullable.
+  final List<SimpleIdentifier> nonNullableNodes = [];
+
+  /// The list of nodes, [Expression]s or [Statement]s, that cannot be reached,
+  /// for example because a previous statement always exits.
+  final List<AstNode> unreachableNodes = [];
+
+  /// The list of [FunctionBody]s that don't complete, for example because
+  /// there is a `return` statement at the end of the function body block.
+  final List<FunctionBody> functionBodiesThatDontComplete = [];
+
+  void putIntoNode(AstNode node) {
+    node.setProperty(_astKey, this);
+  }
+
+  static FlowAnalysisResult getFromNode(AstNode node) {
+    return node.getProperty(_astKey);
+  }
+}
+
+/// The visitor that gathers local variables that are potentially assigned
+/// in corresponding statements, such as loops, `switch` and `try`.
+class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
+  final AssignedVariables assignedVariables;
+
+  _AssignedVariablesVisitor(this.assignedVariables);
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var left = node.leftHandSide;
+
+    super.visitAssignmentExpression(node);
+
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        assignedVariables.write(element);
+      }
+    }
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    assignedVariables.beginStatement();
+    super.visitDoStatement(node);
+    assignedVariables.endStatement(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    var forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForParts) {
+      if (forLoopParts is ForPartsWithExpression) {
+        forLoopParts.initialization?.accept(this);
+      } else if (forLoopParts is ForPartsWithDeclarations) {
+        forLoopParts.variables?.accept(this);
+      } else {
+        throw new StateError('Unrecognized for loop parts');
+      }
+
+      assignedVariables.beginStatement();
+      forLoopParts.condition?.accept(this);
+      node.body.accept(this);
+      forLoopParts.updaters?.accept(this);
+      assignedVariables.endStatement(node);
+    } else if (forLoopParts is ForEachParts) {
+      var iterable = forLoopParts.iterable;
+      var body = node.body;
+
+      iterable.accept(this);
+
+      assignedVariables.beginStatement();
+      body.accept(this);
+      assignedVariables.endStatement(node);
+    } else {
+      throw new StateError('Unrecognized for loop parts');
+    }
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    var expression = node.expression;
+    var members = node.members;
+
+    expression.accept(this);
+
+    assignedVariables.beginStatement();
+    members.accept(this);
+    assignedVariables.endStatement(node);
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    assignedVariables.beginStatement();
+    node.body.accept(this);
+    assignedVariables.endStatement(node.body);
+
+    node.catchClauses.accept(this);
+
+    var finallyBlock = node.finallyBlock;
+    if (finallyBlock != null) {
+      assignedVariables.beginStatement();
+      finallyBlock.accept(this);
+      assignedVariables.endStatement(finallyBlock);
+    }
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    assignedVariables.beginStatement();
+    super.visitWhileStatement(node);
+    assignedVariables.endStatement(node);
+  }
+}
+
+class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
+  final FunctionBody node;
+
+  _FunctionBodyAccess(this.node);
+
+  @override
+  bool isPotentiallyMutatedInClosure(VariableElement variable) {
+    return node.isPotentiallyMutatedInClosure(variable);
+  }
+
+  @override
+  bool isPotentiallyMutatedInScope(VariableElement variable) {
+    return node.isPotentiallyMutatedInScope(variable);
+  }
+}
+
+/// The flow analysis based implementation of [LocalVariableTypeProvider].
+class _LocalVariableTypeProvider implements LocalVariableTypeProvider {
+  final FlowAnalysisHelper _manager;
+
+  _LocalVariableTypeProvider(this._manager);
+
+  @override
+  DartType getType(SimpleIdentifier node) {
+    var variable = node.staticElement as VariableElement;
+    var promotedType = _manager.flow?.promotedType(variable);
+    return promotedType ?? variable.type;
+  }
+}
+
+class _NodeOperations implements NodeOperations<Expression> {
+  @override
+  Expression unwrapParenthesized(Expression node) {
+    return node.unParenthesized;
+  }
+}
+
+class _TypeSystemTypeOperations
+    implements TypeOperations<VariableElement, DartType> {
+  final TypeSystem typeSystem;
+
+  _TypeSystemTypeOperations(this.typeSystem);
+
+  @override
+  DartType elementType(VariableElement element) {
+    return element.type;
+  }
+
+  @override
+  bool isLocalVariable(VariableElement element) {
+    return element is LocalVariableElement;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return typeSystem.isSubtypeOf(leftType, rightType);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 184d379..3bb5ec4 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
 
 class MethodInvocationResolver {
   static final _nameCall = new Name(null, 'call');
@@ -35,8 +36,8 @@
   /// The URI of [_definingLibrary].
   final Uri _definingLibraryUri;
 
-  /// The object keeping track of which elements have had their types promoted.
-  final TypePromotionManager _promoteManager;
+  /// The object providing promoted or declared types of variables.
+  final LocalVariableTypeProvider _localVariableTypeProvider;
 
   /// The invocation being resolved.
   MethodInvocationImpl _invocation;
@@ -49,7 +50,7 @@
         _inheritance = _resolver.inheritance,
         _definingLibrary = _resolver.definingLibrary,
         _definingLibraryUri = _resolver.definingLibrary.source.uri,
-        _promoteManager = _resolver.promoteManager;
+        _localVariableTypeProvider = _resolver.localVariableTypeProvider;
 
   /// The scope used to resolve identifiers.
   Scope get nameScope => _resolver.nameScope;
@@ -400,7 +401,7 @@
         return _setResolution(node, calleeType);
       }
       if (element is VariableElement) {
-        var targetType = _promoteManager.getStaticType(element);
+        var targetType = _localVariableTypeProvider.getType(nameNode);
         return _setResolution(node, targetType);
       }
       // TODO(scheglov) This is a questionable distinction.
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index e2194c6..b7eb69e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -587,6 +587,9 @@
     for (ClassElement element in compilationUnit.enums) {
       define(element);
     }
+    for (ExtensionElement element in compilationUnit.extensions) {
+      define(element);
+    }
     for (FunctionElement element in compilationUnit.functions) {
       define(element);
     }
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
index 7b359dd..c742828 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
@@ -44,6 +44,6 @@
         identifier.length,
         CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
         [name],
-        contextMessages);
+        contextMessages ?? const []);
   }
 }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 791135a..a5590ab 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2437,6 +2437,24 @@
           "Factory bodies can't use 'async', 'async*', or 'sync*'.");
 
   /**
+   * It is an error if a potentially non-nullable local variable which has no
+   * initializer expression and is not marked `late` is used before it is
+   * definitely assigned.
+   *
+   * Parameters:
+   * 0: the name of the variable that is invalid
+   */
+  static const CompileTimeErrorCode
+      NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
+      const CompileTimeErrorCode(
+          'NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
+          "Non-nullable local variable '{0}' must be assigned before "
+              "it can be used.",
+          correction: "Try giving it an initializer expression, "
+              "or ensure that it is assigned on every execution path, "
+              "or mark it 'late'.");
+
+  /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i>
    * or if <i>m > n</i>.
    *
@@ -2453,6 +2471,18 @@
           correction: "Try adding the missing arguments.");
 
   /**
+   * It is an error if a static variable with potentially non-nullable type has
+   * no initializer expression.
+   *
+   * Parameters:
+   * 0: the name of the field that is invalid
+   */
+  static const CompileTimeErrorCode NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD =
+      const CompileTimeErrorCode('NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD',
+          "Non-nullable static field '{0}' must be initialized.",
+          correction: "Try adding an initializer expression.");
+
+  /**
    * It is an error if a top level variable <cut> with potentially non-nullable
    * type has no initializer expression <cut>.
    *
@@ -2467,25 +2497,6 @@
           correction: "Try adding an initializer expression.");
 
   /**
-   * It is an error if a potentially non-nullable local variable which has no
-   * initializer expression and is not marked `late` is used before it is
-   * definitely assigned.
-   *
-   * TODO(scheglov) Update the code and the message when implement definite
-   * assignment analysis.
-   *
-   * Parameters:
-   * 0: the name of the variable that is invalid
-   */
-  static const CompileTimeErrorCode
-      NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE =
-      const CompileTimeErrorCode(
-          'NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE',
-          "Non-nullable local variable '{0}' must be initialized.",
-          correction:
-              "Try giving it an initializer expression, or mark it 'late'.");
-
-  /**
    * No parameters.
    */
   // #### Description
@@ -2962,8 +2973,6 @@
    * 0: the name of the type used in the instance creation that should be
    *    limited by the bound as specified in the class declaration
    * 1: the name of the bounding type
-   *
-   * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
       const CompileTimeErrorCode(
@@ -3493,39 +3502,6 @@
           "The return type '{0}' isn't a '{1}', as defined by anonymous closure.");
 
   /**
-   * 12.11 Instance Creation: It is a static type warning if any of the type
-   * arguments to a constructor of a generic type <i>G</i> invoked by a new
-   * expression or a constant object expression are not subtypes of the bounds
-   * of the corresponding formal type parameters of <i>G</i>.
-   *
-   * 15.8 Parameterized Types: If <i>S</i> is the static type of a member
-   * <i>m</i> of <i>G</i>, then the static type of the member <i>m</i> of
-   * <i>G&lt;A<sub>1</sub>, &hellip;, A<sub>n</sub>&gt;</i> is <i>[A<sub>1</sub>,
-   * &hellip;, A<sub>n</sub>/T<sub>1</sub>, &hellip;, T<sub>n</sub>]S</i> where
-   * <i>T<sub>1</sub>, &hellip;, T<sub>n</sub></i> are the formal type
-   * parameters of <i>G</i>. Let <i>B<sub>i</sub></i> be the bounds of
-   * <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>. It is a static type warning if
-   * <i>A<sub>i</sub></i> is not a subtype of <i>[A<sub>1</sub>, &hellip;,
-   * A<sub>n</sub>/T<sub>1</sub>, &hellip;, T<sub>n</sub>]B<sub>i</sub>, 1 &lt;=
-   * i &lt;= n</i>.
-   *
-   * 7.6.2 Factories: It is a static type warning if any of the type arguments
-   * to <i>k'</i> are not subtypes of the bounds of the corresponding formal
-   * type parameters of type.
-   *
-   * Parameters:
-   * 0: the name of the type used in the instance creation that should be
-   *    limited by the bound as specified in the class declaration
-   * 1: the name of the bounding type
-   *
-   * See [TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
-   */
-  static const StaticTypeWarningCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
-      const StaticTypeWarningCode(
-          'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', "'{0}' doesn't extend '{1}'.",
-          correction: "Try using a type that is or is a subclass of '{1}'.");
-
-  /**
    * 10 Generics: It is a static type warning if a type parameter is a supertype
    * of its upper bound.
    *
@@ -3533,7 +3509,7 @@
    * 0: the name of the type parameter
    * 1: the name of the bounding type
    *
-   * See [TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
+   * See [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   static const StaticTypeWarningCode TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND =
       const StaticTypeWarningCode('TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND',
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 955d11e..e3454ce 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -21,6 +21,7 @@
     show
         LocatedMessage,
         Message,
+        MessageCode,
         messageConstConstructorWithBody,
         messageConstMethod,
         messageConstructorWithReturnType,
@@ -109,25 +110,29 @@
   bool parseFunctionBodies = true;
 
   /// `true` if non-nullable behavior is enabled.
-  ///
-  /// When setting this field, be sure to set `scanner.enableNonNullable`
-  /// to the same value.
-  bool enableNonNullable = false;
+  final bool enableNonNullable;
 
   /// `true` if spread-collections behavior is enabled
-  bool enableSpreadCollections = false;
+  final bool enableSpreadCollections;
 
   /// `true` if control-flow-collections behavior is enabled
-  bool enableControlFlowCollections = false;
+  final bool enableControlFlowCollections;
 
   /// `true` if triple-shift behavior is enabled
-  bool enableTripleShift = false;
+  final bool enableTripleShift;
 
-  FeatureSet _featureSet;
+  final FeatureSet _featureSet;
 
   AstBuilder(ErrorReporter errorReporter, this.fileUri, this.isFullAst,
+      this._featureSet,
       [Uri uri])
       : this.errorReporter = new FastaErrorReporter(errorReporter),
+        this.enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
+        this.enableSpreadCollections =
+            _featureSet.isEnabled(Feature.spread_collections),
+        this.enableControlFlowCollections =
+            _featureSet.isEnabled(Feature.control_flow_collections),
+        this.enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
         uri = uri ?? fileUri;
 
   NodeList<ClassMember> get currentDeclarationMembers {
@@ -203,7 +208,7 @@
 
     SimpleIdentifier name;
     if (nameToken != null) {
-      name = ast.simpleIdentifier(nameToken);
+      name = ast.simpleIdentifier(nameToken, isDeclaration: true);
     }
 
     extensionDeclaration = ast.extensionDeclaration(
@@ -449,21 +454,6 @@
     }
   }
 
-  /// Configures the parser appropriately for the given [featureSet].
-  ///
-  /// TODO(paulberry): stop exposing `enableNonNullable`,
-  /// `enableSpreadCollections`, `enableControlFlowCollections`, and
-  /// `enableTripleShift` so that callers are forced to use this API.  Note that
-  /// this will not be a breaking change, because this code is in `lib/src`.
-  void configureFeatures(FeatureSet featureSet) {
-    enableNonNullable = featureSet.isEnabled(Feature.non_nullable);
-    enableSpreadCollections = featureSet.isEnabled(Feature.spread_collections);
-    enableControlFlowCollections =
-        featureSet.isEnabled(Feature.control_flow_collections);
-    enableTripleShift = featureSet.isEnabled(Feature.triple_shift);
-    _featureSet = featureSet;
-  }
-
   @override
   void debugEvent(String name) {
     // printEvent('AstBuilder: $name');
@@ -573,6 +563,12 @@
     push(ast.awaitExpression(awaitKeyword, pop()));
   }
 
+  void endInvalidAwaitExpression(
+      Token awaitKeyword, Token endToken, MessageCode errorCode) {
+    debugEvent("InvalidAwaitExpression");
+    endAwaitExpression(awaitKeyword, endToken);
+  }
+
   @override
   void endBinaryExpression(Token operatorToken) {
     assert(operatorToken.isOperator ||
@@ -680,7 +676,7 @@
     Token beginToken = pop();
     checkEmpty(endToken.charOffset);
 
-    CompilationUnitImpl unit = ast.compilationUnit2(
+    CompilationUnitImpl unit = ast.compilationUnit(
         beginToken: beginToken,
         scriptTag: scriptTag,
         directives: directives,
@@ -1458,8 +1454,8 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     assert(getOrSet == null ||
         optional('get', getOrSet) ||
         optional('set', getOrSet));
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4b370a9..2603f21 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/variance.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -43,7 +44,7 @@
 class ErrorVerifier extends RecursiveAstVisitor<void> {
   /**
    * Properties on the object class which are safe to call on nullable types.
-   * 
+   *
    * Note that this must include tear-offs.
    *
    * TODO(mfairhurst): Calculate these fields rather than hard-code them.
@@ -293,6 +294,10 @@
   /// fixed.
   final bool disableConflictingGenericsCheck;
 
+  /// If running with [_isNonNullable], the result of the flow analysis of the
+  /// unit being verified by this visitor.
+  final FlowAnalysisResult flowAnalysisResult;
+
   /// The features enabled in the unit currently being checked for errors.
   FeatureSet _featureSet;
 
@@ -301,7 +306,7 @@
    */
   ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
       this._typeProvider, this._inheritanceManager, bool enableSuperMixins,
-      {this.disableConflictingGenericsCheck: false})
+      {this.disableConflictingGenericsCheck: false, this.flowAnalysisResult})
       : _errorReporter = errorReporter,
         _uninstantiatedBoundChecker =
             new _UninstantiatedBoundChecker(errorReporter) {
@@ -713,6 +718,7 @@
       }
     }
     try {
+      _checkForNotInitializedNonNullableStaticField(node);
       super.visitFieldDeclaration(node);
     } finally {
       _isInStaticVariableDeclaration = false;
@@ -1440,7 +1446,6 @@
   @override
   void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
     _checkForFinalNotInitialized(node.variables);
-    _checkForNotInitializedPotentiallyNonNullableLocalVariable(node.variables);
     super.visitVariableDeclarationStatement(node);
   }
 
@@ -3369,75 +3374,6 @@
     }
   }
 
-  void _checkForNotInitializedPotentiallyNonNullableLocalVariable(
-    VariableDeclarationList node,
-  ) {
-    // Const and final checked separately.
-    if (node.isConst || node.isFinal) {
-      return;
-    }
-
-    if (!_isNonNullable) {
-      return;
-    }
-
-    if (node.isLate) {
-      return;
-    }
-
-    if (node.type == null) {
-      return;
-    }
-    var type = node.type.type;
-
-    if (!_typeSystem.isPotentiallyNonNullable(type)) {
-      return;
-    }
-
-    for (var variable in node.variables) {
-      if (variable.initializer == null) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode
-              .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
-          variable.name,
-          [variable.name.name],
-        );
-      }
-    }
-  }
-
-  void _checkForNotInitializedNonNullableTopLevelVariable(
-    VariableDeclarationList node,
-  ) {
-    // Const and final checked separately.
-    if (node.isConst || node.isFinal) {
-      return;
-    }
-
-    if (!_isNonNullable) {
-      return;
-    }
-
-    if (node.type == null) {
-      return;
-    }
-    var type = node.type.type;
-
-    if (!_typeSystem.isPotentiallyNonNullable(type)) {
-      return;
-    }
-
-    for (var variable in node.variables) {
-      if (variable.initializer == null) {
-        _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
-          variable.name,
-          [variable.name.name],
-        );
-      }
-    }
-  }
-
   /**
    * If there are no constructors in the given [members], verify that all
    * final fields are initialized.  Cases in which there is at least one
@@ -4026,6 +3962,8 @@
 
   void _checkForListConstructor(
       InstanceCreationExpression node, InterfaceType type) {
+    if (!_isNonNullable) return;
+
     if (node.argumentList.arguments.length == 1 &&
         _isDartCoreList(type) &&
         _typeSystem.isPotentiallyNonNullable(type.typeArguments[0])) {
@@ -4741,6 +4679,62 @@
     }
   }
 
+  void _checkForNotInitializedNonNullableStaticField(FieldDeclaration node) {
+    if (!_isNonNullable) return;
+
+    if (!node.isStatic) return;
+
+    var fields = node.fields;
+
+    // Const and final checked separately.
+    if (fields.isConst || fields.isFinal) return;
+
+    if (fields.type == null) return;
+    var type = fields.type.type;
+
+    if (!_typeSystem.isPotentiallyNonNullable(type)) return;
+
+    for (var variable in fields.variables) {
+      if (variable.initializer == null) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD,
+          variable.name,
+          [variable.name.name],
+        );
+      }
+    }
+  }
+
+  void _checkForNotInitializedNonNullableTopLevelVariable(
+    VariableDeclarationList node,
+  ) {
+    if (!_isNonNullable) return;
+
+    // Const and final checked separately.
+    if (node.isConst || node.isFinal) {
+      return;
+    }
+
+    if (node.type == null) {
+      return;
+    }
+    var type = node.type.type;
+
+    if (!_typeSystem.isPotentiallyNonNullable(type)) {
+      return;
+    }
+
+    for (var variable in node.variables) {
+      if (variable.initializer == null) {
+        _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_TOP_LEVEL_VARIABLE,
+          variable.name,
+          [variable.name.name],
+        );
+      }
+    }
+  }
+
   /**
    * Check for illegal derefences of nullables, ie, "unchecked" usages of
    * nullable values. Note that *any* usage of a null value is an "unchecked"
@@ -5396,10 +5390,6 @@
   /**
    * Verify that the type arguments in the given [typeName] are all within
    * their bounds.
-   *
-   * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS],
-   * [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS],
-   * [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_BOUND].
    */
   void _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
     // prepare Type
@@ -5459,14 +5449,6 @@
           }
 
           if (!_typeSystem.isSubtypeOf(argType, boundType)) {
-            ErrorCode errorCode;
-            if (_isInConstInstanceCreation) {
-              errorCode =
-                  CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
-            } else {
-              errorCode =
-                  StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
-            }
             if (_shouldAllowSuperBoundedTypes(typeName)) {
               var replacedType =
                   (argType as TypeImpl).replaceTopAndBottom(_typeProvider);
@@ -5477,7 +5459,9 @@
               }
             }
             _errorReporter.reportTypeErrorForNode(
-                errorCode, argumentNode, [argType, boundType]);
+                CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+                argumentNode,
+                [argType, boundType]);
           }
         }
       }
@@ -5987,8 +5971,6 @@
   /**
    * Verify that the given [typeArguments] are all within their bounds, as
    * defined by the given [element].
-   *
-   * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   void _checkTypeArguments(InvocationExpression node) {
     NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments;
@@ -6033,7 +6015,7 @@
             fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
         if (!_typeSystem.isSubtypeOf(argType, bound)) {
           _errorReporter.reportTypeErrorForNode(
-              StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+              CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
               typeArgumentList[i],
               [argType, bound]);
         }
@@ -6059,6 +6041,8 @@
   }
 
   void _checkUseOfDefaultValuesInParameters(FormalParameterList node) {
+    if (!_isNonNullable) return;
+
     AstNode parent = node.parent;
     if (parent is FieldFormalParameter ||
         parent is FunctionTypeAlias ||
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index d494c4e..3248dd0 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
@@ -31,6 +30,7 @@
 import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
 import 'package:front_end/src/fasta/parser/type_info.dart' as fasta;
 import 'package:front_end/src/fasta/scanner.dart' as fasta;
+import 'package:meta/meta.dart';
 
 export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
 export 'package:analyzer/src/dart/error/syntactic_errors.dart';
@@ -199,17 +199,12 @@
 
   /// Initialize a newly created parser to parse tokens in the given [_source]
   /// and to report any errors that are found to the given [_errorListener].
-  ///
-  /// In a future major version release of the analyzer, the [featureSet]
-  /// argument will be required.
   factory Parser(Source source, AnalysisErrorListener errorListener,
-      {bool useFasta, FeatureSet featureSet}) {
+      {bool useFasta, @required FeatureSet featureSet}) {
+    featureSet ??= FeatureSet.fromEnableFlags([]);
     if (useFasta ?? Parser.useFasta) {
-      var parser = new _Parser2(source, errorListener, allowNativeClause: true);
-      if (featureSet != null) {
-        parser.configureFeatures(featureSet);
-      }
-      return parser;
+      return new _Parser2(source, errorListener, featureSet,
+          allowNativeClause: true);
     } else {
       return new Parser.withoutFasta(source, errorListener,
           featureSet: featureSet);
@@ -245,24 +240,6 @@
   @deprecated
   void set enableAssertInitializer(bool enable) {}
 
-  /// Enables or disables parsing of control flow collections.
-  @Deprecated('Pass a FeatureSet to the constructor instead')
-  void set enableControlFlowCollections(bool value) {
-    if (value) {
-      throw new UnimplementedError('control_flow_collections experiment'
-          ' not supported by analyzer parser');
-    }
-  }
-
-  /// Enables or disables non-nullable by default.
-  @Deprecated('Pass a FeatureSet to the constructor instead')
-  void set enableNonNullable(bool value) {
-    if (value) {
-      throw new UnimplementedError(
-          'non-nullable experiment not supported by analyzer parser');
-    }
-  }
-
   /// Return `true` if the parser should parse instance creation expressions
   /// that lack either the `new` or `const` keyword.
   bool get enableOptionalNewAndConst => _enableOptionalNewAndConst;
@@ -279,24 +256,6 @@
     // has been removed from dartfmt.
   }
 
-  /// Enables or disables parsing of spread collections.
-  @Deprecated('Pass a FeatureSet to the constructor instead')
-  void set enableSpreadCollections(bool value) {
-    if (value) {
-      throw new UnimplementedError(
-          'spread_collections experiment not supported by analyzer parser');
-    }
-  }
-
-  /// Enables or disables parsing of the triple shift operators.
-  @Deprecated('Pass a FeatureSet to the constructor instead')
-  void set enableTripleShift(bool value) {
-    if (value) {
-      throw new UnimplementedError('triple_shift experiment'
-          ' not supported by analyzer parser');
-    }
-  }
-
   /// Return `true` if the parser is to allow URI's in part-of directives.
   @deprecated
   bool get enableUriInPartOf => true;
@@ -363,12 +322,6 @@
     return buffer.toString();
   }
 
-  /// Configures the parser appropriately for the given [featureSet].
-  @Deprecated('Pass a FeatureSet to the constructor instead')
-  void configureFeatures(FeatureSet featureSet) {
-    _configureFeatures(featureSet);
-  }
-
   /// Return a synthetic identifier.
   SimpleIdentifier createSyntheticIdentifier({bool isDeclaration: false}) {
     Token syntheticToken;
@@ -1937,7 +1890,7 @@
         } on _TooDeepTreeError {
           _reportErrorForToken(ParserErrorCode.STACK_OVERFLOW, _currentToken);
           Token eof = new Token.eof(0);
-          return astFactory.compilationUnit2(
+          return astFactory.compilationUnit(
               beginToken: eof, endToken: eof, featureSet: _featureSet);
         }
         if (member != null) {
@@ -1987,7 +1940,7 @@
 //        }
       }
     }
-    return astFactory.compilationUnit2(
+    return astFactory.compilationUnit(
         beginToken: firstToken,
         scriptTag: scriptTag,
         directives: directives,
@@ -2443,7 +2396,7 @@
         while (!_matches(TokenType.EOF)) {
           _advance();
         }
-        return astFactory.compilationUnit2(
+        return astFactory.compilationUnit(
             beginToken: firstToken,
             scriptTag: scriptTag,
             directives: directives,
@@ -2451,7 +2404,7 @@
             featureSet: _featureSet);
       }
     }
-    return astFactory.compilationUnit2(
+    return astFactory.compilationUnit(
         beginToken: firstToken,
         scriptTag: scriptTag,
         directives: directives,
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index f7c72e0..5f560dd 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -24,15 +24,13 @@
   final AstBuilder astBuilder;
 
   ParserAdapter(this.currentToken, ErrorReporter errorReporter, Uri fileUri,
-      {bool allowNativeClause: false, FeatureSet featureSet})
+      FeatureSet featureSet,
+      {bool allowNativeClause: false})
       : fastaParser = new fasta.Parser(null),
-        astBuilder = new AstBuilder(errorReporter, fileUri, true) {
+        astBuilder = new AstBuilder(errorReporter, fileUri, true, featureSet) {
     fastaParser.listener = astBuilder;
     astBuilder.parser = fastaParser;
     astBuilder.allowNativeClause = allowNativeClause;
-    if (featureSet != null) {
-      astBuilder.configureFeatures(featureSet);
-    }
   }
 
   @override
@@ -41,25 +39,6 @@
   }
 
   @override
-  void set enableControlFlowCollections(bool value) {
-    if (IsExpired.control_flow_collections &&
-        value != IsEnabledByDefault.control_flow_collections) {
-      throw new StateError('control_flow_collections may only be set'
-          ' to ${IsEnabledByDefault.control_flow_collections}');
-    }
-    astBuilder.enableControlFlowCollections = value;
-  }
-
-  /// Enables or disables non-nullable by default.
-  void set enableNonNullable(bool value) {
-    if (IsExpired.non_nullable && value != IsEnabledByDefault.non_nullable) {
-      throw new StateError(
-          'non_nullable may only be set to ${IsEnabledByDefault.non_nullable}');
-    }
-    astBuilder.enableNonNullable = value;
-  }
-
-  @override
   bool get enableOptionalNewAndConst => false;
 
   @override
@@ -72,25 +51,6 @@
   }
 
   @override
-  void set enableSpreadCollections(bool value) {
-    if (IsExpired.spread_collections &&
-        value != IsEnabledByDefault.spread_collections) {
-      throw new StateError('spread_collections may only be set'
-          ' to ${IsEnabledByDefault.spread_collections}');
-    }
-    astBuilder.enableSpreadCollections = value;
-  }
-
-  @override
-  void set enableTripleShift(bool value) {
-    if (IsExpired.triple_shift && value != IsEnabledByDefault.triple_shift) {
-      throw new StateError('triple_shift may only be set'
-          ' to ${IsEnabledByDefault.triple_shift}');
-    }
-    astBuilder.enableTripleShift = value;
-  }
-
-  @override
   void set parseFunctionBodies(bool parseFunctionBodies) {
     astBuilder.parseFunctionBodies = parseFunctionBodies;
   }
@@ -111,11 +71,6 @@
   }
 
   @override
-  void configureFeatures(FeatureSet featureSet) {
-    astBuilder.configureFeatures(featureSet);
-  }
-
-  @override
   Expression parseAdditiveExpression() => parseExpression2();
 
   @override
@@ -423,16 +378,17 @@
   @override
   bool enableUriInPartOf = true;
 
-  factory _Parser2(Source source, AnalysisErrorListener errorListener,
+  factory _Parser2(
+      Source source, AnalysisErrorListener errorListener, FeatureSet featureSet,
       {bool allowNativeClause: false}) {
     var errorReporter = new ErrorReporter(errorListener, source);
-    return new _Parser2._(source, errorReporter, source.uri,
+    return new _Parser2._(source, errorReporter, source.uri, featureSet,
         allowNativeClause: allowNativeClause);
   }
 
   _Parser2._(this._source, ErrorReporter errorReporter, Uri fileUri,
-      {bool allowNativeClause: false})
-      : super(null, errorReporter, fileUri,
+      FeatureSet featureSet, {bool allowNativeClause: false})
+      : super(null, errorReporter, fileUri, featureSet,
             allowNativeClause: allowNativeClause);
 
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b5b6b72..26f2d52 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -26,6 +26,7 @@
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
 import 'package:analyzer/src/error/codes.dart';
@@ -35,7 +36,9 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/type_promotion_manager.dart';
 import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:meta/meta.dart';
@@ -3715,7 +3718,9 @@
   InferenceContext inferenceContext = null;
 
   /// The object keeping track of which elements have had their types promoted.
-  TypePromotionManager _promoteManager = new TypePromotionManager();
+  TypePromotionManager _promoteManager;
+
+  final FlowAnalysisHelper _flowAnalysis;
 
   /// A comment before a function should be resolved in the context of the
   /// function. But when we incrementally resolve a comment, we don't want to
@@ -3725,9 +3730,6 @@
   /// be built and the comment resolved.
   bool resolveOnlyCommentInFunctionBody = false;
 
-  /// Body of the function currently being analyzed, if any.
-  FunctionBody _currentFunctionBody;
-
   /// The type of the expression of the immediately enclosing [SwitchStatement],
   /// or `null` if not in a [SwitchStatement].
   DartType _enclosingSwitchStatementExpressionType;
@@ -3755,7 +3757,8 @@
       {FeatureSet featureSet,
       Scope nameScope,
       bool propagateTypes: true,
-      reportConstEvaluationErrors: true})
+      reportConstEvaluationErrors: true,
+      FlowAnalysisHelper flowAnalysisHelper})
       : this._(
             inheritance,
             definingLibrary,
@@ -3766,7 +3769,8 @@
                 definingLibrary.context.analysisOptions.contextFeatures,
             nameScope,
             propagateTypes,
-            reportConstEvaluationErrors);
+            reportConstEvaluationErrors,
+            flowAnalysisHelper);
 
   ResolverVisitor._(
       this.inheritance,
@@ -3777,16 +3781,18 @@
       FeatureSet featureSet,
       Scope nameScope,
       bool propagateTypes,
-      reportConstEvaluationErrors)
+      reportConstEvaluationErrors,
+      this._flowAnalysis)
       : _analysisOptions = definingLibrary.context.analysisOptions,
         _uiAsCodeEnabled =
             featureSet.isEnabled(Feature.control_flow_collections) ||
                 featureSet.isEnabled(Feature.spread_collections),
         super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
+    this.typeSystem = definingLibrary.context.typeSystem;
+    this._promoteManager = TypePromotionManager(typeSystem);
     this.elementResolver = new ElementResolver(this,
         reportConstEvaluationErrors: reportConstEvaluationErrors);
-    this.typeSystem = definingLibrary.context.typeSystem;
     bool strongModeHints = false;
     AnalysisOptions options = _analysisOptions;
     if (options is AnalysisOptionsImpl) {
@@ -3803,12 +3809,14 @@
   /// @return the element representing the function containing the current node
   ExecutableElement get enclosingFunction => _enclosingFunction;
 
-  /// Return the object keeping track of which elements have had their types
-  /// promoted.
-  ///
-  /// @return the object keeping track of which elements have had their types
-  ///         promoted
-  TypePromotionManager get promoteManager => _promoteManager;
+  /// Return the object providing promoted or declared types of variables.
+  LocalVariableTypeProvider get localVariableTypeProvider {
+    if (_flowAnalysis != null) {
+      return _flowAnalysis.localVariableTypeProvider;
+    } else {
+      return _promoteManager.localVariableTypeProvider;
+    }
+  }
 
   /// Return the static element associated with the given expression whose type
   /// can be overridden, or `null` if there is no element whose type can be
@@ -3831,24 +3839,6 @@
     return null;
   }
 
-  /// Return the static element associated with the given expression whose type
-  /// can be promoted, or `null` if there is no element whose type can be
-  /// promoted.
-  VariableElement getPromotionStaticElement(Expression expression) {
-    expression = expression?.unParenthesized;
-    if (expression is SimpleIdentifier) {
-      Element element = expression.staticElement;
-      if (element is VariableElement) {
-        ElementKind kind = element.kind;
-        if (kind == ElementKind.LOCAL_VARIABLE ||
-            kind == ElementKind.PARAMETER) {
-          return element;
-        }
-      }
-    }
-    return null;
-  }
-
   /// Given a downward inference type [fnType], and the declared
   /// [typeParameterList] for a function expression, determines if we can enable
   /// downward inference and if so, returns the function type to use for
@@ -3907,7 +3897,7 @@
 
   /// Set the enclosing function body when partial AST is resolved.
   void prepareCurrentFunctionBody(FunctionBody body) {
-    _currentFunctionBody = body;
+    _promoteManager.enterFunctionBody(body);
   }
 
   /// Set information about enclosing declarations.
@@ -4019,14 +4009,22 @@
 
   @override
   void visitAssignmentExpression(AssignmentExpression node) {
-    node.leftHandSide?.accept(this);
+    var left = node.leftHandSide;
+    var right = node.rightHandSide;
+
+    left?.accept(this);
+
+    var leftLocalVariable = _flowAnalysis?.assignmentExpression(node);
+
     TokenType operator = node.operator.type;
     if (operator == TokenType.EQ ||
         operator == TokenType.QUESTION_QUESTION_EQ) {
-      InferenceContext.setType(
-          node.rightHandSide, node.leftHandSide.staticType);
+      InferenceContext.setType(right, left.staticType);
     }
-    node.rightHandSide?.accept(this);
+
+    right?.accept(this);
+    _flowAnalysis?.assignmentExpression_afterRight(leftLocalVariable, right);
+
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
@@ -4043,66 +4041,92 @@
 
   @override
   void visitBinaryExpression(BinaryExpression node) {
-    TokenType operatorType = node.operator.type;
-    Expression leftOperand = node.leftOperand;
-    Expression rightOperand = node.rightOperand;
-    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
-      InferenceContext.setType(leftOperand, typeProvider.boolType);
-      InferenceContext.setType(rightOperand, typeProvider.boolType);
-      leftOperand?.accept(this);
-      if (rightOperand != null) {
-        _promoteManager.enterScope();
-        try {
-          // Type promotion.
-          _promoteTypes(leftOperand);
-          _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
-          _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
-          _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-              rightOperand);
-          // Visit right operand.
-          rightOperand.accept(this);
-        } finally {
-          _promoteManager.exitScope();
-        }
+    TokenType operator = node.operator.type;
+    Expression left = node.leftOperand;
+    Expression right = node.rightOperand;
+    var flow = _flowAnalysis?.flow;
+
+    if (operator == TokenType.AMPERSAND_AMPERSAND) {
+      InferenceContext.setType(left, typeProvider.boolType);
+      InferenceContext.setType(right, typeProvider.boolType);
+
+      // TODO(scheglov) Do we need these checks for null?
+      left?.accept(this);
+
+      if (_flowAnalysis != null) {
+        flow?.logicalAnd_rightBegin(node, left);
+        _flowAnalysis.checkUnreachableNode(right);
+        right.accept(this);
+        flow?.logicalAnd_end(node, right);
+      } else {
+        _promoteManager.visitBinaryExpression_and_rhs(
+          left,
+          right,
+          () {
+            right.accept(this);
+          },
+        );
       }
+
       node.accept(elementResolver);
-    } else if (operatorType == TokenType.BAR_BAR) {
-      InferenceContext.setType(leftOperand, typeProvider.boolType);
-      InferenceContext.setType(rightOperand, typeProvider.boolType);
-      leftOperand?.accept(this);
-      if (rightOperand != null) {
-        rightOperand.accept(this);
-      }
+    } else if (operator == TokenType.BAR_BAR) {
+      InferenceContext.setType(left, typeProvider.boolType);
+      InferenceContext.setType(right, typeProvider.boolType);
+
+      left?.accept(this);
+
+      flow?.logicalOr_rightBegin(node, left);
+      _flowAnalysis?.checkUnreachableNode(right);
+      right.accept(this);
+      flow?.logicalOr_end(node, right);
+
       node.accept(elementResolver);
+    } else if (operator == TokenType.BANG_EQ) {
+      left.accept(this);
+      right.accept(this);
+      node.accept(elementResolver);
+      _flowAnalysis?.binaryExpression_bangEq(node, left, right);
+    } else if (operator == TokenType.EQ_EQ) {
+      left.accept(this);
+      right.accept(this);
+      node.accept(elementResolver);
+      _flowAnalysis?.binaryExpression_eqEq(node, left, right);
     } else {
-      if (operatorType == TokenType.QUESTION_QUESTION) {
-        InferenceContext.setTypeFromNode(leftOperand, node);
+      if (operator == TokenType.QUESTION_QUESTION) {
+        InferenceContext.setTypeFromNode(left, node);
       }
-      leftOperand?.accept(this);
+      left?.accept(this);
 
       // Call ElementResolver.visitBinaryExpression to resolve the user-defined
       // operator method, if applicable.
       node.accept(elementResolver);
 
-      if (operatorType == TokenType.QUESTION_QUESTION) {
+      if (operator == TokenType.QUESTION_QUESTION) {
         // Set the right side, either from the context, or using the information
         // from the left side if it is more precise.
         DartType contextType = InferenceContext.getContext(node);
-        DartType leftType = leftOperand?.staticType;
+        DartType leftType = left?.staticType;
         if (contextType == null || contextType.isDynamic) {
           contextType = leftType;
         }
-        InferenceContext.setType(rightOperand, contextType);
+        InferenceContext.setType(right, contextType);
       } else {
         var invokeType = node.staticInvokeType;
         if (invokeType != null && invokeType.parameters.isNotEmpty) {
           // If this is a user-defined operator, set the right operand context
           // using the operator method's parameter type.
           var rightParam = invokeType.parameters[0];
-          InferenceContext.setType(rightOperand, rightParam.type);
+          InferenceContext.setType(right, rightParam.type);
         }
       }
-      rightOperand?.accept(this);
+
+      if (operator == TokenType.QUESTION_QUESTION) {
+        flow?.ifNullExpression_rightBegin();
+        right.accept(this);
+        flow?.ifNullExpression_end();
+      } else {
+        right?.accept(this);
+      }
     }
     node.accept(typeAnalyzer);
   }
@@ -4110,14 +4134,22 @@
   @override
   void visitBlockFunctionBody(BlockFunctionBody node) {
     try {
+      _flowAnalysis?.blockFunctionBody_enter(node);
       inferenceContext.pushReturnContext(node);
       super.visitBlockFunctionBody(node);
     } finally {
       inferenceContext.popReturnContext(node);
+      _flowAnalysis?.blockFunctionBody_exit(node);
     }
   }
 
   @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    _flowAnalysis?.flow?.booleanLiteral(node, node.value);
+    super.visitBooleanLiteral(node);
+  }
+
+  @override
   void visitBreakStatement(BreakStatement node) {
     //
     // We do not visit the label because it needs to be visited in the context
@@ -4125,6 +4157,7 @@
     //
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
+    _flowAnalysis?.breakStatement(node);
   }
 
   @override
@@ -4215,28 +4248,43 @@
   @override
   void visitConditionalExpression(ConditionalExpression node) {
     Expression condition = node.condition;
+    var flow = _flowAnalysis?.flow;
+
+    // TODO(scheglov) Do we need these checks for null?
     condition?.accept(this);
+
     Expression thenExpression = node.thenExpression;
-    if (thenExpression != null) {
-      _promoteManager.enterScope();
-      try {
-        // Type promotion.
-        _promoteTypes(condition);
-        _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
-        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-            thenExpression);
-        // Visit "then" expression.
-        InferenceContext.setTypeFromNode(thenExpression, node);
-        thenExpression.accept(this);
-      } finally {
-        _promoteManager.exitScope();
+    InferenceContext.setTypeFromNode(thenExpression, node);
+
+    if (_flowAnalysis != null) {
+      if (flow != null) {
+        flow.conditional_thenBegin(node, condition);
+        _flowAnalysis.checkUnreachableNode(thenExpression);
       }
+      thenExpression.accept(this);
+    } else {
+      _promoteManager.visitConditionalExpression_then(
+        condition,
+        thenExpression,
+        () {
+          thenExpression.accept(this);
+        },
+      );
     }
+
     Expression elseExpression = node.elseExpression;
-    if (elseExpression != null) {
-      InferenceContext.setTypeFromNode(elseExpression, node);
+    InferenceContext.setTypeFromNode(elseExpression, node);
+
+    if (flow != null) {
+      var isBool = thenExpression.staticType.isDartCoreBool;
+      flow.conditional_elseBegin(node, thenExpression, isBool);
+      _flowAnalysis.checkUnreachableNode(elseExpression);
+      elseExpression.accept(this);
+      flow.conditional_end(node, elseExpression, isBool);
+    } else {
       elseExpression.accept(this);
     }
+
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
@@ -4244,15 +4292,14 @@
   @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
-    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
-      _currentFunctionBody = node.body;
+      _promoteManager.enterFunctionBody(node.body);
       _enclosingFunction = node.declaredElement;
       FunctionType type = _enclosingFunction.type;
       InferenceContext.setType(node.body, type.returnType);
       super.visitConstructorDeclaration(node);
     } finally {
-      _currentFunctionBody = outerFunctionBody;
+      _promoteManager.exitFunctionBody();
       _enclosingFunction = outerFunction;
     }
     ConstructorElementImpl constructor = node.declaredElement;
@@ -4304,6 +4351,7 @@
     //
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
+    _flowAnalysis?.continueStatement(node);
   }
 
   @override
@@ -4327,9 +4375,24 @@
   }
 
   @override
-  void visitDoStatement(DoStatement node) {
+  void visitDoStatementInScope(DoStatement node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
+    var body = node.body;
+    var condition = node.condition;
+
     InferenceContext.setType(node.condition, typeProvider.boolType);
-    super.visitDoStatement(node);
+
+    _flowAnalysis?.flow?.doStatement_bodyBegin(
+      node,
+      _flowAnalysis?.assignedVariables[node],
+    );
+    visitStatementInScope(body);
+
+    _flowAnalysis?.flow?.doStatement_conditionBegin();
+    condition.accept(this);
+
+    _flowAnalysis?.flow?.doStatement_end(node, node.condition);
   }
 
   @override
@@ -4444,6 +4507,8 @@
 
   @override
   void visitForStatementInScope(ForStatement node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
     ForLoopParts forLoopParts = node.forLoopParts;
     if (forLoopParts is ForParts) {
       if (forLoopParts is ForPartsWithDeclarations) {
@@ -4451,10 +4516,22 @@
       } else if (forLoopParts is ForPartsWithExpression) {
         forLoopParts.initialization?.accept(this);
       }
-      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
-      forLoopParts.condition?.accept(this);
+
+      var condition = forLoopParts.condition;
+      InferenceContext.setType(condition, typeProvider.boolType);
+
+      _flowAnalysis?.forStatement_conditionBegin(node, condition);
+      if (condition != null) {
+        condition.accept(this);
+      }
+
+      _flowAnalysis?.forStatement_bodyBegin(node, condition);
       visitStatementInScope(node.body);
+
+      _flowAnalysis?.flow?.forStatement_updaterBegin();
       forLoopParts.updaters.accept(this);
+
+      _flowAnalysis?.flow?.forStatement_end();
     } else if (forLoopParts is ForEachParts) {
       Expression iterable = forLoopParts.iterable;
       DeclaredIdentifier loopVariable;
@@ -4493,10 +4570,18 @@
       //
       iterable?.accept(this);
       loopVariable?.accept(this);
+
+      _flowAnalysis?.flow?.forEachStatement_bodyBegin(
+        _flowAnalysis?.assignedVariables[node],
+      );
+
       Statement body = node.body;
       if (body != null) {
         visitStatementInScope(body);
       }
+
+      _flowAnalysis?.flow?.forEachStatement_end();
+
       node.accept(elementResolver);
       node.accept(typeAnalyzer);
     }
@@ -4505,16 +4590,15 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
-    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
       SimpleIdentifier functionName = node.name;
-      _currentFunctionBody = node.functionExpression.body;
+      _promoteManager.enterFunctionBody(node.functionExpression.body);
       _enclosingFunction = functionName.staticElement as ExecutableElement;
       InferenceContext.setType(
           node.functionExpression, _enclosingFunction.type);
       super.visitFunctionDeclaration(node);
     } finally {
-      _currentFunctionBody = outerFunctionBody;
+      _promoteManager.exitFunctionBody();
       _enclosingFunction = outerFunction;
     }
   }
@@ -4528,9 +4612,13 @@
   @override
   void visitFunctionExpression(FunctionExpression node) {
     ExecutableElement outerFunction = _enclosingFunction;
-    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
-      _currentFunctionBody = node.body;
+      if (_flowAnalysis != null) {
+        _flowAnalysis.flow?.functionExpression_begin();
+      } else {
+        _promoteManager.enterFunctionBody(node.body);
+      }
+
       _enclosingFunction = node.declaredElement;
       DartType functionType = InferenceContext.getContext(node);
       if (functionType is FunctionType) {
@@ -4544,7 +4632,12 @@
       }
       super.visitFunctionExpression(node);
     } finally {
-      _currentFunctionBody = outerFunctionBody;
+      if (_flowAnalysis != null) {
+        _flowAnalysis.flow?.functionExpression_end();
+      } else {
+        _promoteManager.exitFunctionBody();
+      }
+
       _enclosingFunction = outerFunction;
     }
   }
@@ -4592,22 +4685,16 @@
   void visitIfElement(IfElement node) {
     Expression condition = node.condition;
     InferenceContext.setType(condition, typeProvider.boolType);
+    // TODO(scheglov) Do we need these checks for null?
     condition?.accept(this);
     CollectionElement thenElement = node.thenElement;
-    if (thenElement != null) {
-      _promoteManager.enterScope();
-      try {
-        // Type promotion.
-        _promoteTypes(condition);
-        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
-        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-            thenElement);
-        // Visit "then".
+    _promoteManager.visitIfElement_thenElement(
+      condition,
+      thenElement,
+      () {
         thenElement.accept(this);
-      } finally {
-        _promoteManager.exitScope();
-      }
-    }
+      },
+    );
     node.elseElement?.accept(this);
 
     node.accept(elementResolver);
@@ -4616,28 +4703,35 @@
 
   @override
   void visitIfStatement(IfStatement node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
     Expression condition = node.condition;
+
     InferenceContext.setType(condition, typeProvider.boolType);
     condition?.accept(this);
+
     Statement thenStatement = node.thenStatement;
-    if (thenStatement != null) {
-      _promoteManager.enterScope();
-      try {
-        // Type promotion.
-        _promoteTypes(condition);
-        _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
-        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-            thenStatement);
-        // Visit "then".
-        visitStatementInScope(thenStatement);
-      } finally {
-        _promoteManager.exitScope();
-      }
+    if (_flowAnalysis != null) {
+      _flowAnalysis.flow.ifStatement_thenBegin(node, condition);
+      visitStatementInScope(thenStatement);
+    } else {
+      _promoteManager.visitIfStatement_thenStatement(
+        condition,
+        thenStatement,
+        () {
+          visitStatementInScope(thenStatement);
+        },
+      );
     }
+
     Statement elseStatement = node.elseStatement;
     if (elseStatement != null) {
+      _flowAnalysis?.flow?.ifStatement_elseBegin();
       visitStatementInScope(elseStatement);
     }
+
+    _flowAnalysis?.flow?.ifStatement_end(elseStatement != null);
+
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
@@ -4665,6 +4759,12 @@
   }
 
   @override
+  void visitIsExpression(IsExpression node) {
+    super.visitIsExpression(node);
+    _flowAnalysis?.isExpression(node);
+  }
+
+  @override
   void visitLabel(Label node) {}
 
   @override
@@ -4701,16 +4801,15 @@
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
-    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
-      _currentFunctionBody = node.body;
+      _promoteManager.enterFunctionBody(node.body);
       _enclosingFunction = node.declaredElement;
       DartType returnType =
           _computeReturnOrYieldType(_enclosingFunction.type?.returnType);
       InferenceContext.setType(node.body, returnType);
       super.visitMethodDeclaration(node);
     } finally {
-      _currentFunctionBody = outerFunctionBody;
+      _promoteManager.exitFunctionBody();
       _enclosingFunction = outerFunction;
     }
   }
@@ -4767,6 +4866,7 @@
 
   @override
   void visitNode(AstNode node) {
+    _flowAnalysis?.checkUnreachableNode(node);
     node.visitChildren(this);
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -4790,6 +4890,16 @@
   }
 
   @override
+  void visitPrefixExpression(PrefixExpression node) {
+    super.visitPrefixExpression(node);
+
+    var operator = node.operator.type;
+    if (operator == TokenType.BANG) {
+      _flowAnalysis?.flow?.logicalNot_end(node, node.operand);
+    }
+  }
+
+  @override
   void visitPropertyAccess(PropertyAccess node) {
     //
     // We visit the target, but do not visit the property name because it needs
@@ -4816,6 +4926,12 @@
   }
 
   @override
+  void visitRethrowExpression(RethrowExpression node) {
+    super.visitRethrowExpression(node);
+    _flowAnalysis?.flow?.handleExit();
+  }
+
+  @override
   void visitReturnStatement(ReturnStatement node) {
     Expression e = node.expression;
     InferenceContext.setType(e, inferenceContext.returnContext);
@@ -4829,6 +4945,7 @@
       }
       inferenceContext.addReturnOrYieldType(type);
     }
+    _flowAnalysis?.flow?.handleExit();
   }
 
   @override
@@ -4889,6 +5006,23 @@
   void visitShowCombinator(ShowCombinator node) {}
 
   @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    _flowAnalysis?.simpleIdentifier(node);
+
+    if (_flowAnalysis != null &&
+        _flowAnalysis.isPotentiallyNonNullableLocalReadBeforeWrite(node)) {
+      errorReporter.reportErrorForNode(
+        CompileTimeErrorCode
+            .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+        node,
+        [node.name],
+      );
+    }
+
+    super.visitSimpleIdentifier(node);
+  }
+
+  @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     //
     // We visit the argument list, but do not visit the optional identifier
@@ -4904,6 +5038,8 @@
 
   @override
   void visitSwitchCase(SwitchCase node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
     InferenceContext.setType(
         node.expression, _enclosingSwitchStatementExpressionType);
     super.visitSwitchCase(node);
@@ -4911,17 +5047,97 @@
 
   @override
   void visitSwitchStatementInScope(SwitchStatement node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
     var previousExpressionType = _enclosingSwitchStatementExpressionType;
     try {
-      node.expression?.accept(this);
-      _enclosingSwitchStatementExpressionType = node.expression.staticType;
-      node.members.accept(this);
+      var expression = node.expression;
+      expression.accept(this);
+      _enclosingSwitchStatementExpressionType = expression.staticType;
+
+      if (_flowAnalysis != null) {
+        var flow = _flowAnalysis.flow;
+        var assignedInCases = _flowAnalysis.assignedVariables[node];
+
+        flow.switchStatement_expressionEnd(node);
+
+        var hasDefault = false;
+        var members = node.members;
+        for (var member in members) {
+          flow.switchStatement_beginCase(
+            member.labels.isNotEmpty
+                ? assignedInCases
+                : _flowAnalysis.assignedVariables.emptySet,
+          );
+          member.accept(this);
+
+          // Implicit `break` at the end of `default`.
+          if (member is SwitchDefault) {
+            hasDefault = true;
+            flow.handleBreak(node);
+          }
+        }
+
+        flow.switchStatement_end(node, hasDefault);
+      } else {
+        node.members.accept(this);
+      }
     } finally {
       _enclosingSwitchStatementExpressionType = previousExpressionType;
     }
   }
 
   @override
+  void visitThrowExpression(ThrowExpression node) {
+    super.visitThrowExpression(node);
+    _flowAnalysis?.flow?.handleExit();
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    if (_flowAnalysis == null) {
+      return super.visitTryStatement(node);
+    }
+
+    _flowAnalysis.checkUnreachableNode(node);
+    var flow = _flowAnalysis.flow;
+
+    var body = node.body;
+    var catchClauses = node.catchClauses;
+    var finallyBlock = node.finallyBlock;
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_bodyBegin();
+    }
+
+    flow.tryCatchStatement_bodyBegin();
+    body.accept(this);
+    flow.tryCatchStatement_bodyEnd(
+      _flowAnalysis.assignedVariables[body],
+    );
+
+    var catchLength = catchClauses.length;
+    for (var i = 0; i < catchLength; ++i) {
+      var catchClause = catchClauses[i];
+      flow.tryCatchStatement_catchBegin();
+      catchClause.accept(this);
+      flow.tryCatchStatement_catchEnd();
+    }
+
+    flow.tryCatchStatement_end();
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_finallyBegin(
+        _flowAnalysis.assignedVariables[body],
+      );
+      finallyBlock.accept(this);
+      flow.tryFinallyStatement_end(
+        _flowAnalysis.assignedVariables[finallyBlock],
+      );
+    }
+  }
+
+  @override
   void visitTypeName(TypeName node) {}
 
   @override
@@ -4954,18 +5170,34 @@
   }
 
   @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    _flowAnalysis?.variableDeclarationStatement(node);
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
   void visitWhileStatement(WhileStatement node) {
+    _flowAnalysis?.checkUnreachableNode(node);
+
     // Note: since we don't call the base class, we have to maintain
     // _implicitLabelScope ourselves.
     ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
     try {
       _implicitLabelScope = _implicitLabelScope.nest(node);
+
       Expression condition = node.condition;
       InferenceContext.setType(condition, typeProvider.boolType);
+
+      _flowAnalysis?.flow?.whileStatement_conditionBegin(
+        _flowAnalysis?.assignedVariables[node],
+      );
       condition?.accept(this);
+
       Statement body = node.body;
       if (body != null) {
+        _flowAnalysis?.flow?.whileStatement_bodyBegin(node, condition);
         visitStatementInScope(body);
+        _flowAnalysis?.flow?.whileStatement_end();
       }
     } finally {
       _implicitLabelScope = outerImplicitScope;
@@ -5021,36 +5253,6 @@
     }
   }
 
-  /// Checks each promoted variable in the current scope for compliance with the
-  /// following specification statement:
-  ///
-  /// If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i>
-  /// then the variable <i>v</i> is not potentially mutated anywhere in the
-  /// scope of <i>v</i>.
-  void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-      AstNode target) {
-    for (Element element in _promoteManager.promotedElements) {
-      if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
-        if (_isVariableAccessedInClosure(element, target)) {
-          _promoteManager.setType(element, null);
-        }
-      }
-    }
-  }
-
-  /// Checks each promoted variable in the current scope for compliance with the
-  /// following specification statement:
-  ///
-  /// <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a
-  /// closure.
-  void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) {
-    for (Element element in _promoteManager.promotedElements) {
-      if (_isVariablePotentiallyMutatedIn(element, target)) {
-        _promoteManager.setType(element, null);
-      }
-    }
-  }
-
   /// Given the declared return type of a function, compute the type of the
   /// values which should be returned or yielded as appropriate.  If a type
   /// cannot be computed from the declared return type, return null.
@@ -5333,86 +5535,6 @@
     }
   }
 
-  /// Return `true` if the given variable is accessed within a closure in the
-  /// given [AstNode] and also mutated somewhere in variable scope. This
-  /// information is only available for local variables (including parameters).
-  ///
-  /// @param variable the variable to check
-  /// @param target the [AstNode] to check within
-  /// @return `true` if this variable is potentially mutated somewhere in the
-  ///         given ASTNode
-  bool _isVariableAccessedInClosure(Element variable, AstNode target) {
-    _ResolverVisitor_isVariableAccessedInClosure visitor =
-        new _ResolverVisitor_isVariableAccessedInClosure(variable);
-    target.accept(visitor);
-    return visitor.result;
-  }
-
-  /// Return `true` if the given variable is potentially mutated somewhere in
-  /// the given [AstNode]. This information is only available for local
-  /// variables (including parameters).
-  ///
-  /// @param variable the variable to check
-  /// @param target the [AstNode] to check within
-  /// @return `true` if this variable is potentially mutated somewhere in the
-  ///         given ASTNode
-  bool _isVariablePotentiallyMutatedIn(Element variable, AstNode target) {
-    _ResolverVisitor_isVariablePotentiallyMutatedIn visitor =
-        new _ResolverVisitor_isVariablePotentiallyMutatedIn(variable);
-    target.accept(visitor);
-    return visitor.result;
-  }
-
-  /// If it is appropriate to do so, promotes the current type of the static
-  /// element associated with the given expression with the given type.
-  /// Generally speaking, it is appropriate if the given type is more specific
-  /// than the current type.
-  ///
-  /// @param expression the expression used to access the static element whose
-  ///        types might be promoted
-  /// @param potentialType the potential type of the elements
-  void _promote(Expression expression, DartType potentialType) {
-    VariableElement element = getPromotionStaticElement(expression);
-    if (element != null) {
-      // may be mutated somewhere in closure
-      if (_currentFunctionBody.isPotentiallyMutatedInClosure(element)) {
-        return;
-      }
-      // prepare current variable type
-      DartType type = _promoteManager.getType(element) ??
-          expression.staticType ??
-          DynamicTypeImpl.instance;
-
-      potentialType ??= DynamicTypeImpl.instance;
-
-      // Check if we can promote to potentialType from type.
-      DartType promoteType = typeSystem.tryPromoteToType(potentialType, type);
-      if (promoteType != null) {
-        // Do promote type of variable.
-        _promoteManager.setType(element, promoteType);
-      }
-    }
-  }
-
-  /// Promotes type information using given condition.
-  void _promoteTypes(Expression condition) {
-    if (condition is BinaryExpression) {
-      if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-        Expression left = condition.leftOperand;
-        Expression right = condition.rightOperand;
-        _promoteTypes(left);
-        _promoteTypes(right);
-        _clearTypePromotionsIfPotentiallyMutatedIn(right);
-      }
-    } else if (condition is IsExpression) {
-      if (condition.notOperator == null) {
-        _promote(condition.expression, condition.type.type);
-      }
-    } else if (condition is ParenthesizedExpression) {
-      _promoteTypes(condition.expression);
-    }
-  }
-
   void _pushCollectionTypesDown(CollectionElement element,
       {DartType elementType,
       @required DartType iterableType,
@@ -5809,13 +5931,17 @@
     ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
     try {
       _implicitLabelScope = _implicitLabelScope.nest(node);
-      visitStatementInScope(node.body);
-      node.condition?.accept(this);
+      visitDoStatementInScope(node);
     } finally {
       _implicitLabelScope = outerImplicitScope;
     }
   }
 
+  void visitDoStatementInScope(DoStatement node) {
+    visitStatementInScope(node.body);
+    node.condition?.accept(this);
+  }
+
   @override
   void visitEnumDeclaration(EnumDeclaration node) {
     ClassElement classElement = node.declaredElement;
@@ -7110,93 +7236,6 @@
   }
 }
 
-/// Instances of the class `TypePromotionManager` manage the ability to promote
-/// types of local variables and formal parameters from their declared types
-/// based on control flow.
-class TypePromotionManager {
-  /// The current promotion scope, or `null` if no scope has been entered.
-  TypePromotionManager_TypePromoteScope currentScope;
-
-  /// Returns the elements with promoted types.
-  Iterable<Element> get promotedElements => currentScope.promotedElements;
-
-  /// Enter a new promotions scope.
-  void enterScope() {
-    currentScope = new TypePromotionManager_TypePromoteScope(currentScope);
-  }
-
-  /// Exit the current promotion scope.
-  void exitScope() {
-    if (currentScope == null) {
-      throw new StateError("No scope to exit");
-    }
-    currentScope = currentScope._outerScope;
-  }
-
-  /// Return the static type of the given [variable] - declared or promoted.
-  DartType getStaticType(VariableElement variable) =>
-      getType(variable) ?? variable.type;
-
-  /// Return the promoted type of the given [element], or `null` if the type of
-  /// the element has not been promoted.
-  DartType getType(Element element) => currentScope?.getType(element);
-
-  /// Set the promoted type of the given element to the given type.
-  ///
-  /// @param element the element whose type might have been promoted
-  /// @param type the promoted type of the given element
-  void setType(Element element, DartType type) {
-    if (currentScope == null) {
-      throw new StateError("Cannot promote without a scope");
-    }
-    currentScope.setType(element, type);
-  }
-}
-
-/// Instances of the class `TypePromoteScope` represent a scope in which the
-/// types of elements can be promoted.
-class TypePromotionManager_TypePromoteScope {
-  /// The outer scope in which types might be promoter.
-  final TypePromotionManager_TypePromoteScope _outerScope;
-
-  /// A table mapping elements to the promoted type of that element.
-  Map<Element, DartType> _promotedTypes = new HashMap<Element, DartType>();
-
-  /// Initialize a newly created scope to be an empty child of the given scope.
-  ///
-  /// @param outerScope the outer scope in which types might be promoted
-  TypePromotionManager_TypePromoteScope(this._outerScope);
-
-  /// Returns the elements with promoted types.
-  Iterable<Element> get promotedElements => _promotedTypes.keys.toSet();
-
-  /// Return the promoted type of the given element, or `null` if the type of
-  /// the element has not been promoted.
-  ///
-  /// @param element the element whose type might have been promoted
-  /// @return the promoted type of the given element
-  DartType getType(Element element) {
-    DartType type = _promotedTypes[element];
-    if (type == null && element is PropertyAccessorElement) {
-      type = _promotedTypes[element.variable];
-    }
-    if (type != null) {
-      return type;
-    } else if (_outerScope != null) {
-      return _outerScope.getType(element);
-    }
-    return null;
-  }
-
-  /// Set the promoted type of the given element to the given type.
-  ///
-  /// @param element the element whose type might have been promoted
-  /// @param type the promoted type of the given element
-  void setType(Element element, DartType type) {
-    _promotedTypes[element] = type;
-  }
-}
-
 /// The interface `TypeProvider` defines the behavior of objects that provide
 /// access to types defined by the language.
 abstract class TypeProvider {
@@ -9076,56 +9115,3 @@
 
 /// The kind of literal to which an unknown literal should be resolved.
 enum _LiteralResolutionKind { ambiguous, map, set }
-
-class _ResolverVisitor_isVariableAccessedInClosure
-    extends RecursiveAstVisitor<void> {
-  final Element variable;
-
-  bool result = false;
-
-  bool _inClosure = false;
-
-  _ResolverVisitor_isVariableAccessedInClosure(this.variable);
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    bool inClosure = this._inClosure;
-    try {
-      this._inClosure = true;
-      super.visitFunctionExpression(node);
-    } finally {
-      this._inClosure = inClosure;
-    }
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (result) {
-      return;
-    }
-    if (_inClosure && identical(node.staticElement, variable)) {
-      result = true;
-    }
-  }
-}
-
-class _ResolverVisitor_isVariablePotentiallyMutatedIn
-    extends RecursiveAstVisitor<void> {
-  final Element variable;
-
-  bool result = false;
-
-  _ResolverVisitor_isVariablePotentiallyMutatedIn(this.variable);
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (result) {
-      return;
-    }
-    if (identical(node.staticElement, variable)) {
-      if (node.inSetterContext()) {
-        result = true;
-      }
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 86ef733..b1ec9e0 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -7,16 +7,10 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
@@ -227,72 +221,3 @@
     return null;
   }
 }
-
-/**
- * An object used to read and parse the libraries file
- * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for information
- * about the libraries in an SDK. The library information is represented as a
- * Dart file containing a single top-level variable whose value is a const map.
- * The keys of the map are the names of libraries defined in the SDK and the
- * values in the map are info objects defining the library. For example, a
- * subset of a typical SDK might have a libraries file that looks like the
- * following:
- *
- *     final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
- *       // Used by VM applications
- *       "builtin" : const LibraryInfo(
- *         "builtin/builtin_runtime.dart",
- *         category: "Server",
- *         platforms: VM_PLATFORM),
- *
- *       "compiler" : const LibraryInfo(
- *         "compiler/compiler.dart",
- *         category: "Tools",
- *         platforms: 0),
- *     };
- */
-@deprecated
-class SdkLibrariesReader {
-  /**
-   * A flag indicating whether the dart2js path should be used when it is
-   * available.
-   */
-  final bool _useDart2jsPaths;
-
-  /**
-   * Initialize a newly created library reader to use the dart2js path if
-   * [_useDart2jsPaths] is `true`.
-   */
-  SdkLibrariesReader(this._useDart2jsPaths);
-
-  /**
-   * Return the library map read from the given [file], given that the content
-   * of the file is already known to be [libraryFileContents].
-   */
-  LibraryMap readFromFile(JavaFile file, String libraryFileContents) =>
-      readFromSource(new FileBasedSource(file), libraryFileContents);
-
-  /**
-   * Return the library map read from the given [source], given that the content
-   * of the file is already known to be [libraryFileContents].
-   */
-  LibraryMap readFromSource(Source source, String libraryFileContents) {
-    BooleanErrorListener errorListener = new BooleanErrorListener();
-    // TODO(paulberry): initialize the feature set appropriately based on the
-    // version of the SDK we are reading, and enable flags.
-    var featureSet = FeatureSet.fromEnableFlags([]);
-    Scanner scanner = new Scanner(
-        source, new CharSequenceReader(libraryFileContents), errorListener)
-      ..configureFeatures(featureSet);
-    Parser parser = new Parser(source, errorListener, featureSet: featureSet);
-    CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
-    SdkLibrariesReader_LibraryBuilder libraryBuilder =
-        new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths);
-    // If any syntactic errors were found then don't try to visit the AST
-    // structure.
-    if (!errorListener.errorReported) {
-      unit.accept(libraryBuilder);
-    }
-    return libraryBuilder.librariesMap;
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 1ce52ef..efa1dc9 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -2,8 +2,6 @@
 // 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 'dart:collection';
-
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -21,6 +19,7 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
 import 'package:analyzer/src/task/strong/checker.dart'
     show getExpressionType, getReadType;
 import 'package:meta/meta.dart';
@@ -72,9 +71,9 @@
   InterfaceType thisType;
 
   /**
-   * The object keeping track of which elements have had their types promoted.
+   * The object providing promoted or declared types of variables.
    */
-  TypePromotionManager _promoteManager;
+  LocalVariableTypeProvider _localVariableTypeProvider;
 
   /**
    * Initialize a newly created static type analyzer to analyze types for the
@@ -86,7 +85,7 @@
     _typeProvider = _resolver.typeProvider;
     _typeSystem = _resolver.typeSystem;
     _dynamicType = _typeProvider.dynamicType;
-    _promoteManager = _resolver.promoteManager;
+    _localVariableTypeProvider = _resolver.localVariableTypeProvider;
     AnalysisOptionsImpl analysisOptions =
         _resolver.definingLibrary.context.analysisOptions;
     _strictInference = analysisOptions.strictInference;
@@ -1042,8 +1041,7 @@
     } else if (element is TypeParameterElement) {
       staticType = _nonNullable(_typeProvider.typeType);
     } else if (element is VariableElement) {
-      VariableElement variable = element;
-      staticType = _promoteManager.getStaticType(variable);
+      staticType = _localVariableTypeProvider.getType(node);
     } else if (element is PrefixElement) {
       var parent = node.parent;
       if (parent is PrefixedIdentifier && parent.prefix == node ||
@@ -1296,9 +1294,6 @@
       }
     } else if (element is ExecutableElement) {
       return _computeInvokeReturnType(element.type, isNullableInvoke: false);
-    } else if (element is VariableElement) {
-      DartType variableType = _promoteManager.getStaticType(element);
-      return _computeInvokeReturnType(variableType, isNullableInvoke: false);
     }
     return _dynamicType;
   }
@@ -1320,48 +1315,6 @@
     return returnType.type;
   }
 
-  DartType _findIteratedType(DartType type, DartType targetType) {
-    // TODO(vsm): Use leafp's matchType here?
-    // Set by _find if match is found
-    DartType result;
-    // Elements we've already visited on a given inheritance path.
-    HashSet<ClassElement> visitedClasses;
-
-    type = type.resolveToBound(_typeProvider.objectType);
-
-    bool _find(InterfaceType type) {
-      ClassElement element = type.element;
-      if (type == _typeProvider.objectType || element == null) {
-        return false;
-      }
-      if (element == targetType.element) {
-        List<DartType> typeArguments = type.typeArguments;
-        assert(typeArguments.length == 1);
-        result = typeArguments[0];
-        return true;
-      }
-      if (visitedClasses == null) {
-        visitedClasses = new HashSet<ClassElement>();
-      }
-      // Already visited this class along this path
-      if (!visitedClasses.add(element)) {
-        return false;
-      }
-      try {
-        return _find(type.superclass) ||
-            type.interfaces.any(_find) ||
-            type.mixins.any(_find);
-      } finally {
-        visitedClasses.remove(element);
-      }
-    }
-
-    if (type is InterfaceType) {
-      _find(type);
-    }
-    return result;
-  }
-
   /**
    * If the given element name can be mapped to the name of a class defined within the given
    * library, return the type specified by the argument.
@@ -1573,14 +1526,22 @@
       }
       if (iterable != null) {
         LocalVariableElementImpl element = loopVariable.declaredElement;
-        DartType exprType = iterable.staticType;
-        DartType targetType = (awaitKeyword == null)
-            ? _typeProvider.iterableType
-            : _typeProvider.streamType;
-        DartType iteratedType = _findIteratedType(exprType, targetType);
+
+        DartType iterableType = iterable.staticType;
+        iterableType = iterableType.resolveToBound(_typeProvider.objectType);
+
+        ClassElement iteratedElement = (awaitKeyword == null)
+            ? _typeProvider.iterableType.element
+            : _typeProvider.streamType.element;
+
+        InterfaceType iteratedType = iterableType is InterfaceTypeImpl
+            ? iterableType.asInstanceOf(iteratedElement)
+            : null;
+
         if (element != null && iteratedType != null) {
-          element.type = iteratedType;
-          loopVariable.identifier.staticType = iteratedType;
+          DartType elementType = iteratedType.typeArguments.single;
+          element.type = elementType;
+          loopVariable.identifier.staticType = elementType;
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 9237339..a84c48b 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -277,7 +277,7 @@
           String scriptTag,
           List<Directive> directives,
           List<CompilationUnitMember> declarations) =>
-      astFactory.compilationUnit2(
+      astFactory.compilationUnit(
           beginToken: TokenFactory.tokenFromType(TokenType.EOF),
           scriptTag:
               scriptTag == null ? null : AstTestFactory.scriptTag(scriptTag),
@@ -293,7 +293,7 @@
           List<Directive> directives,
           List<CompilationUnitMember> declarations,
           FeatureSet featureSet}) =>
-      astFactory.compilationUnit2(
+      astFactory.compilationUnit(
           beginToken: TokenFactory.tokenFromType(TokenType.EOF),
           scriptTag:
               scriptTag == null ? null : AstTestFactory.scriptTag(scriptTag),
@@ -505,6 +505,15 @@
           rightBracket:
               TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
 
+  static ExtensionOverride extensionOverride(
+          {@required Identifier extensionName,
+          TypeArgumentList typeArguments,
+          @required ArgumentList argumentList}) =>
+      astFactory.extensionOverride(
+          extensionName: extensionName,
+          typeArguments: typeArguments,
+          argumentList: argumentList);
+
   static FieldDeclaration fieldDeclaration(bool isStatic, Keyword keyword,
           TypeAnnotation type, List<VariableDeclaration> variables) =>
       astFactory.fieldDeclaration2(
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 8ea7304..b408d5f 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -121,11 +121,6 @@
   InterfaceType _mapObjectObjectType;
 
   /**
-   * The type representing the built-in type 'Never'.
-   */
-  InterfaceType _neverType;
-
-  /**
    * An shared object representing the value 'null'.
    */
   DartObjectImpl _nullObject;
@@ -446,13 +441,8 @@
   }
 
   @override
-  InterfaceType get neverType {
-    if (_neverType == null) {
-      ClassElementImpl neverElement =
-          ElementFactory.classElement('Never', objectType);
-      _neverType = neverElement.type;
-    }
-    return _neverType;
+  DartType get neverType {
+    return BottomTypeImpl.instance;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/type_promotion_manager.dart b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
new file mode 100644
index 0000000..14f1835
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/type_promotion_manager.dart
@@ -0,0 +1,395 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/variable_type_provider.dart';
+
+/// Instances of the class `TypePromotionManager` manage the ability to promote
+/// types of local variables and formal parameters from their declared types
+/// based on control flow.
+class TypePromotionManager {
+  final TypeSystem _typeSystem;
+
+  /// The current promotion scope, or `null` if no scope has been entered.
+  _TypePromoteScope _currentScope;
+
+  final List<FunctionBody> _functionBodyStack = [];
+
+  /// Body of the function currently being analyzed, if any.
+  FunctionBody _currentFunctionBody;
+
+  TypePromotionManager(this._typeSystem);
+
+  LocalVariableTypeProvider get localVariableTypeProvider {
+    return _LegacyLocalVariableTypeProvider(this);
+  }
+
+  /// Returns the elements with promoted types.
+  Iterable<Element> get _promotedElements {
+    return _currentScope.promotedElements;
+  }
+
+  void enterFunctionBody(FunctionBody body) {
+    _functionBodyStack.add(_currentFunctionBody);
+    _currentFunctionBody = body;
+  }
+
+  void exitFunctionBody() {
+    _currentFunctionBody = _functionBodyStack.removeLast();
+  }
+
+  void visitBinaryExpression_and_rhs(
+      Expression leftOperand, Expression rightOperand, void f()) {
+    if (rightOperand != null) {
+      _enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(leftOperand);
+        _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
+        _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
+        _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+            rightOperand);
+        // Visit right operand.
+        f();
+      } finally {
+        _exitScope();
+      }
+    }
+  }
+
+  void visitConditionalExpression_then(
+      Expression condition, Expression thenExpression, void f()) {
+    if (thenExpression != null) {
+      _enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
+        _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+          thenExpression,
+        );
+        // Visit "then" expression.
+        f();
+      } finally {
+        _exitScope();
+      }
+    }
+  }
+
+  void visitIfElement_thenElement(
+      Expression condition, CollectionElement thenElement, void f()) {
+    if (thenElement != null) {
+      _enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
+        _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+            thenElement);
+        // Visit "then".
+        f();
+      } finally {
+        _exitScope();
+      }
+    }
+  }
+
+  void visitIfStatement_thenStatement(
+      Expression condition, Statement thenStatement, void f()) {
+    if (thenStatement != null) {
+      _enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
+        _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+            thenStatement);
+        // Visit "then".
+        f();
+      } finally {
+        _exitScope();
+      }
+    }
+  }
+
+  /// Checks each promoted variable in the current scope for compliance with the
+  /// following specification statement:
+  ///
+  /// If the variable <i>v</i> is accessed by a closure in <i>s<sub>1</sub></i>
+  /// then the variable <i>v</i> is not potentially mutated anywhere in the
+  /// scope of <i>v</i>.
+  void _clearTypePromotionsIfAccessedInClosureAndPotentiallyMutated(
+      AstNode target) {
+    for (Element element in _promotedElements) {
+      if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
+        if (_isVariableAccessedInClosure(element, target)) {
+          _setType(element, null);
+        }
+      }
+    }
+  }
+
+  /// Checks each promoted variable in the current scope for compliance with the
+  /// following specification statement:
+  ///
+  /// <i>v</i> is not potentially mutated in <i>s<sub>1</sub></i> or within a
+  /// closure.
+  void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) {
+    for (Element element in _promotedElements) {
+      if (_isVariablePotentiallyMutatedIn(element, target)) {
+        _setType(element, null);
+      }
+    }
+  }
+
+  /// Enter a new promotions scope.
+  void _enterScope() {
+    _currentScope = new _TypePromoteScope(_currentScope);
+  }
+
+  /// Exit the current promotion scope.
+  void _exitScope() {
+    if (_currentScope == null) {
+      throw new StateError("No scope to exit");
+    }
+    _currentScope = _currentScope._outerScope;
+  }
+
+  /// Return the promoted type of the given [element], or `null` if the type of
+  /// the element has not been promoted.
+  DartType _getPromotedType(Element element) {
+    return _currentScope?.getType(element);
+  }
+
+  /// Return the static element associated with the given expression whose type
+  /// can be promoted, or `null` if there is no element whose type can be
+  /// promoted.
+  VariableElement _getPromotionStaticElement(Expression expression) {
+    expression = expression?.unParenthesized;
+    if (expression is SimpleIdentifier) {
+      Element element = expression.staticElement;
+      if (element is VariableElement) {
+        ElementKind kind = element.kind;
+        if (kind == ElementKind.LOCAL_VARIABLE ||
+            kind == ElementKind.PARAMETER) {
+          return element;
+        }
+      }
+    }
+    return null;
+  }
+
+  /// Given that the [node] is a reference to a [VariableElement], return the
+  /// static type of the variable at this node - declared or promoted.
+  DartType _getType(SimpleIdentifier node) {
+    var variable = node.staticElement as VariableElement;
+    return _getPromotedType(variable) ?? variable.type;
+  }
+
+  /// Return `true` if the given variable is accessed within a closure in the
+  /// given [AstNode] and also mutated somewhere in variable scope. This
+  /// information is only available for local variables (including parameters).
+  ///
+  /// @param variable the variable to check
+  /// @param target the [AstNode] to check within
+  /// @return `true` if this variable is potentially mutated somewhere in the
+  ///         given ASTNode
+  bool _isVariableAccessedInClosure(Element variable, AstNode target) {
+    _ResolverVisitor_isVariableAccessedInClosure visitor =
+        new _ResolverVisitor_isVariableAccessedInClosure(variable);
+    target.accept(visitor);
+    return visitor.result;
+  }
+
+  /// Return `true` if the given variable is potentially mutated somewhere in
+  /// the given [AstNode]. This information is only available for local
+  /// variables (including parameters).
+  ///
+  /// @param variable the variable to check
+  /// @param target the [AstNode] to check within
+  /// @return `true` if this variable is potentially mutated somewhere in the
+  ///         given ASTNode
+  bool _isVariablePotentiallyMutatedIn(Element variable, AstNode target) {
+    _ResolverVisitor_isVariablePotentiallyMutatedIn visitor =
+        new _ResolverVisitor_isVariablePotentiallyMutatedIn(variable);
+    target.accept(visitor);
+    return visitor.result;
+  }
+
+  /// If it is appropriate to do so, promotes the current type of the static
+  /// element associated with the given expression with the given type.
+  /// Generally speaking, it is appropriate if the given type is more specific
+  /// than the current type.
+  ///
+  /// @param expression the expression used to access the static element whose
+  ///        types might be promoted
+  /// @param potentialType the potential type of the elements
+  void _promote(Expression expression, DartType potentialType) {
+    VariableElement element = _getPromotionStaticElement(expression);
+    if (element != null) {
+      // may be mutated somewhere in closure
+      if (_currentFunctionBody.isPotentiallyMutatedInClosure(element)) {
+        return;
+      }
+      // prepare current variable type
+      DartType type = _getPromotedType(element) ??
+          expression.staticType ??
+          DynamicTypeImpl.instance;
+
+      potentialType ??= DynamicTypeImpl.instance;
+
+      // Check if we can promote to potentialType from type.
+      DartType promoteType = _typeSystem.tryPromoteToType(potentialType, type);
+      if (promoteType != null) {
+        // Do promote type of variable.
+        _setType(element, promoteType);
+      }
+    }
+  }
+
+  /// Promotes type information using given condition.
+  void _promoteTypes(Expression condition) {
+    if (condition is BinaryExpression) {
+      if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        Expression left = condition.leftOperand;
+        Expression right = condition.rightOperand;
+        _promoteTypes(left);
+        _promoteTypes(right);
+        _clearTypePromotionsIfPotentiallyMutatedIn(right);
+      }
+    } else if (condition is IsExpression) {
+      if (condition.notOperator == null) {
+        _promote(condition.expression, condition.type.type);
+      }
+    } else if (condition is ParenthesizedExpression) {
+      _promoteTypes(condition.expression);
+    }
+  }
+
+  /// Set the promoted type of the given element to the given type.
+  ///
+  /// @param element the element whose type might have been promoted
+  /// @param type the promoted type of the given element
+  void _setType(Element element, DartType type) {
+    if (_currentScope == null) {
+      throw new StateError("Cannot promote without a scope");
+    }
+    _currentScope.setType(element, type);
+  }
+}
+
+/// The legacy, pre-NNBD implementation of [LocalVariableTypeProvider].
+class _LegacyLocalVariableTypeProvider implements LocalVariableTypeProvider {
+  final TypePromotionManager _manager;
+
+  _LegacyLocalVariableTypeProvider(this._manager);
+
+  @override
+  DartType getType(SimpleIdentifier node) {
+    return _manager._getType(node);
+  }
+}
+
+class _ResolverVisitor_isVariableAccessedInClosure
+    extends RecursiveAstVisitor<void> {
+  final Element variable;
+
+  bool result = false;
+
+  bool _inClosure = false;
+
+  _ResolverVisitor_isVariableAccessedInClosure(this.variable);
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    bool inClosure = this._inClosure;
+    try {
+      this._inClosure = true;
+      super.visitFunctionExpression(node);
+    } finally {
+      this._inClosure = inClosure;
+    }
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (result) {
+      return;
+    }
+    if (_inClosure && identical(node.staticElement, variable)) {
+      result = true;
+    }
+  }
+}
+
+class _ResolverVisitor_isVariablePotentiallyMutatedIn
+    extends RecursiveAstVisitor<void> {
+  final Element variable;
+
+  bool result = false;
+
+  _ResolverVisitor_isVariablePotentiallyMutatedIn(this.variable);
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (result) {
+      return;
+    }
+    if (identical(node.staticElement, variable)) {
+      if (node.inSetterContext()) {
+        result = true;
+      }
+    }
+  }
+}
+
+/// Instances of the class `TypePromoteScope` represent a scope in which the
+/// types of elements can be promoted.
+class _TypePromoteScope {
+  /// The outer scope in which types might be promoter.
+  final _TypePromoteScope _outerScope;
+
+  /// A table mapping elements to the promoted type of that element.
+  Map<Element, DartType> _promotedTypes = {};
+
+  /// Initialize a newly created scope to be an empty child of the given scope.
+  ///
+  /// @param outerScope the outer scope in which types might be promoted
+  _TypePromoteScope(this._outerScope);
+
+  /// Returns the elements with promoted types.
+  Iterable<Element> get promotedElements => _promotedTypes.keys.toSet();
+
+  /// Return the promoted type of the given element, or `null` if the type of
+  /// the element has not been promoted.
+  ///
+  /// @param element the element whose type might have been promoted
+  /// @return the promoted type of the given element
+  DartType getType(Element element) {
+    DartType type = _promotedTypes[element];
+    if (type == null && element is PropertyAccessorElement) {
+      type = _promotedTypes[element.variable];
+    }
+    if (type != null) {
+      return type;
+    } else if (_outerScope != null) {
+      return _outerScope.getType(element);
+    }
+    return null;
+  }
+
+  /// Set the promoted type of the given element to the given type.
+  ///
+  /// @param element the element whose type might have been promoted
+  /// @param type the promoted type of the given element
+  void setType(Element element, DartType type) {
+    _promotedTypes[element] = type;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 53d06e1..523beb8 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -65,11 +65,17 @@
 }
 
 /// Is [t] the top of the legacy type hierarch.
-bool _isLegacyTop(DartType t, {@required bool orTrueTop}) =>
-// TODO(mfairhurst): handle FutureOr<LegacyTop> cases, with tests.
-    (t.isObject &&
-        (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) ||
-    (orTrueTop ? _isTop(t) : false);
+bool _isLegacyTop(DartType t, {@required bool orTrueTop}) {
+  if (t.isDartAsyncFutureOr) {
+    return _isLegacyTop((t as InterfaceType).typeArguments[0],
+        orTrueTop: orTrueTop);
+  }
+  if (t.isObject &&
+      (t as TypeImpl).nullabilitySuffix == NullabilitySuffix.none) {
+    return true;
+  }
+  return orTrueTop ? _isTop(t) : false;
+}
 
 bool _isTop(DartType t) {
   if (t.isDartAsyncFutureOr) {
@@ -103,10 +109,6 @@
 
   Dart2TypeSystem(this.typeProvider, {this.implicitCasts: true});
 
-  @deprecated
-  @override
-  bool get isStrong => true;
-
   /// Returns true iff the type [t] accepts function types, and requires an
   /// implicit coercion if interface types with a `call` method are passed in.
   ///
@@ -631,6 +633,7 @@
     }
 
     // Legacy top case. Must be done now to find Object* <: Object.
+    // TODO: handle false positives like FutureOr<Object?>* and T* extends int?.
     if (t1.nullabilitySuffix == NullabilitySuffix.star &&
         _isLegacyTop(t2, orTrueTop: false)) {
       return true;
@@ -1923,12 +1926,6 @@
 // TODO(brianwilkerson) Rename this class to TypeSystemImpl.
 abstract class TypeSystem implements public.TypeSystem {
   /**
-   * Whether the type system is strong or not.
-   */
-  @deprecated
-  bool get isStrong;
-
-  /**
    * The provider of types for the system
    */
   TypeProvider get typeProvider;
@@ -2105,11 +2102,11 @@
   bool isNonNullable(DartType type) {
     if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
       return false;
-    } else if (type.isDartAsyncFutureOr) {
-      isNonNullable((type as InterfaceType).typeArguments[0]);
     } else if ((type as TypeImpl).nullabilitySuffix ==
         NullabilitySuffix.question) {
       return false;
+    } else if (type.isDartAsyncFutureOr) {
+      return isNonNullable((type as InterfaceType).typeArguments[0]);
     } else if (type is TypeParameterType) {
       return isNonNullable(type.bound);
     }
@@ -2120,10 +2117,13 @@
   bool isNullable(DartType type) {
     if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
       return true;
+    } else if ((type as TypeImpl).nullabilitySuffix ==
+        NullabilitySuffix.question) {
+      return true;
     } else if (type.isDartAsyncFutureOr) {
-      isNullable((type as InterfaceType).typeArguments[0]);
+      return isNullable((type as InterfaceType).typeArguments[0]);
     }
-    return (type as TypeImpl).nullabilitySuffix != NullabilitySuffix.none;
+    return false;
   }
 
   /// Check that [f1] is a subtype of [f2] for a member override.
@@ -2342,8 +2342,30 @@
    *   Return a function type with those types.
    */
   DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
-    // TODO(rnystrom): Right now, this assumes f and g do not have any type
-    // parameters. Revisit that in the presence of generic methods.
+    var fTypeFormals = f.typeFormals;
+    var gTypeFormals = g.typeFormals;
+
+    // If F and G differ in their number of type parameters, then the
+    // least upper bound of F and G is Function.
+    if (fTypeFormals.length != gTypeFormals.length) {
+      return typeProvider.functionType;
+    }
+
+    // If F and G differ in bounds of their of type parameters, then the
+    // least upper bound of F and G is Function.
+    var freshTypeFormalTypes =
+        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
+    if (freshTypeFormalTypes == null) {
+      return typeProvider.functionType;
+    }
+
+    var typeFormals = freshTypeFormalTypes
+        .map<TypeParameterElement>((t) => t.element)
+        .toList();
+
+    f = f.instantiate(freshTypeFormalTypes);
+    g = g.instantiate(freshTypeFormalTypes);
+
     List<DartType> fRequired = f.normalParameterTypes;
     List<DartType> gRequired = g.normalParameterTypes;
 
@@ -2394,7 +2416,14 @@
 
     // Calculate the LUB of the return type.
     DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
-    return new FunctionElementImpl.synthetic(parameters, returnType).type;
+
+    if (AnalysisDriver.useSummary2) {
+      return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
+    }
+
+    var element = FunctionElementImpl.synthetic(parameters, returnType);
+    element.typeParameters = typeFormals;
+    return element.type;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/variable_type_provider.dart b/pkg/analyzer/lib/src/generated/variable_type_provider.dart
new file mode 100644
index 0000000..376d102
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/variable_type_provider.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+
+/// Provider of types for local variables and formal parameters.
+abstract class LocalVariableTypeProvider {
+  /// Given that the [node] is a reference to a local variable, or a parameter,
+  /// return the type of the variable at the node - declared or promoted.
+  DartType getType(SimpleIdentifier node);
+}
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 79fff64..7e0df3b 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -1082,11 +1082,6 @@
     _forForStatement.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
-  @Deprecated('Replaced by addForStatement')
-  void addForStatement2(LintRule linter, AstVisitor visitor) {
-    addForStatement(linter, visitor);
-  }
-
   void addFunctionDeclaration(LintRule linter, AstVisitor visitor) {
     _forFunctionDeclaration
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 5c6d947..93b3719 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -887,6 +887,7 @@
 class AnalysisDriverUnitErrorBuilder extends Object
     with _AnalysisDriverUnitErrorMixin
     implements idl.AnalysisDriverUnitError {
+  List<DiagnosticMessageBuilder> _contextMessages;
   String _correction;
   int _length;
   String _message;
@@ -894,6 +895,15 @@
   String _uniqueName;
 
   @override
+  List<DiagnosticMessageBuilder> get contextMessages =>
+      _contextMessages ??= <DiagnosticMessageBuilder>[];
+
+  /// The context messages associated with the error.
+  set contextMessages(List<DiagnosticMessageBuilder> value) {
+    this._contextMessages = value;
+  }
+
+  @override
   String get correction => _correction ??= '';
 
   /// The optional correction hint for the error.
@@ -936,19 +946,23 @@
   }
 
   AnalysisDriverUnitErrorBuilder(
-      {String correction,
+      {List<DiagnosticMessageBuilder> contextMessages,
+      String correction,
       int length,
       String message,
       int offset,
       String uniqueName})
-      : _correction = correction,
+      : _contextMessages = contextMessages,
+        _correction = correction,
         _length = length,
         _message = message,
         _offset = offset,
         _uniqueName = uniqueName;
 
   /// Flush [informative] data recursively.
-  void flushInformative() {}
+  void flushInformative() {
+    _contextMessages?.forEach((b) => b.flushInformative());
+  }
 
   /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
@@ -957,12 +971,25 @@
     signature.addString(this._uniqueName ?? '');
     signature.addString(this._message ?? '');
     signature.addString(this._correction ?? '');
+    if (this._contextMessages == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._contextMessages.length);
+      for (var x in this._contextMessages) {
+        x?.collectApiSignature(signature);
+      }
+    }
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_contextMessages;
     fb.Offset offset_correction;
     fb.Offset offset_message;
     fb.Offset offset_uniqueName;
+    if (!(_contextMessages == null || _contextMessages.isEmpty)) {
+      offset_contextMessages = fbBuilder
+          .writeList(_contextMessages.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (_correction != null) {
       offset_correction = fbBuilder.writeString(_correction);
     }
@@ -973,6 +1000,9 @@
       offset_uniqueName = fbBuilder.writeString(_uniqueName);
     }
     fbBuilder.startTable();
+    if (offset_contextMessages != null) {
+      fbBuilder.addOffset(5, offset_contextMessages);
+    }
     if (offset_correction != null) {
       fbBuilder.addOffset(4, offset_correction);
     }
@@ -1009,6 +1039,7 @@
 
   _AnalysisDriverUnitErrorImpl(this._bc, this._bcOffset);
 
+  List<idl.DiagnosticMessage> _contextMessages;
   String _correction;
   int _length;
   String _message;
@@ -1016,6 +1047,14 @@
   String _uniqueName;
 
   @override
+  List<idl.DiagnosticMessage> get contextMessages {
+    _contextMessages ??= const fb.ListReader<idl.DiagnosticMessage>(
+            const _DiagnosticMessageReader())
+        .vTableGet(_bc, _bcOffset, 5, const <idl.DiagnosticMessage>[]);
+    return _contextMessages;
+  }
+
+  @override
   String get correction {
     _correction ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
     return _correction;
@@ -1051,6 +1090,9 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (contextMessages.isNotEmpty)
+      _result["contextMessages"] =
+          contextMessages.map((_value) => _value.toJson()).toList();
     if (correction != '') _result["correction"] = correction;
     if (length != 0) _result["length"] = length;
     if (message != '') _result["message"] = message;
@@ -1061,6 +1103,7 @@
 
   @override
   Map<String, Object> toMap() => {
+        "contextMessages": contextMessages,
         "correction": correction,
         "length": length,
         "message": message,
@@ -3526,6 +3569,162 @@
   String toString() => convert.json.encode(toJson());
 }
 
+class DiagnosticMessageBuilder extends Object
+    with _DiagnosticMessageMixin
+    implements idl.DiagnosticMessage {
+  String _filePath;
+  int _length;
+  String _message;
+  int _offset;
+
+  @override
+  String get filePath => _filePath ??= '';
+
+  /// The absolute and normalized path of the file associated with this message.
+  set filePath(String value) {
+    this._filePath = value;
+  }
+
+  @override
+  int get length => _length ??= 0;
+
+  /// The length of the source range associated with this message.
+  set length(int value) {
+    assert(value == null || value >= 0);
+    this._length = value;
+  }
+
+  @override
+  String get message => _message ??= '';
+
+  /// The text of the message.
+  set message(String value) {
+    this._message = value;
+  }
+
+  @override
+  int get offset => _offset ??= 0;
+
+  /// The zero-based offset from the start of the file to the beginning of the
+  /// source range associated with this message.
+  set offset(int value) {
+    assert(value == null || value >= 0);
+    this._offset = value;
+  }
+
+  DiagnosticMessageBuilder(
+      {String filePath, int length, String message, int offset})
+      : _filePath = filePath,
+        _length = length,
+        _message = message,
+        _offset = offset;
+
+  /// Flush [informative] data recursively.
+  void flushInformative() {}
+
+  /// Accumulate non-[informative] data into [signature].
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._filePath ?? '');
+    signature.addInt(this._length ?? 0);
+    signature.addString(this._message ?? '');
+    signature.addInt(this._offset ?? 0);
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_filePath;
+    fb.Offset offset_message;
+    if (_filePath != null) {
+      offset_filePath = fbBuilder.writeString(_filePath);
+    }
+    if (_message != null) {
+      offset_message = fbBuilder.writeString(_message);
+    }
+    fbBuilder.startTable();
+    if (offset_filePath != null) {
+      fbBuilder.addOffset(0, offset_filePath);
+    }
+    if (_length != null && _length != 0) {
+      fbBuilder.addUint32(1, _length);
+    }
+    if (offset_message != null) {
+      fbBuilder.addOffset(2, offset_message);
+    }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addUint32(3, _offset);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _DiagnosticMessageReader extends fb.TableReader<_DiagnosticMessageImpl> {
+  const _DiagnosticMessageReader();
+
+  @override
+  _DiagnosticMessageImpl createObject(fb.BufferContext bc, int offset) =>
+      new _DiagnosticMessageImpl(bc, offset);
+}
+
+class _DiagnosticMessageImpl extends Object
+    with _DiagnosticMessageMixin
+    implements idl.DiagnosticMessage {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _DiagnosticMessageImpl(this._bc, this._bcOffset);
+
+  String _filePath;
+  int _length;
+  String _message;
+  int _offset;
+
+  @override
+  String get filePath {
+    _filePath ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+    return _filePath;
+  }
+
+  @override
+  int get length {
+    _length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
+    return _length;
+  }
+
+  @override
+  String get message {
+    _message ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, '');
+    return _message;
+  }
+
+  @override
+  int get offset {
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
+    return _offset;
+  }
+}
+
+abstract class _DiagnosticMessageMixin implements idl.DiagnosticMessage {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (filePath != '') _result["filePath"] = filePath;
+    if (length != 0) _result["length"] = length;
+    if (message != '') _result["message"] = message;
+    if (offset != 0) _result["offset"] = offset;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "filePath": filePath,
+        "length": length,
+        "message": message,
+        "offset": offset,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
 class DirectiveInfoBuilder extends Object
     with _DirectiveInfoMixin
     implements idl.DirectiveInfo {
@@ -22257,6 +22456,331 @@
   String toString() => convert.json.encode(toJson());
 }
 
+class UnlinkedExtensionBuilder extends Object
+    with _UnlinkedExtensionMixin
+    implements idl.UnlinkedExtension {
+  List<UnlinkedExprBuilder> _annotations;
+  CodeRangeBuilder _codeRange;
+  UnlinkedDocumentationCommentBuilder _documentationComment;
+  List<UnlinkedExecutableBuilder> _executables;
+  EntityRefBuilder _extendedType;
+  String _name;
+  int _nameOffset;
+  List<UnlinkedTypeParamBuilder> _typeParameters;
+
+  @override
+  List<UnlinkedExprBuilder> get annotations =>
+      _annotations ??= <UnlinkedExprBuilder>[];
+
+  /// Annotations for this extension.
+  set annotations(List<UnlinkedExprBuilder> value) {
+    this._annotations = value;
+  }
+
+  @override
+  CodeRangeBuilder get codeRange => _codeRange;
+
+  /// Code range of the extension.
+  set codeRange(CodeRangeBuilder value) {
+    this._codeRange = value;
+  }
+
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment =>
+      _documentationComment;
+
+  /// Documentation comment for the extension, or `null` if there is no
+  /// documentation comment.
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+    this._documentationComment = value;
+  }
+
+  @override
+  List<UnlinkedExecutableBuilder> get executables =>
+      _executables ??= <UnlinkedExecutableBuilder>[];
+
+  /// Executable objects (methods, getters, and setters) contained in the
+  /// extension.
+  set executables(List<UnlinkedExecutableBuilder> value) {
+    this._executables = value;
+  }
+
+  @override
+  EntityRefBuilder get extendedType => _extendedType;
+
+  /// The type being extended.
+  set extendedType(EntityRefBuilder value) {
+    this._extendedType = value;
+  }
+
+  @override
+  String get name => _name ??= '';
+
+  /// Name of the extension, or an empty string if there is no name.
+  set name(String value) {
+    this._name = value;
+  }
+
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
+  /// Offset of the extension name relative to the beginning of the file, or
+  /// zero if there is no name.
+  set nameOffset(int value) {
+    assert(value == null || value >= 0);
+    this._nameOffset = value;
+  }
+
+  @override
+  List<UnlinkedTypeParamBuilder> get typeParameters =>
+      _typeParameters ??= <UnlinkedTypeParamBuilder>[];
+
+  /// Type parameters of the extension, if any.
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+    this._typeParameters = value;
+  }
+
+  UnlinkedExtensionBuilder(
+      {List<UnlinkedExprBuilder> annotations,
+      CodeRangeBuilder codeRange,
+      UnlinkedDocumentationCommentBuilder documentationComment,
+      List<UnlinkedExecutableBuilder> executables,
+      EntityRefBuilder extendedType,
+      String name,
+      int nameOffset,
+      List<UnlinkedTypeParamBuilder> typeParameters})
+      : _annotations = annotations,
+        _codeRange = codeRange,
+        _documentationComment = documentationComment,
+        _executables = executables,
+        _extendedType = extendedType,
+        _name = name,
+        _nameOffset = nameOffset,
+        _typeParameters = typeParameters;
+
+  /// Flush [informative] data recursively.
+  void flushInformative() {
+    _annotations?.forEach((b) => b.flushInformative());
+    _codeRange = null;
+    _documentationComment = null;
+    _executables?.forEach((b) => b.flushInformative());
+    _extendedType?.flushInformative();
+    _nameOffset = null;
+    _typeParameters?.forEach((b) => b.flushInformative());
+  }
+
+  /// Accumulate non-[informative] data into [signature].
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._name ?? '');
+    if (this._executables == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._executables.length);
+      for (var x in this._executables) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._extendedType != null);
+    this._extendedType?.collectApiSignature(signature);
+    if (this._annotations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._annotations.length);
+      for (var x in this._annotations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._typeParameters == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._typeParameters.length);
+      for (var x in this._typeParameters) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_annotations;
+    fb.Offset offset_codeRange;
+    fb.Offset offset_documentationComment;
+    fb.Offset offset_executables;
+    fb.Offset offset_extendedType;
+    fb.Offset offset_name;
+    fb.Offset offset_typeParameters;
+    if (!(_annotations == null || _annotations.isEmpty)) {
+      offset_annotations = fbBuilder
+          .writeList(_annotations.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_codeRange != null) {
+      offset_codeRange = _codeRange.finish(fbBuilder);
+    }
+    if (_documentationComment != null) {
+      offset_documentationComment = _documentationComment.finish(fbBuilder);
+    }
+    if (!(_executables == null || _executables.isEmpty)) {
+      offset_executables = fbBuilder
+          .writeList(_executables.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_extendedType != null) {
+      offset_extendedType = _extendedType.finish(fbBuilder);
+    }
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (!(_typeParameters == null || _typeParameters.isEmpty)) {
+      offset_typeParameters = fbBuilder
+          .writeList(_typeParameters.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_annotations != null) {
+      fbBuilder.addOffset(4, offset_annotations);
+    }
+    if (offset_codeRange != null) {
+      fbBuilder.addOffset(7, offset_codeRange);
+    }
+    if (offset_documentationComment != null) {
+      fbBuilder.addOffset(5, offset_documentationComment);
+    }
+    if (offset_executables != null) {
+      fbBuilder.addOffset(2, offset_executables);
+    }
+    if (offset_extendedType != null) {
+      fbBuilder.addOffset(3, offset_extendedType);
+    }
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addUint32(1, _nameOffset);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(6, offset_typeParameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _UnlinkedExtensionReader extends fb.TableReader<_UnlinkedExtensionImpl> {
+  const _UnlinkedExtensionReader();
+
+  @override
+  _UnlinkedExtensionImpl createObject(fb.BufferContext bc, int offset) =>
+      new _UnlinkedExtensionImpl(bc, offset);
+}
+
+class _UnlinkedExtensionImpl extends Object
+    with _UnlinkedExtensionMixin
+    implements idl.UnlinkedExtension {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _UnlinkedExtensionImpl(this._bc, this._bcOffset);
+
+  List<idl.UnlinkedExpr> _annotations;
+  idl.CodeRange _codeRange;
+  idl.UnlinkedDocumentationComment _documentationComment;
+  List<idl.UnlinkedExecutable> _executables;
+  idl.EntityRef _extendedType;
+  String _name;
+  int _nameOffset;
+  List<idl.UnlinkedTypeParam> _typeParameters;
+
+  @override
+  List<idl.UnlinkedExpr> get annotations {
+    _annotations ??=
+        const fb.ListReader<idl.UnlinkedExpr>(const _UnlinkedExprReader())
+            .vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedExpr>[]);
+    return _annotations;
+  }
+
+  @override
+  idl.CodeRange get codeRange {
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 7, null);
+    return _codeRange;
+  }
+
+  @override
+  idl.UnlinkedDocumentationComment get documentationComment {
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader()
+        .vTableGet(_bc, _bcOffset, 5, null);
+    return _documentationComment;
+  }
+
+  @override
+  List<idl.UnlinkedExecutable> get executables {
+    _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(
+            const _UnlinkedExecutableReader())
+        .vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedExecutable>[]);
+    return _executables;
+  }
+
+  @override
+  idl.EntityRef get extendedType {
+    _extendedType ??=
+        const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
+    return _extendedType;
+  }
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
+    return _nameOffset;
+  }
+
+  @override
+  List<idl.UnlinkedTypeParam> get typeParameters {
+    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(
+            const _UnlinkedTypeParamReader())
+        .vTableGet(_bc, _bcOffset, 6, const <idl.UnlinkedTypeParam>[]);
+    return _typeParameters;
+  }
+}
+
+abstract class _UnlinkedExtensionMixin implements idl.UnlinkedExtension {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty)
+      _result["annotations"] =
+          annotations.map((_value) => _value.toJson()).toList();
+    if (codeRange != null) _result["codeRange"] = codeRange.toJson();
+    if (documentationComment != null)
+      _result["documentationComment"] = documentationComment.toJson();
+    if (executables.isNotEmpty)
+      _result["executables"] =
+          executables.map((_value) => _value.toJson()).toList();
+    if (extendedType != null) _result["extendedType"] = extendedType.toJson();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (typeParameters.isNotEmpty)
+      _result["typeParameters"] =
+          typeParameters.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "annotations": annotations,
+        "codeRange": codeRange,
+        "documentationComment": documentationComment,
+        "executables": executables,
+        "extendedType": extendedType,
+        "name": name,
+        "nameOffset": nameOffset,
+        "typeParameters": typeParameters,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
 class UnlinkedImportBuilder extends Object
     with _UnlinkedImportMixin
     implements idl.UnlinkedImport {
@@ -26053,6 +26577,7 @@
     implements idl.UnlinkedUnit {
   List<int> _apiSignature;
   List<UnlinkedClassBuilder> _classes;
+  List<UnlinkedExtensionBuilder> _extensions;
   CodeRangeBuilder _codeRange;
   List<UnlinkedEnumBuilder> _enums;
   List<UnlinkedExecutableBuilder> _executables;
@@ -26094,6 +26619,15 @@
   }
 
   @override
+  List<UnlinkedExtensionBuilder> get extensions =>
+      _extensions ??= <UnlinkedExtensionBuilder>[];
+
+  /// Extensions declared in the compilation unit.
+  set extensions(List<UnlinkedExtensionBuilder> value) {
+    this._extensions = value;
+  }
+
+  @override
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the unit.
@@ -26272,6 +26806,7 @@
   UnlinkedUnitBuilder(
       {List<int> apiSignature,
       List<UnlinkedClassBuilder> classes,
+      List<UnlinkedExtensionBuilder> extensions,
       CodeRangeBuilder codeRange,
       List<UnlinkedEnumBuilder> enums,
       List<UnlinkedExecutableBuilder> executables,
@@ -26293,6 +26828,7 @@
       List<UnlinkedVariableBuilder> variables})
       : _apiSignature = apiSignature,
         _classes = classes,
+        _extensions = extensions,
         _codeRange = codeRange,
         _enums = enums,
         _executables = executables,
@@ -26316,6 +26852,7 @@
   /// Flush [informative] data recursively.
   void flushInformative() {
     _classes?.forEach((b) => b.flushInformative());
+    _extensions?.forEach((b) => b.flushInformative());
     _codeRange = null;
     _enums?.forEach((b) => b.flushInformative());
     _executables?.forEach((b) => b.flushInformative());
@@ -26437,6 +26974,14 @@
       }
     }
     signature.addBool(this._isNNBD == true);
+    if (this._extensions == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._extensions.length);
+      for (var x in this._extensions) {
+        x?.collectApiSignature(signature);
+      }
+    }
   }
 
   List<int> toBuffer() {
@@ -26447,6 +26992,7 @@
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_apiSignature;
     fb.Offset offset_classes;
+    fb.Offset offset_extensions;
     fb.Offset offset_codeRange;
     fb.Offset offset_enums;
     fb.Offset offset_executables;
@@ -26469,6 +27015,10 @@
       offset_classes = fbBuilder
           .writeList(_classes.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (!(_extensions == null || _extensions.isEmpty)) {
+      offset_extensions = fbBuilder
+          .writeList(_extensions.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (_codeRange != null) {
       offset_codeRange = _codeRange.finish(fbBuilder);
     }
@@ -26532,6 +27082,9 @@
     if (offset_classes != null) {
       fbBuilder.addOffset(2, offset_classes);
     }
+    if (offset_extensions != null) {
+      fbBuilder.addOffset(22, offset_extensions);
+    }
     if (offset_codeRange != null) {
       fbBuilder.addOffset(15, offset_codeRange);
     }
@@ -26616,6 +27169,7 @@
 
   List<int> _apiSignature;
   List<idl.UnlinkedClass> _classes;
+  List<idl.UnlinkedExtension> _extensions;
   idl.CodeRange _codeRange;
   List<idl.UnlinkedEnum> _enums;
   List<idl.UnlinkedExecutable> _executables;
@@ -26652,6 +27206,14 @@
   }
 
   @override
+  List<idl.UnlinkedExtension> get extensions {
+    _extensions ??= const fb.ListReader<idl.UnlinkedExtension>(
+            const _UnlinkedExtensionReader())
+        .vTableGet(_bc, _bcOffset, 22, const <idl.UnlinkedExtension>[]);
+    return _extensions;
+  }
+
+  @override
   idl.CodeRange get codeRange {
     _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 15, null);
     return _codeRange;
@@ -26802,6 +27364,9 @@
     if (apiSignature.isNotEmpty) _result["apiSignature"] = apiSignature;
     if (classes.isNotEmpty)
       _result["classes"] = classes.map((_value) => _value.toJson()).toList();
+    if (extensions.isNotEmpty)
+      _result["extensions"] =
+          extensions.map((_value) => _value.toJson()).toList();
     if (codeRange != null) _result["codeRange"] = codeRange.toJson();
     if (enums.isNotEmpty)
       _result["enums"] = enums.map((_value) => _value.toJson()).toList();
@@ -26847,6 +27412,7 @@
   Map<String, Object> toMap() => {
         "apiSignature": apiSignature,
         "classes": classes,
+        "extensions": extensions,
         "codeRange": codeRange,
         "enums": enums,
         "executables": executables,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index caaf7d3..f4e0ac1 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1455,6 +1455,9 @@
 
 /// Information about an error in a resolved unit.
 table AnalysisDriverUnitError {
+  /// The context messages associated with the error.
+  contextMessages:[DiagnosticMessage] (id: 5);
+
   /// The optional correction hint for the error.
   correction:string (id: 4);
 
@@ -1689,6 +1692,21 @@
   offset:uint (id: 0);
 }
 
+table DiagnosticMessage {
+  /// The absolute and normalized path of the file associated with this message.
+  filePath:string (id: 0);
+
+  /// The length of the source range associated with this message.
+  length:uint (id: 1);
+
+  /// The text of the message.
+  message:string (id: 2);
+
+  /// The zero-based offset from the start of the file to the beginning of the
+  /// source range associated with this message.
+  offset:uint (id: 3);
+}
+
 /// Information about the Dartdoc directives in an [AvailableFile].
 table DirectiveInfo {
   /// The names of the defined templates.
@@ -2702,6 +2720,36 @@
   strings:[string] (id: 3);
 }
 
+/// Unlinked summary information about an extension declaration.
+table UnlinkedExtension {
+  /// Annotations for this extension.
+  annotations:[UnlinkedExpr] (id: 4);
+
+  /// Code range of the extension.
+  codeRange:CodeRange (id: 7);
+
+  /// Documentation comment for the extension, or `null` if there is no
+  /// documentation comment.
+  documentationComment:UnlinkedDocumentationComment (id: 5);
+
+  /// Executable objects (methods, getters, and setters) contained in the
+  /// extension.
+  executables:[UnlinkedExecutable] (id: 2);
+
+  /// The type being extended.
+  extendedType:EntityRef (id: 3);
+
+  /// Name of the extension, or an empty string if there is no name.
+  name:string (id: 0);
+
+  /// Offset of the extension name relative to the beginning of the file, or
+  /// zero if there is no name.
+  nameOffset:uint (id: 1);
+
+  /// Type parameters of the extension, if any.
+  typeParameters:[UnlinkedTypeParam] (id: 6);
+}
+
 /// Unlinked summary information about an import declaration.
 table UnlinkedImport {
   /// Annotations for this import declaration.
@@ -3022,6 +3070,9 @@
   /// Classes declared in the compilation unit.
   classes:[UnlinkedClass] (id: 2);
 
+  /// Extensions declared in the compilation unit.
+  extensions:[UnlinkedExtension] (id: 22);
+
   /// Code range of the unit.
   codeRange:CodeRange (id: 15);
 
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 1034e2b..b157cdf 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -118,6 +118,10 @@
 
 /// Information about an error in a resolved unit.
 abstract class AnalysisDriverUnitError extends base.SummaryClass {
+  /// The context messages associated with the error.
+  @Id(5)
+  List<DiagnosticMessage> get contextMessages;
+
   /// The optional correction hint for the error.
   @Id(4)
   String get correction;
@@ -444,6 +448,25 @@
   int get offset;
 }
 
+abstract class DiagnosticMessage extends base.SummaryClass {
+  /// The absolute and normalized path of the file associated with this message.
+  @Id(0)
+  String get filePath;
+
+  /// The length of the source range associated with this message.
+  @Id(1)
+  int get length;
+
+  /// The text of the message.
+  @Id(2)
+  String get message;
+
+  /// The zero-based offset from the start of the file to the beginning of the
+  /// source range associated with this message.
+  @Id(3)
+  int get offset;
+}
+
 /// Information about the Dartdoc directives in an [AvailableFile].
 abstract class DirectiveInfo extends base.SummaryClass {
   /// The names of the defined templates.
@@ -3473,6 +3496,47 @@
   bitShiftRightLogical,
 }
 
+/// Unlinked summary information about an extension declaration.
+abstract class UnlinkedExtension extends base.SummaryClass {
+  /// Annotations for this extension.
+  @Id(4)
+  List<UnlinkedExpr> get annotations;
+
+  /// Code range of the extension.
+  @informative
+  @Id(7)
+  CodeRange get codeRange;
+
+  /// Documentation comment for the extension, or `null` if there is no
+  /// documentation comment.
+  @informative
+  @Id(5)
+  UnlinkedDocumentationComment get documentationComment;
+
+  /// Executable objects (methods, getters, and setters) contained in the
+  /// extension.
+  @Id(2)
+  List<UnlinkedExecutable> get executables;
+
+  /// The type being extended.
+  @Id(3)
+  EntityRef get extendedType;
+
+  /// Name of the extension, or an empty string if there is no name.
+  @Id(0)
+  String get name;
+
+  /// Offset of the extension name relative to the beginning of the file, or
+  /// zero if there is no name.
+  @informative
+  @Id(1)
+  int get nameOffset;
+
+  /// Type parameters of the extension, if any.
+  @Id(6)
+  List<UnlinkedTypeParam> get typeParameters;
+}
+
 /// Unlinked summary information about an import declaration.
 abstract class UnlinkedImport extends base.SummaryClass {
   /// Annotations for this import declaration.
@@ -4128,6 +4192,10 @@
   @Id(2)
   List<UnlinkedClass> get classes;
 
+  /// Extensions declared in the compilation unit.
+  @Id(22)
+  List<UnlinkedExtension> get extensions;
+
   /// Code range of the unit.
   @informative
   @Id(15)
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 5bc3580..e5e51d3 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1075,6 +1075,7 @@
   Map<String, ReferenceableElementForLink> _containedNames;
   List<TopLevelVariableElementForLink> _topLevelVariables;
   List<ClassElementForLink_Enum> _enums;
+  List<ExtensionElementForLink> _extensions;
   List<TopLevelFunctionElementForLink> _functions;
   List<PropertyAccessorElementForLink> _accessors;
   List<FunctionTypeAliasElementForLink> _functionTypeAliases;
@@ -1153,6 +1154,17 @@
   }
 
   @override
+  List<ExtensionElementForLink> get extensions {
+    if (_extensions == null) {
+      _extensions = <ExtensionElementForLink>[];
+      for (UnlinkedExtension unlinkedExtension in _unlinkedUnit.extensions) {
+        _extensions.add(ExtensionElementForLink(this, unlinkedExtension));
+      }
+    }
+    return _extensions;
+  }
+
+  @override
   List<TopLevelFunctionElementForLink> get functions {
     if (_functions == null) {
       _functions = <TopLevelFunctionElementForLink>[];
@@ -2553,6 +2565,21 @@
   }
 }
 
+class ExtensionElementForLink
+    with ReferenceableElementForLink
+    implements ExtensionElementImpl {
+  @override
+  final CompilationUnitElementForLink enclosingElement;
+
+  // TODO(brianwilkerson) Remove this field if it remains unreferenced.
+  final UnlinkedExtension _unlinkedExtension;
+
+  ExtensionElementForLink(this.enclosingElement, this._unlinkedExtension);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
 /// Element representing a field resynthesized from a summary during
 /// linking.
 abstract class FieldElementForLink implements FieldElement {
@@ -3605,9 +3632,6 @@
   }
 
   @override
-  bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
-
-  @override
   ContextForLink get context => _linker.context;
 
   @override
@@ -3644,6 +3668,9 @@
   bool get isInSdk => _absoluteUri.scheme == 'dart';
 
   @override
+  bool get isNonNullableByDefault => _unlinkedDefiningUnit.isNNBD;
+
+  @override
   bool get isSynthetic => _linkedLibrary == null;
 
   /// If this library is part of the build unit being linked, return the library
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 3608b07..f5da9a7 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -238,6 +238,10 @@
   /// [UnlinkedClass.executables] or [UnlinkedExecutable.localFunctions].
   List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
 
+  /// List of objects which should be written to [UnlinkedUnit.extensions].
+  final List<UnlinkedExtensionBuilder> extensions =
+      <UnlinkedExtensionBuilder>[];
+
   /// List of objects which should be written to [UnlinkedUnit.exports].
   final List<UnlinkedExportNonPublicBuilder> exports =
       <UnlinkedExportNonPublicBuilder>[];
@@ -504,6 +508,7 @@
     b.classes = classes;
     b.enums = enums;
     b.executables = executables;
+    b.extensions = extensions;
     b.exports = exports;
     b.imports = unlinkedImports;
     b.mixins = mixins;
@@ -1184,6 +1189,41 @@
   }
 
   @override
+  visitExtensionDeclaration(ExtensionDeclaration node) {
+    int oldScopesLength = scopes.length;
+    enclosingClassHasConstConstructor = false;
+    List<UnlinkedExecutableBuilder> oldExecutables = executables;
+    executables = <UnlinkedExecutableBuilder>[];
+    List<UnlinkedVariableBuilder> oldVariables = variables;
+    variables = <UnlinkedVariableBuilder>[];
+    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
+    scopes.add(typeParameterScope);
+
+    UnlinkedExtensionBuilder b = UnlinkedExtensionBuilder();
+    b.name = node.name?.name;
+    b.nameOffset = node.name?.offset ?? 0;
+    b.typeParameters =
+        serializeTypeParameters(node.typeParameters, typeParameterScope);
+    if (node.members != null) {
+      scopes.add(buildClassMemberScope(node.name?.name, node.members));
+      for (ClassMember member in node.members) {
+        member.accept(this);
+      }
+      scopes.removeLast();
+    }
+    b.executables = executables;
+    b.documentationComment = serializeDocumentation(node.documentationComment);
+    b.annotations = serializeAnnotations(node.metadata);
+    b.codeRange = serializeCodeRange(node);
+    extensions.add(b);
+
+    scopes.removeLast();
+    assert(scopes.length == oldScopesLength);
+    executables = oldExecutables;
+    variables = oldVariables;
+  }
+
+  @override
   void visitFieldDeclaration(FieldDeclaration node) {
     serializeVariables(node.fields, node.staticKeyword != null,
         node.documentationComment, node.metadata, true);
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 46f9ec4..0bb6202 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -344,7 +344,7 @@
   }
 
   CompilationUnit _read_compilationUnit(LinkedNode data) {
-    return astFactory.compilationUnit2(
+    return astFactory.compilationUnit(
         beginToken: null,
         scriptTag: _readNode(data.compilationUnit_scriptTag),
         directives: _readNodeList(data.compilationUnit_directives),
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ec6a624..b7ed57f 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -804,9 +804,6 @@
     if (node is VariableDeclaration) {
       return node.isLate;
     }
-    if (node is VariableDeclarationList) {
-      return node.isLate;
-    }
     if (node is EnumConstantDeclaration) {
       return false;
     }
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index ac469fd..0da3ffe 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -93,8 +93,8 @@
     initializerInference.createNodes();
 
     _performOverrideInference();
-    initializerInference.perform();
     _inferConstructorFieldFormals();
+    initializerInference.perform();
   }
 
   void _inferConstructorFieldFormals() {
@@ -103,6 +103,7 @@
         for (var class_ in unit.types) {
           var fields = <String, DartType>{};
           for (var field in class_.fields) {
+            if (field.isStatic) continue;
             if (field.isSynthetic) continue;
 
             var name = field.name;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 9bc342b..d84a7ab 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -175,7 +175,7 @@
   ];
 
   // Supported 'analyzer' optional checks options.
-  static const List<String> optionalCecksOptions = const [
+  static const List<String> optionalChecksOptions = const [
     chromeOsManifestChecks,
   ];
 }
@@ -497,7 +497,8 @@
 
 /// Validates `analyzer` optional-checks value configuration options.
 class OptionalChecksValueValidator extends OptionsValidator {
-  ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.optionalCecksOptions);
+  ErrorBuilder builder =
+      new ErrorBuilder(AnalyzerOptions.optionalChecksOptions);
   ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
 
   @override
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 917fc1c..52afb8a 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -461,6 +461,7 @@
   double nextDouble() => 2.0;
   int nextInt() => 1;
 }
+class Point<T extends num> {}
 ''');
 
 const List<SdkLibrary> _LIBRARIES = const [
diff --git a/pkg/analyzer/lib/src/util/ast_data_extractor.dart b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
new file mode 100644
index 0000000..bf528bd
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/ast_data_extractor.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:front_end/src/testing/id.dart'
+    show ActualData, DataRegistry, Id, IdKind, MemberId, NodeId;
+
+/// Abstract IR visitor for computing data corresponding to a node or element,
+/// and record it with a generic [Id]
+/// TODO(paulberry): if I try to extend GeneralizingAstVisitor<void>, the VM
+/// crashes.
+abstract class AstDataExtractor<T> extends GeneralizingAstVisitor<dynamic>
+    with DataRegistry<T> {
+  final Uri uri;
+
+  @override
+  final Map<Id, ActualData<T>> actualMap;
+
+  AstDataExtractor(this.uri, this.actualMap);
+
+  NodeId computeDefaultNodeId(AstNode node) =>
+      NodeId(_nodeOffset(node), IdKind.node);
+
+  void computeForExpression(Expression node, NodeId id) {
+    if (id == null) return;
+    T value = computeNodeValue(id, node);
+    registerValue(uri, node.offset, id, value, node);
+  }
+
+  void computeForMember(Declaration node, Id id) {
+    if (id == null) return;
+    T value = computeNodeValue(id, node);
+    registerValue(uri, node.offset, id, value, node);
+  }
+
+  void computeForStatement(Statement node, NodeId id) {
+    if (id == null) return;
+    T value = computeNodeValue(id, node);
+    registerValue(uri, node.offset, id, value, node);
+  }
+
+  /// Implement this to compute the data corresponding to [node].
+  ///
+  /// If `null` is returned, [node] has no associated data.
+  T computeNodeValue(Id id, AstNode node);
+
+  Id createMemberId(Declaration node) {
+    var element = node.declaredElement;
+    if (element.enclosingElement is CompilationUnitElement) {
+      var memberName = element.name;
+      if (element is PropertyAccessorElement && element.isSetter) {
+        memberName += '=';
+      }
+      return MemberId.internal(memberName);
+    }
+    throw UnimplementedError(
+        'TODO(paulberry): $element (${element.runtimeType})');
+  }
+
+  NodeId createStatementId(Statement node) =>
+      NodeId(_nodeOffset(node), IdKind.stmt);
+
+  @override
+  void fail(String message) {
+    throw _Failure(message);
+  }
+
+  @override
+  void report(Uri uri, int offset, String message) {
+    // TODO(paulberry): find a way to print the error more nicely.
+    print('$uri:$offset: $message');
+  }
+
+  void run(CompilationUnit unit) {
+    unit.accept(this);
+  }
+
+  @override
+  visitExpression(Expression node) {
+    computeForExpression(node, computeDefaultNodeId(node));
+    super.visitExpression(node);
+  }
+
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    if (node.parent is CompilationUnit) {
+      computeForMember(node, createMemberId(node));
+    }
+    return super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  visitStatement(Statement node) {
+    computeForStatement(node, createStatementId(node));
+    super.visitStatement(node);
+  }
+
+  int _nodeOffset(AstNode node) {
+    var offset = node.offset;
+    assert(offset != null && offset >= 0,
+        "No fileOffset on $node (${node.runtimeType})");
+    return offset;
+  }
+}
+
+class _Failure implements Exception {
+  final message;
+
+  _Failure([this.message]);
+
+  String toString() {
+    if (message == null) return "Exception";
+    return "Exception: $message";
+  }
+}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 29b6585..6f7bc5b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.36.4-dev
+version: 0.37.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.18
+  front_end: 0.1.20
   glob: ^1.0.3
   html: '>=0.13.4+1 <0.15.0'
-  kernel: 0.3.18
+  kernel: 0.3.20
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 1aebc1fe8..2f4eb29 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -2,10 +2,14 @@
 // 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 'dart:io';
+
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -17,6 +21,109 @@
 
 @reflectiveTest
 class UtilitiesTest with ResourceProviderMixin {
+  FeatureSet get defaultFeatureSet =>
+      FeatureSet.forTesting(sdkVersion: '2.2.2');
+
+  test_parseFile_default_resource_provider() {
+    String content = '''
+void main() => print('Hello, world!');
+    ''';
+    ParseStringResult result = _withTemporaryFile(content,
+        (path) => parseFile(path: path, featureSet: defaultFeatureSet));
+    expect(result.content, content);
+    expect(result.errors, isEmpty);
+    expect(result.lineInfo, isNotNull);
+    expect(result.unit.toString(),
+        equals("void main() => print('Hello, world!');"));
+  }
+
+  test_parseFile_errors_noThrow() {
+    String content = '''
+void main() => print('Hello, world!')
+''';
+    ParseStringResult result = _withMemoryFile(
+        content,
+        (resourceProvider, path) => parseFile(
+            path: path,
+            featureSet: defaultFeatureSet,
+            resourceProvider: resourceProvider,
+            throwIfDiagnostics: false));
+    expect(result.content, content);
+    expect(result.errors, hasLength(1));
+    expect(result.lineInfo, isNotNull);
+    expect(result.unit.toString(),
+        equals("void main() => print('Hello, world!');"));
+  }
+
+  test_parseFile_errors_throw() {
+    String content = '''
+void main() => print('Hello, world!')
+''';
+    expect(
+        () => _withMemoryFile(
+            content,
+            (resourceProvider, path) => parseFile(
+                path: path,
+                featureSet: defaultFeatureSet,
+                resourceProvider: resourceProvider)),
+        throwsA(const TypeMatcher<ArgumentError>()));
+  }
+
+  test_parseFile_featureSet_nnbd_off() {
+    String content = '''
+int? f() => 1;
+''';
+    var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0');
+    expect(featureSet.isEnabled(Feature.non_nullable), isFalse);
+    ParseStringResult result = _withMemoryFile(
+        content,
+        (resourceProvider, path) => parseFile(
+            path: path,
+            resourceProvider: resourceProvider,
+            throwIfDiagnostics: false,
+            featureSet: featureSet));
+    expect(result.content, content);
+    expect(result.errors, hasLength(1));
+    expect(result.lineInfo, isNotNull);
+    expect(result.unit.toString(), equals('int? f() => 1;'));
+  }
+
+  test_parseFile_featureSet_nnbd_on() {
+    String content = '''
+int? f() => 1;
+''';
+    var featureSet =
+        FeatureSet.forTesting(additionalFeatures: [Feature.non_nullable]);
+    ParseStringResult result = _withMemoryFile(
+        content,
+        (resourceProvider, path) => parseFile(
+            path: path,
+            resourceProvider: resourceProvider,
+            throwIfDiagnostics: false,
+            featureSet: featureSet));
+    expect(result.content, content);
+    expect(result.errors, isEmpty);
+    expect(result.lineInfo, isNotNull);
+    expect(result.unit.toString(), equals('int? f() => 1;'));
+  }
+
+  test_parseFile_noErrors() {
+    String content = '''
+void main() => print('Hello, world!');
+''';
+    ParseStringResult result = _withMemoryFile(
+        content,
+        (resourceProvider, path) => parseFile(
+            path: path,
+            featureSet: defaultFeatureSet,
+            resourceProvider: resourceProvider));
+    expect(result.content, content);
+    expect(result.errors, isEmpty);
+    expect(result.lineInfo, isNotNull);
+    expect(result.unit.toString(),
+        equals("void main() => print('Hello, world!');"));
+  }
+
   test_parseString_errors_noThrow() {
     String content = '''
 void main() => print('Hello, world!')
@@ -88,4 +195,24 @@
     expect(result.unit.toString(),
         equals("void main() => print('Hello, world!');"));
   }
+
+  T _withMemoryFile<T>(String content,
+      T callback(MemoryResourceProvider resourceProvider, String path)) {
+    var resourceProvider = MemoryResourceProvider();
+    var path =
+        resourceProvider.pathContext.fromUri(Uri.parse('file:///test.dart'));
+    resourceProvider.newFile(path, content);
+    return callback(resourceProvider, path);
+  }
+
+  T _withTemporaryFile<T>(String content, T callback(String path)) {
+    var tempDir = Directory.systemTemp.createTempSync();
+    try {
+      var file = File(p.join(tempDir.path, 'test.dart'));
+      file.writeAsStringSync(content);
+      return callback(file.path);
+    } finally {
+      tempDir.deleteSync(recursive: true);
+    }
+  }
 }
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index a7de7ad..adfcf2e 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -274,7 +274,7 @@
             null,
             AstTestFactory.typeName4('int'),
             [AstTestFactory.variableDeclaration('V')]);
-    CompilationUnit unit = astFactory.compilationUnit2(
+    CompilationUnit unit = astFactory.compilationUnit(
         beginToken: topLevelVariableDeclaration.beginToken,
         declarations: [topLevelVariableDeclaration],
         endToken: topLevelVariableDeclaration.endToken,
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a860794..7e37544 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart'; // ignore: deprecated_member_use_from_same_package
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
@@ -38,8 +37,6 @@
     defineReflectiveTests(ErrorSeverityTest);
     defineReflectiveTests(FileBasedSourceTest);
     defineReflectiveTests(ResolveRelativeUriTest);
-    // ignore: deprecated_member_use_from_same_package
-    defineReflectiveTests(SDKLibrariesReaderTest);
     defineReflectiveTests(UriKindTest);
   });
 }
@@ -520,80 +517,6 @@
   }
 }
 
-@deprecated
-@reflectiveTest
-class SDKLibrariesReaderTest extends EngineTestCase {
-  test_readFrom_dart2js() async {
-    LibraryMap libraryMap = new SdkLibrariesReader(true)
-        .readFromFile(FileUtilities2.createFile("/libs.dart"), r'''
-final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
-  'first' : const LibraryInfo(
-    'first/first.dart',
-    categories: 'Client',
-    documented: true,
-    platforms: VM_PLATFORM,
-    dart2jsPath: 'first/first_dart2js.dart'),
-};''');
-    expect(libraryMap, isNotNull);
-    expect(libraryMap.size(), 1);
-    SdkLibrary first = libraryMap.getLibrary("dart:first");
-    expect(first, isNotNull);
-    expect(first.category, "Client");
-    expect(first.path, "first/first_dart2js.dart");
-    expect(first.shortName, "dart:first");
-    expect(first.isDart2JsLibrary, false);
-    expect(first.isDocumented, true);
-    expect(first.isImplementation, false);
-    expect(first.isVmLibrary, true);
-  }
-
-  test_readFrom_empty() async {
-    LibraryMap libraryMap = new SdkLibrariesReader(false)
-        .readFromFile(FileUtilities2.createFile("/libs.dart"), "");
-    expect(libraryMap, isNotNull);
-    expect(libraryMap.size(), 0);
-  }
-
-  test_readFrom_normal() async {
-    LibraryMap libraryMap = new SdkLibrariesReader(false)
-        .readFromFile(FileUtilities2.createFile("/libs.dart"), r'''
-final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
-  'first' : const LibraryInfo(
-    'first/first.dart',
-    categories: 'Client',
-    documented: true,
-    platforms: VM_PLATFORM),
-
-  'second' : const LibraryInfo(
-    'second/second.dart',
-    categories: 'Server',
-    documented: false,
-    implementation: true,
-    platforms: 0),
-};''');
-    expect(libraryMap, isNotNull);
-    expect(libraryMap.size(), 2);
-    SdkLibrary first = libraryMap.getLibrary("dart:first");
-    expect(first, isNotNull);
-    expect(first.category, "Client");
-    expect(first.path, "first/first.dart");
-    expect(first.shortName, "dart:first");
-    expect(first.isDart2JsLibrary, false);
-    expect(first.isDocumented, true);
-    expect(first.isImplementation, false);
-    expect(first.isVmLibrary, true);
-    SdkLibrary second = libraryMap.getLibrary("dart:second");
-    expect(second, isNotNull);
-    expect(second.category, "Server");
-    expect(second.path, "second/second.dart");
-    expect(second.shortName, "dart:second");
-    expect(second.isDart2JsLibrary, false);
-    expect(second.isDocumented, false);
-    expect(second.isImplementation, true);
-    expect(second.isVmLibrary, false);
-  }
-}
-
 @reflectiveTest
 class UriKindTest {
   test_fromEncoding() async {
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 181575f..21bcf7c 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -2459,7 +2459,7 @@
 class Baz extends Bar {}
 void main() {}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 3),
     ]);
     // Instantiate-to-bounds should have instantiated "Bar" to "Bar<Foo>".
     expect(result.unit.declaredElement.getType('Baz').supertype.toString(),
@@ -4723,7 +4723,8 @@
 }
 print(x) {}
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+          expectedMessages: [message('/test/lib/test.dart', 34, 1)]),
     ]);
   }
 
@@ -4736,7 +4737,8 @@
 }
 print(x) {}
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+          expectedMessages: [message('/test/lib/test.dart', 38, 1)]),
     ]);
   }
 
@@ -4751,7 +4753,8 @@
 }
 print(x) {}
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1,
+          expectedMessages: [message('/test/lib/test.dart', 48, 1)]),
     ]);
   }
 
@@ -4761,7 +4764,8 @@
   var v = () => v;
 }
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1,
+          expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
     ]);
   }
 
@@ -4771,7 +4775,8 @@
   var v = v;
 }
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1,
+          expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
     ]);
   }
 
@@ -4783,7 +4788,8 @@
   print(s + String);
 }
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+          expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
     ]);
   }
 
@@ -4795,7 +4801,8 @@
   print(s + String);
 }
 ''', [
-      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+      error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+          expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
     ]);
   }
 
@@ -5141,7 +5148,7 @@
     ];
     if (!AnalysisDriver.useSummary2) {
       errors.add(
-        error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
+        error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 22, 3),
       );
     }
     await assertErrorsInCode('''
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index a8a660d..5b08f71 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -2,6 +2,7 @@
 // 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:front_end/src/fasta/messages.dart' show MessageCode;
 import 'package:front_end/src/fasta/parser.dart';
 import 'package:front_end/src/fasta/parser/forwarding_listener.dart';
 import 'package:front_end/src/scanner/token.dart';
@@ -578,6 +579,13 @@
   }
 
   @override
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    end('InvalidAwaitExpression');
+    super.endInvalidAwaitExpression(beginToken, endToken, errorCode);
+  }
+
+  @override
   void endBlock(int count, Token beginToken, Token endToken) {
     end('Block');
     super.endBlock(count, beginToken, endToken);
@@ -908,10 +916,11 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     end('Method');
-    super.endMethod(getOrSet, beginToken, beginParam, endToken);
+    super.endMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index cb15507..e67ca0b 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1845,8 +1845,8 @@
     // Run parser
     ErrorReporter errorReporter = new ErrorReporter(listener, source);
     fasta.Parser parser = new fasta.Parser(null);
-    AstBuilder astBuilder = new AstBuilder(errorReporter, source.uri, true)
-      ..configureFeatures(featureSet);
+    AstBuilder astBuilder =
+        new AstBuilder(errorReporter, source.uri, true, featureSet);
     parser.listener = astBuilder;
     astBuilder.parser = parser;
     astBuilder.allowNativeClause = allowNativeClause;
@@ -2780,9 +2780,8 @@
   ParserProxy._(analyzer.Token firstToken, ErrorReporter errorReporter,
       Uri fileUri, this._errorListener, FeatureSet featureSet,
       {bool allowNativeClause: false, this.expectedEndOffset})
-      : super(firstToken, errorReporter, fileUri,
+      : super(firstToken, errorReporter, fileUri, featureSet,
             allowNativeClause: allowNativeClause) {
-    configureFeatures(featureSet);
     _eventListener = new ForwardingTestListener(astBuilder);
     fastaParser.listener = _eventListener;
   }
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index ad2f86f..6b2cfd5 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1071,7 +1071,7 @@
 class G<E extends A> {}
 class D = G<B> with C;
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
     ]);
   }
 
@@ -1082,7 +1082,7 @@
 class G<E extends A> {}
 class C extends G<B>{}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
     ]);
   }
 
@@ -1092,7 +1092,7 @@
 class X<T extends Type> {}
 class Y<U> extends X<U> {}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
     ]);
   }
 
@@ -1106,7 +1106,7 @@
   C(G<B> this.f) {}
 }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 71, 1),
     ]);
   }
 
@@ -1117,7 +1117,7 @@
 class G<E extends A> {}
 G<B> f() { return null; }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
     ]);
   }
 
@@ -1128,7 +1128,7 @@
 class G<E extends A> {}
 typedef G<B> f();
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 56, 1),
     ]);
   }
 
@@ -1139,7 +1139,7 @@
 class G<E extends A> {}
 f(G<B> h()) {}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
     ]);
   }
 
@@ -1150,7 +1150,7 @@
 class G<E extends A> {}
 class C implements G<B>{}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 67, 1),
     ]);
   }
 
@@ -1161,7 +1161,7 @@
 class G<E extends A> {}
 var b = 1 is G<B>;
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 61, 1),
     ]);
   }
 
@@ -1178,7 +1178,7 @@
   print(f<String>('hello', 'world'));
 }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 145, 6),
     ]);
   }
 
@@ -1198,7 +1198,7 @@
   print(factory.point<String>('hello', 'world'));
 }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 202, 6),
     ]);
   }
 
@@ -1216,7 +1216,7 @@
   print(f<String>('hello', 'world'));
 }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 140, 6),
     ]);
   }
 
@@ -1229,7 +1229,7 @@
   G<B> m() { return null; }
 }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 60, 1),
     ]);
   }
 
@@ -1240,7 +1240,7 @@
 class G<E extends A> {}
 f() { return new G<B>(); }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 65, 1),
     ]);
   }
 
@@ -1252,7 +1252,7 @@
 class G<E extends B> {}
 f() { return new G<A>(); }
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 96, 1),
     ]);
   }
 
@@ -1263,7 +1263,7 @@
 typedef F<T extends A>();
 F<B> fff;
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
     ]);
   }
 
@@ -1274,7 +1274,7 @@
 class G<E extends A> {}
 f(G<B> g) {}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 50, 1),
     ]);
   }
 
@@ -1288,7 +1288,7 @@
 }
 ''', [
       error(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, 99, 4),
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 101, 1),
     ]);
   }
 
@@ -1300,7 +1300,7 @@
 class D<E extends A> {}
 C<D<B>> Var;
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 64, 1),
     ]);
   }
 
@@ -1312,7 +1312,7 @@
 class G<E extends A> {}
 class D<F extends G<B>> {}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 77, 1),
     ]);
   }
 
@@ -1323,7 +1323,7 @@
 class G<E extends A> {}
 G<B> g;
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 48, 1),
     ]);
   }
 
@@ -1334,7 +1334,7 @@
 class G<E extends A> {}
 class C extends Object with G<B>{}
 ''', [
-      error(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 76, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 176d24f..0c95349 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -5051,7 +5051,7 @@
 ''';
     await resolveTestUnit(code, noErrors: false);
     assertErrors(
-        testSource, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+        testSource, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
   }
 
   test_instantiateToBounds_class_error_instantiation_malbounded() async {
@@ -5066,7 +5066,7 @@
     await resolveTestUnit(code, noErrors: false);
     assertErrors(testSource, [
       StrongModeCode.COULD_NOT_INFER,
-      StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+      CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
     ]);
     expectIdentifierType('c =', 'C<List<dynamic>, List<List<dynamic>>>');
   }
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 25a512d..b795962 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier;
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/exception/exception.dart';
@@ -118,15 +119,61 @@
   /// The offset of the beginning of the error's region.
   final int length;
 
+  /// The list of context messages that are expected to be associated with the
+  /// error.
+  final List<ExpectedMessage> expectedMessages;
+
   /// Initialize a newly created error description.
-  ExpectedError(this.code, this.offset, this.length);
+  ExpectedError(this.code, this.offset, this.length,
+      {this.expectedMessages = const <ExpectedMessage>[]});
 
   /// Return `true` if the [error] matches this description of what it's
   /// expected to be.
   bool matches(AnalysisError error) {
-    return error.offset == offset &&
-        error.length == length &&
-        error.errorCode == code;
+    if (error.offset != offset ||
+        error.length != length ||
+        error.errorCode != code) {
+      return false;
+    }
+    List<DiagnosticMessage> contextMessages = error.contextMessages.toList();
+    contextMessages.sort((first, second) {
+      int result = first.filePath.compareTo(second.filePath);
+      if (result != 0) {
+        return result;
+      }
+      return second.offset - first.offset;
+    });
+    if (contextMessages.length != expectedMessages.length) {
+      return false;
+    }
+    for (int i = 0; i < expectedMessages.length; i++) {
+      if (!expectedMessages[i].matches(contextMessages[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+/// A description of a message that is expected to be reported with an error.
+class ExpectedMessage {
+  /// The path of the file with which the message is associated.
+  final String filePath;
+
+  /// The offset of the beginning of the error's region.
+  final int offset;
+
+  /// The offset of the beginning of the error's region.
+  final int length;
+
+  ExpectedMessage(this.filePath, this.offset, this.length);
+
+  /// Return `true` if the [message] matches this description of what it's
+  /// expected to be.
+  bool matches(DiagnosticMessage message) {
+    return message.filePath == filePath &&
+        message.offset == offset &&
+        message.length == length;
   }
 }
 
@@ -227,12 +274,30 @@
       buffer.writeln();
       buffer.writeln('To accept the current state, expect:');
       for (AnalysisError actual in errors) {
+        List<DiagnosticMessage> contextMessages = actual.contextMessages;
         buffer.write('  error(');
         buffer.write(actual.errorCode);
         buffer.write(', ');
         buffer.write(actual.offset);
         buffer.write(', ');
         buffer.write(actual.length);
+        if (contextMessages.isNotEmpty) {
+          buffer.write(', expectedMessages: [');
+          for (int i = 0; i < contextMessages.length; i++) {
+            DiagnosticMessage message = contextMessages[i];
+            if (i > 0) {
+              buffer.write(', ');
+            }
+            buffer.write('message(resourceProvider.convertPath(\'');
+            buffer.write(message.filePath);
+            buffer.write('\'), ');
+            buffer.write(message.offset);
+            buffer.write(', ');
+            buffer.write(message.length);
+            buffer.write(')');
+          }
+          buffer.write(']');
+        }
         buffer.writeln('),');
       }
       fail(buffer.toString());
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 511ce30..eca10d8 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -54,6 +54,7 @@
   InterfaceType get intType => typeProvider.intType;
   InterfaceType get iterableType => typeProvider.iterableType;
   InterfaceType get listType => typeProvider.listType;
+  DartType get neverType => typeProvider.neverType;
   DartType get nullType => typeProvider.nullType;
   InterfaceType get numType => typeProvider.numType;
   InterfaceType get objectType => typeProvider.objectType;
@@ -414,17 +415,66 @@
    *
    * The return type defaults to `void` if omitted.
    */
-  FunctionType _functionType(List<DartType> required,
-      {List<DartType> optional,
-      Map<String, DartType> named,
-      DartType returns}) {
-    if (returns == null) {
-      returns = voidType;
+  FunctionType _functionType({
+    List<TypeParameterElement> typeFormals,
+    List<DartType> required,
+    List<DartType> optional,
+    Map<String, DartType> named,
+    DartType returns,
+  }) {
+    if (optional != null && named != null) {
+      throw ArgumentError(
+        'Cannot have both optional positional and named parameters.',
+      );
     }
 
-    return ElementFactory.functionElement8(required, returns,
-            optional: optional, named: named)
-        .type;
+    var parameters = <ParameterElement>[];
+    if (required != null) {
+      for (var i = 0; i < required.length; ++i) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            'r$i',
+            required[i],
+            ParameterKind.REQUIRED,
+          ),
+        );
+      }
+    }
+    if (optional != null) {
+      for (var i = 0; i < optional.length; ++i) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            'p$i',
+            optional[i],
+            ParameterKind.POSITIONAL,
+          ),
+        );
+      }
+    }
+    if (named != null) {
+      for (var namedEntry in named.entries) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            namedEntry.key,
+            namedEntry.value,
+            ParameterKind.NAMED,
+          ),
+        );
+      }
+    }
+
+    return FunctionTypeImpl.synthetic(
+      returns ?? voidType,
+      typeFormals ?? const <TypeParameterElement>[],
+      parameters,
+    );
+  }
+
+  TypeParameterElementImpl _typeParameterElement(String name,
+      {DartType bound}) {
+    var element = TypeParameterElementImpl.synthetic(name);
+    element.bound = bound ?? typeProvider.objectType;
+    return element;
   }
 }
 
@@ -1205,92 +1255,170 @@
   }
 
   void test_functionsDifferentNamedTakeUnion() {
-    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
-    FunctionType type2 =
-        _functionType([], named: {'b': doubleType, 'c': stringType});
-    FunctionType expected =
-        _functionType([], named: {'a': intType, 'b': numType, 'c': stringType});
+    var type1 = _functionType(
+      named: {'a': intType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'b': doubleType, 'c': stringType},
+    );
+    var expected = _functionType(
+      named: {'a': intType, 'b': numType, 'c': stringType},
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsDifferentOptionalArityTakeMax() {
-    FunctionType type1 = _functionType([], optional: [intType]);
-    FunctionType type2 =
-        _functionType([], optional: [doubleType, stringType, objectType]);
-    FunctionType expected =
-        _functionType([], optional: [numType, stringType, objectType]);
+    var type1 = _functionType(
+      optional: [intType],
+    );
+    var type2 = _functionType(
+      required: [],
+      optional: [doubleType, stringType, objectType],
+    );
+    var expected = _functionType(
+      optional: [numType, stringType, objectType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsDifferentRequiredArityBecomeOptional() {
-    FunctionType type1 = _functionType([intType]);
-    FunctionType type2 = _functionType([intType, intType, intType]);
-    FunctionType expected =
-        _functionType([intType], optional: [intType, intType]);
+    var type1 = _functionType(
+      required: [intType],
+    );
+    var type2 = _functionType(
+      required: [intType, intType, intType],
+    );
+    var expected = _functionType(
+      required: [intType],
+      optional: [intType, intType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsFromDynamic() {
-    FunctionType type1 = _functionType([dynamicType]);
-    FunctionType type2 = _functionType([intType]);
-    FunctionType expected = _functionType([dynamicType]);
+    var type1 = _functionType(required: [dynamicType]);
+    var type2 = _functionType(required: [intType]);
+    var expected = _functionType(required: [dynamicType]);
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsGlbReturnType() {
-    FunctionType type1 = _functionType([], returns: intType);
-    FunctionType type2 = _functionType([], returns: numType);
-    FunctionType expected = _functionType([], returns: intType);
+    var type1 = _functionType(returns: intType);
+    var type2 = _functionType(returns: numType);
+    var expected = _functionType(returns: intType);
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubNamedParams() {
-    FunctionType type1 =
-        _functionType([], named: {'a': stringType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
-    FunctionType expected =
-        _functionType([], named: {'a': objectType, 'b': numType});
+    var type1 = _functionType(
+      named: {'a': stringType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'b': numType},
+    );
+    var expected = _functionType(
+      named: {'a': objectType, 'b': numType},
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubPositionalParams() {
-    FunctionType type1 = _functionType([], optional: [stringType, intType]);
-    FunctionType type2 = _functionType([], optional: [intType, numType]);
-    FunctionType expected = _functionType([], optional: [objectType, numType]);
+    var type1 = _functionType(
+      optional: [stringType, intType],
+    );
+    var type2 = _functionType(
+      optional: [intType, numType],
+    );
+    var expected = _functionType(
+      optional: [objectType, numType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubRequiredParams() {
-    FunctionType type1 = _functionType([stringType, intType, intType]);
-    FunctionType type2 = _functionType([intType, doubleType, numType]);
-    FunctionType expected = _functionType([objectType, numType, numType]);
+    var type1 = _functionType(
+      required: [stringType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType, doubleType, numType],
+    );
+    var expected = _functionType(
+      required: [objectType, numType, numType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsMixedOptionalAndRequiredBecomeOptional() {
-    FunctionType type1 = _functionType([intType, intType],
-        optional: [intType, intType, intType]);
-    FunctionType type2 = _functionType([intType], optional: [intType, intType]);
-    FunctionType expected = _functionType([intType],
-        optional: [intType, intType, intType, intType]);
+    var type1 = _functionType(
+      required: [intType, intType],
+      optional: [intType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType],
+      optional: [intType, intType],
+    );
+    var expected = _functionType(
+      required: [intType],
+      optional: [intType, intType, intType, intType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsReturnBottomIfMixOptionalAndNamed() {
     // Dart doesn't allow a function to have both optional and named parameters,
     // so if we would have synthethized that, pick bottom instead.
-    FunctionType type1 = _functionType([intType], named: {'a': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType});
+    var type1 = _functionType(
+      required: [intType],
+      named: {'a': intType},
+    );
+    var type2 = _functionType(
+      required: [],
+      named: {'a': intType},
+    );
     _checkGreatestLowerBound(type1, type2, bottomType);
   }
 
-  void test_functionsSameType() {
-    FunctionType type1 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType type2 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType expected = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
+  void test_functionsSameType_withNamed() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    _checkGreatestLowerBound(type1, type2, expected);
+  }
+
+  void test_functionsSameType_withOptional() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
@@ -1386,8 +1514,11 @@
       ElementFactory.typeParameterElement('T').type
     ];
     for (DartType type in types) {
-      _checkGreatestLowerBound(_functionType([], returns: voidType),
-          _functionType([], returns: type), _functionType([], returns: type));
+      _checkGreatestLowerBound(
+        _functionType(required: [], returns: voidType),
+        _functionType(required: [], returns: type),
+        _functionType(required: [], returns: type),
+      );
     }
   }
 }
@@ -1399,71 +1530,164 @@
     typeSystem = new Dart2TypeSystem(typeProvider);
   }
 
-  void test_functionsDifferentRequiredArity() {
-    FunctionType type1 = _functionType([intType, intType]);
-    FunctionType type2 = _functionType([intType, intType, intType]);
+  void test_differentRequiredArity() {
+    var type1 = _functionType(required: [intType, intType]);
+    var type2 = _functionType(required: [intType, intType, intType]);
     _checkLeastUpperBound(type1, type2, functionType);
   }
 
-  void test_functionsFuzzyArrows() {
-    FunctionType type1 = _functionType([dynamicType]);
-    FunctionType type2 = _functionType([intType]);
-    FunctionType expected = _functionType([intType]);
+  void test_fuzzyArrows() {
+    var type1 = _functionType(required: [dynamicType]);
+    var type2 = _functionType(required: [intType]);
+    var expected = _functionType(required: [intType]);
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbNamedParams() {
-    FunctionType type1 =
-        _functionType([], named: {'a': stringType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
-    FunctionType expected =
-        _functionType([], named: {'a': bottomType, 'b': intType});
+  void test_glbNamedParams() {
+    var type1 = _functionType(
+      named: {'a': stringType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'b': numType},
+    );
+    var expected = _functionType(
+      named: {'a': bottomType, 'b': intType},
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbPositionalParams() {
-    FunctionType type1 = _functionType([], optional: [stringType, intType]);
-    FunctionType type2 = _functionType([], optional: [intType, numType]);
-    FunctionType expected = _functionType([], optional: [bottomType, intType]);
+  void test_glbPositionalParams() {
+    var type1 = _functionType(
+      optional: [stringType, intType],
+    );
+    var type2 = _functionType(
+      optional: [intType, numType],
+    );
+    var expected = _functionType(
+      optional: [bottomType, intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbRequiredParams() {
-    FunctionType type1 = _functionType([stringType, intType, intType]);
-    FunctionType type2 = _functionType([intType, doubleType, numType]);
-    FunctionType expected = _functionType([bottomType, bottomType, intType]);
+  void test_glbRequiredParams() {
+    var type1 = _functionType(
+      required: [stringType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType, doubleType, numType],
+    );
+    var expected = _functionType(
+      required: [bottomType, bottomType, intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsIgnoreExtraNamedParams() {
-    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'c': intType});
-    FunctionType expected = _functionType([], named: {'a': intType});
+  void test_ignoreExtraNamedParams() {
+    var type1 = _functionType(
+      named: {'a': intType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'c': intType},
+    );
+    var expected = _functionType(
+      named: {'a': intType},
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsIgnoreExtraPositionalParams() {
-    FunctionType type1 =
-        _functionType([], optional: [intType, intType, stringType]);
-    FunctionType type2 = _functionType([], optional: [intType]);
-    FunctionType expected = _functionType([], optional: [intType]);
+  void test_ignoreExtraPositionalParams() {
+    var type1 = _functionType(
+      optional: [intType, intType, stringType],
+    );
+    var type2 = _functionType(
+      optional: [intType],
+    );
+    var expected = _functionType(
+      optional: [intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsLubReturnType() {
-    FunctionType type1 = _functionType([], returns: intType);
-    FunctionType type2 = _functionType([], returns: doubleType);
-    FunctionType expected = _functionType([], returns: numType);
+  void test_lubReturnType() {
+    var type1 = _functionType(returns: intType);
+    var type2 = _functionType(returns: doubleType);
+    var expected = _functionType(returns: numType);
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsSameType() {
-    FunctionType type1 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType type2 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType expected = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
+  void test_sameType_withNamed() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_sameType_withOptional() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_typeFormals_differentBounds() {
+    var T1 = _typeParameterElement('T1', bound: intType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var T2 = _typeParameterElement('T2', bound: doubleType);
+    var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+    _checkLeastUpperBound(type1, type2, functionType);
+  }
+
+  void test_typeFormals_differentNumber() {
+    var T1 = _typeParameterElement('T1', bound: numType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var type2 = _functionType(returns: intType);
+
+    _checkLeastUpperBound(type1, type2, functionType);
+  }
+
+  void test_typeFormals_sameBounds() {
+    var T1 = _typeParameterElement('T1', bound: numType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var T2 = _typeParameterElement('T2', bound: numType);
+    var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+    var TE = _typeParameterElement('T', bound: numType);
+    var expected = _functionType(typeFormals: [TE], returns: TE.type);
+
     _checkLeastUpperBound(type1, type2, expected);
   }
 }
@@ -1566,32 +1790,38 @@
   }
 
   void test_nestedFunctionsLubInnerParamTypes() {
-    FunctionType type1 = _functionType([
-      _functionType([stringType, intType, intType])
-    ]);
-    FunctionType type2 = _functionType([
-      _functionType([intType, doubleType, numType])
-    ]);
-    FunctionType expected = _functionType([
-      _functionType([objectType, numType, numType])
-    ]);
+    var type1 = _functionType(
+      required: [
+        _functionType(required: [stringType, intType, intType])
+      ],
+    );
+    var type2 = _functionType(
+      required: [
+        _functionType(required: [intType, doubleType, numType])
+      ],
+    );
+    var expected = _functionType(
+      required: [
+        _functionType(required: [objectType, numType, numType])
+      ],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
   void test_nestedNestedFunctionsGlbInnermostParamTypes() {
-    FunctionType type1 = _functionType([
-      _functionType([
-        _functionType([stringType, intType, intType])
+    FunctionType type1 = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [stringType, intType, intType])
       ])
     ]);
-    FunctionType type2 = _functionType([
-      _functionType([
-        _functionType([intType, doubleType, numType])
+    FunctionType type2 = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [intType, doubleType, numType])
       ])
     ]);
-    FunctionType expected = _functionType([
-      _functionType([
-        _functionType([bottomType, bottomType, intType])
+    FunctionType expected = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [bottomType, bottomType, intType])
       ])
     ]);
     _checkLeastUpperBound(type1, type2, expected);
@@ -1840,9 +2070,10 @@
     ];
     for (DartType type in types) {
       _checkLeastUpperBound(
-          _functionType([], returns: voidType),
-          _functionType([], returns: type),
-          _functionType([], returns: voidType));
+        _functionType(returns: voidType),
+        _functionType(returns: type),
+        _functionType(returns: voidType),
+      );
     }
   }
 }
@@ -1878,6 +2109,46 @@
     _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
   }
 
+  @failingTest
+  void test_futureOr_topTypes() {
+    var objectStar =
+        (objectType as TypeImpl).withNullability(NullabilitySuffix.star);
+    var objectQuestion =
+        (objectType as TypeImpl).withNullability(NullabilitySuffix.question);
+    var futureOrObject = futureOrType.instantiate([objectType]);
+    var futureOrObjectStar = futureOrType.instantiate([objectStar]);
+    var futureOrObjectQuestion = futureOrType.instantiate([objectQuestion]);
+    var futureOrStarObject =
+        (futureOrObject as TypeImpl).withNullability(NullabilitySuffix.star);
+    var futureOrQuestionObject = (futureOrObject as TypeImpl)
+        .withNullability(NullabilitySuffix.question);
+    var futureOrStarObjectStar = (futureOrObjectStar as TypeImpl)
+        .withNullability(NullabilitySuffix.star);
+    var futureOrQuestionObjectStar = (futureOrObjectStar as TypeImpl)
+        .withNullability(NullabilitySuffix.question);
+    var futureOrStarObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+        .withNullability(NullabilitySuffix.star);
+    var futureOrQuestionObjectQuestion = (futureOrObjectQuestion as TypeImpl)
+        .withNullability(NullabilitySuffix.question);
+
+    //FutureOr<Object> <: FutureOr*<Object?>
+    _checkGroups(futureOrObject, equivalents: [
+      objectStar,
+      futureOrObjectStar,
+      futureOrStarObject,
+      futureOrStarObjectStar,
+      objectType
+    ], subtypes: [], supertypes: [
+      objectQuestion,
+      futureOrQuestionObject,
+      futureOrObjectQuestion,
+      futureOrQuestionObject,
+      futureOrQuestionObjectStar,
+      futureOrStarObjectQuestion,
+      futureOrQuestionObjectQuestion
+    ]);
+  }
+
   void test_int_nullableTypes() {
     List<DartType> equivalents = <DartType>[
       intType,
@@ -2458,56 +2729,222 @@
 
 @reflectiveTest
 class TypeSystemTest extends AbstractTypeSystemTest {
-  DartType get futureOrWithNoneType =>
-      typeProvider.futureOrType.instantiate([noneType]);
+  DartType get functionClassTypeNone {
+    return InterfaceTypeImpl.explicit(
+      typeProvider.functionType.element,
+      const <DartType>[],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
 
-  DartType get futureOrWithQuestionType =>
-      typeProvider.futureOrType.instantiate([questionType]);
+  DartType get functionClassTypeQuestion {
+    return InterfaceTypeImpl.explicit(
+      typeProvider.functionType.element,
+      const <DartType>[],
+      nullabilitySuffix: NullabilitySuffix.question,
+    );
+  }
 
-  DartType get futureOrWithStarType =>
-      typeProvider.futureOrType.instantiate([starType]);
+  DartType get functionClassTypeStar {
+    return InterfaceTypeImpl.explicit(
+      typeProvider.functionType.element,
+      const <DartType>[],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+  }
 
   DartType get noneType => (typeProvider.stringType as TypeImpl)
       .withNullability(NullabilitySuffix.none);
 
+  FunctionType get nothingToVoidFunctionTypeNone {
+    return FunctionTypeImpl.synthetic(
+      voidType,
+      const <TypeParameterElement>[],
+      const <ParameterElement>[],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  FunctionType get nothingToVoidFunctionTypeQuestion {
+    return FunctionTypeImpl.synthetic(
+      voidType,
+      const <TypeParameterElement>[],
+      const <ParameterElement>[],
+      nullabilitySuffix: NullabilitySuffix.question,
+    );
+  }
+
+  FunctionType get nothingToVoidFunctionTypeStar {
+    return FunctionTypeImpl.synthetic(
+      voidType,
+      const <TypeParameterElement>[],
+      const <ParameterElement>[],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+  }
+
   DartType get questionType => (typeProvider.stringType as TypeImpl)
       .withNullability(NullabilitySuffix.question);
 
   DartType get starType => (typeProvider.stringType as TypeImpl)
       .withNullability(NullabilitySuffix.star);
 
+  DartType futureOrTypeNone({@required DartType argument}) {
+    var element = typeProvider.futureOrType.element;
+    return InterfaceTypeImpl.explicit(
+      element,
+      <DartType>[argument],
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
+  }
+
+  DartType futureOrTypeQuestion({@required DartType argument}) {
+    var element = typeProvider.futureOrType.element;
+    return InterfaceTypeImpl.explicit(
+      element,
+      <DartType>[argument],
+      nullabilitySuffix: NullabilitySuffix.question,
+    );
+  }
+
+  DartType futureOrTypeStar({@required DartType argument}) {
+    var element = typeProvider.futureOrType.element;
+    return InterfaceTypeImpl.explicit(
+      element,
+      <DartType>[argument],
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
+  }
+
   test_isNonNullable_dynamic() {
     expect(typeSystem.isNonNullable(dynamicType), false);
   }
 
-  test_isNonNullable_futureOr_noneArg() {
-    expect(typeSystem.isNonNullable(futureOrWithNoneType), true);
+  test_isNonNullable_function_none() {
+    expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeNone), true);
   }
 
-  test_isNonNullable_futureOr_questionArg() {
-    expect(typeSystem.isNonNullable(futureOrWithQuestionType), true);
+  test_isNonNullable_function_question() {
+    expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeQuestion), false);
   }
 
-  test_isNonNullable_futureOr_starArg() {
-    expect(typeSystem.isNonNullable(futureOrWithStarType), true);
+  test_isNonNullable_function_star() {
+    expect(typeSystem.isNonNullable(nothingToVoidFunctionTypeStar), true);
   }
 
-  test_isNonNullable_none() {
+  test_isNonNullable_functionClass_none() {
+    expect(typeSystem.isNonNullable(functionClassTypeNone), true);
+  }
+
+  test_isNonNullable_functionClass_question() {
+    expect(typeSystem.isNonNullable(functionClassTypeQuestion), false);
+  }
+
+  test_isNonNullable_functionClass_star() {
+    expect(typeSystem.isNonNullable(functionClassTypeStar), true);
+  }
+
+  test_isNonNullable_futureOr_noneArgument_none() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeNone(argument: noneType),
+      ),
+      true,
+    );
+  }
+
+  test_isNonNullable_futureOr_noneArgument_question() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeQuestion(argument: noneType),
+      ),
+      false,
+    );
+  }
+
+  test_isNonNullable_futureOr_noneArgument_star() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeStar(argument: noneType),
+      ),
+      true,
+    );
+  }
+
+  test_isNonNullable_futureOr_questionArgument_none() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeNone(argument: questionType),
+      ),
+      false,
+    );
+  }
+
+  test_isNonNullable_futureOr_questionArgument_question() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeQuestion(argument: questionType),
+      ),
+      false,
+    );
+  }
+
+  test_isNonNullable_futureOr_questionArgument_star() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeStar(argument: questionType),
+      ),
+      false,
+    );
+  }
+
+  test_isNonNullable_futureOr_starArgument_none() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeNone(argument: starType),
+      ),
+      true,
+    );
+  }
+
+  test_isNonNullable_futureOr_starArgument_question() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeStar(argument: questionType),
+      ),
+      false,
+    );
+  }
+
+  test_isNonNullable_futureOr_starArgument_star() {
+    expect(
+      typeSystem.isNonNullable(
+        futureOrTypeStar(argument: starType),
+      ),
+      true,
+    );
+  }
+
+  test_isNonNullable_interface_none() {
     expect(typeSystem.isNonNullable(noneType), true);
   }
 
+  test_isNonNullable_interface_question() {
+    expect(typeSystem.isNonNullable(questionType), false);
+  }
+
+  test_isNonNullable_interface_star() {
+    expect(typeSystem.isNonNullable(starType), true);
+  }
+
+  test_isNonNullable_never() {
+    expect(typeSystem.isNonNullable(neverType), true);
+  }
+
   test_isNonNullable_null() {
     expect(typeSystem.isNonNullable(nullType), false);
   }
 
-  test_isNonNullable_question() {
-    expect(typeSystem.isNonNullable(questionType), false);
-  }
-
-  test_isNonNullable_star() {
-    expect(typeSystem.isNonNullable(starType), true);
-  }
-
   test_isNonNullable_typeParameter_noneBound_none() {
     expect(
       typeSystem.isNonNullable(
@@ -2561,34 +2998,131 @@
     expect(typeSystem.isNullable(dynamicType), true);
   }
 
-  test_isNullable_futureOr_noneArg() {
-    expect(typeSystem.isNullable(futureOrWithNoneType), true);
+  test_isNullable_function_none() {
+    expect(typeSystem.isNullable(nothingToVoidFunctionTypeNone), false);
   }
 
-  test_isNullable_futureOr_questionArg() {
-    expect(typeSystem.isNullable(futureOrWithQuestionType), true);
+  test_isNullable_function_question() {
+    expect(typeSystem.isNullable(nothingToVoidFunctionTypeQuestion), true);
   }
 
-  test_isNullable_futureOr_starArg() {
-    expect(typeSystem.isNullable(futureOrWithStarType), true);
+  test_isNullable_function_star() {
+    expect(typeSystem.isNullable(nothingToVoidFunctionTypeStar), false);
   }
 
-  test_isNullable_none() {
+  test_isNullable_functionClass_none() {
+    expect(typeSystem.isNullable(functionClassTypeNone), false);
+  }
+
+  test_isNullable_functionClass_question() {
+    expect(typeSystem.isNullable(functionClassTypeQuestion), true);
+  }
+
+  test_isNullable_functionClass_star() {
+    expect(typeSystem.isNullable(functionClassTypeStar), false);
+  }
+
+  test_isNullable_futureOr_noneArgument_none() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeNone(argument: noneType),
+      ),
+      false,
+    );
+  }
+
+  test_isNullable_futureOr_noneArgument_question() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeQuestion(argument: noneType),
+      ),
+      true,
+    );
+  }
+
+  test_isNullable_futureOr_noneArgument_star() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeStar(argument: noneType),
+      ),
+      false,
+    );
+  }
+
+  test_isNullable_futureOr_questionArgument_none() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeNone(argument: questionType),
+      ),
+      true,
+    );
+  }
+
+  test_isNullable_futureOr_questionArgument_question() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeQuestion(argument: questionType),
+      ),
+      true,
+    );
+  }
+
+  test_isNullable_futureOr_questionArgument_star() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeStar(argument: questionType),
+      ),
+      true,
+    );
+  }
+
+  test_isNullable_futureOr_starArgument_none() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeNone(argument: starType),
+      ),
+      false,
+    );
+  }
+
+  test_isNullable_futureOr_starArgument_question() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeQuestion(argument: starType),
+      ),
+      true,
+    );
+  }
+
+  test_isNullable_futureOr_starArgument_star() {
+    expect(
+      typeSystem.isNullable(
+        futureOrTypeStar(argument: starType),
+      ),
+      false,
+    );
+  }
+
+  test_isNullable_interface_none() {
     expect(typeSystem.isNullable(noneType), false);
   }
 
+  test_isNullable_interface_question() {
+    expect(typeSystem.isNullable(questionType), true);
+  }
+
+  test_isNullable_interface_star() {
+    expect(typeSystem.isNullable(starType), false);
+  }
+
+  test_isNullable_never() {
+    expect(typeSystem.isNullable(neverType), false);
+  }
+
   test_isNullable_null() {
     expect(typeSystem.isNullable(nullType), true);
   }
 
-  test_isNullable_question() {
-    expect(typeSystem.isNullable(questionType), true);
-  }
-
-  test_isNullable_star() {
-    expect(typeSystem.isNullable(starType), true);
-  }
-
   test_isNullable_typeParameter_noneBound_none() {
     expect(
       typeSystem.isNullable(
@@ -2630,7 +3164,7 @@
       typeSystem.isNullable(
         typeParameterTypeStar(bound: starType),
       ),
-      true,
+      false,
     );
   }
 
@@ -2642,17 +3176,35 @@
     expect(typeSystem.isPotentiallyNonNullable(dynamicType), false);
   }
 
-  test_isPotentiallyNonNullable_futureOr_noneArg() {
-    expect(typeSystem.isPotentiallyNonNullable(futureOrWithNoneType), false);
-  }
-
-  test_isPotentiallyNonNullable_futureOr_questionArg() {
+  test_isPotentiallyNonNullable_futureOr_noneArgument_none() {
     expect(
-        typeSystem.isPotentiallyNonNullable(futureOrWithQuestionType), false);
+      typeSystem.isPotentiallyNonNullable(
+        futureOrTypeNone(argument: noneType),
+      ),
+      true,
+    );
   }
 
-  test_isPotentiallyNonNullable_futureOr_starArg() {
-    expect(typeSystem.isPotentiallyNonNullable(futureOrWithStarType), false);
+  test_isPotentiallyNonNullable_futureOr_questionArgument_none() {
+    expect(
+      typeSystem.isPotentiallyNonNullable(
+        futureOrTypeNone(argument: questionType),
+      ),
+      false,
+    );
+  }
+
+  test_isPotentiallyNonNullable_futureOr_starArgument_none() {
+    expect(
+      typeSystem.isPotentiallyNonNullable(
+        futureOrTypeNone(argument: starType),
+      ),
+      true,
+    );
+  }
+
+  test_isPotentiallyNonNullable_never() {
+    expect(typeSystem.isPotentiallyNonNullable(neverType), true);
   }
 
   test_isPotentiallyNonNullable_none() {
@@ -2668,7 +3220,7 @@
   }
 
   test_isPotentiallyNonNullable_star() {
-    expect(typeSystem.isPotentiallyNonNullable(starType), false);
+    expect(typeSystem.isPotentiallyNonNullable(starType), true);
   }
 
   test_isPotentiallyNonNullable_void() {
@@ -2679,16 +3231,35 @@
     expect(typeSystem.isPotentiallyNullable(dynamicType), true);
   }
 
-  test_isPotentiallyNullable_futureOr_noneArg() {
-    expect(typeSystem.isPotentiallyNullable(futureOrWithNoneType), false);
+  test_isPotentiallyNullable_futureOr_noneArgument_none() {
+    expect(
+      typeSystem.isPotentiallyNullable(
+        futureOrTypeNone(argument: noneType),
+      ),
+      false,
+    );
   }
 
-  test_isPotentiallyNullable_futureOr_questionArg() {
-    expect(typeSystem.isPotentiallyNullable(futureOrWithQuestionType), false);
+  test_isPotentiallyNullable_futureOr_questionArgument_none() {
+    expect(
+      typeSystem.isPotentiallyNullable(
+        futureOrTypeNone(argument: questionType),
+      ),
+      true,
+    );
   }
 
-  test_isPotentiallyNullable_futureOr_starArg() {
-    expect(typeSystem.isPotentiallyNullable(futureOrWithStarType), false);
+  test_isPotentiallyNullable_futureOr_starArgument_none() {
+    expect(
+      typeSystem.isPotentiallyNullable(
+        futureOrTypeNone(argument: starType),
+      ),
+      false,
+    );
+  }
+
+  test_isPotentiallyNullable_never() {
+    expect(typeSystem.isPotentiallyNullable(neverType), false);
   }
 
   test_isPotentiallyNullable_none() {
@@ -2715,23 +3286,29 @@
     expect(bound, isNotNull);
     var element = TypeParameterElementImpl.synthetic('T');
     element.bound = bound;
-    return TypeParameterTypeImpl(element,
-        nullabilitySuffix: NullabilitySuffix.none);
+    return TypeParameterTypeImpl(
+      element,
+      nullabilitySuffix: NullabilitySuffix.none,
+    );
   }
 
   DartType typeParameterTypeQuestion({@required DartType bound}) {
     expect(bound, isNotNull);
     var element = TypeParameterElementImpl.synthetic('T');
     element.bound = bound;
-    return TypeParameterTypeImpl(element,
-        nullabilitySuffix: NullabilitySuffix.question);
+    return TypeParameterTypeImpl(
+      element,
+      nullabilitySuffix: NullabilitySuffix.question,
+    );
   }
 
   DartType typeParameterTypeStar({@required DartType bound}) {
     expect(bound, isNotNull);
     var element = TypeParameterElementImpl.synthetic('T');
     element.bound = bound;
-    return TypeParameterTypeImpl(element,
-        nullabilitySuffix: NullabilitySuffix.star);
+    return TypeParameterTypeImpl(
+      element,
+      nullabilitySuffix: NullabilitySuffix.star,
+    );
   }
 }
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 3fec6a9..4bb1920 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -8,6 +8,7 @@
 
 void main() {
   test("parses a valid compilation unit successfully", () {
+    // ignore: deprecated_member_use_from_same_package
     var unit = parseCompilationUnit("void main() => print('Hello, world!');");
     expect(unit.toString(), equals("void main() => print('Hello, world!');"));
   });
@@ -24,9 +25,11 @@
 
     test('with errors suppressed', () {
       checkCompilationUnit(
+          // ignore: deprecated_member_use_from_same_package
           parseCompilationUnit(contents, suppressErrors: true));
     });
     test('with errors enabled', () {
+      // ignore: deprecated_member_use_from_same_package
       checkCompilationUnit(parseCompilationUnit(contents));
     });
   });
@@ -45,15 +48,18 @@
 
     test('with errors suppressed', () {
       checkCompilationUnit(
+          // ignore: deprecated_member_use_from_same_package
           parseCompilationUnit(contents, suppressErrors: true));
     });
     test('with errors enabled', () {
+      // ignore: deprecated_member_use_from_same_package
       checkCompilationUnit(parseCompilationUnit(contents));
     });
   });
 
   test("throws errors for an invalid compilation unit", () {
     expect(() {
+      // ignore: deprecated_member_use_from_same_package
       parseCompilationUnit("void main() => print('Hello, world!')",
           name: 'test.dart');
     }, throwsA(predicate((error) {
@@ -64,6 +70,7 @@
 
   test("defaults to '<unknown source>' if no name is provided", () {
     expect(() {
+      // ignore: deprecated_member_use_from_same_package
       parseCompilationUnit("void main() => print('Hello, world!')");
     }, throwsA(predicate((error) {
       return error is AnalyzerErrorGroup &&
@@ -74,12 +81,14 @@
   });
 
   test("allows you to specify whether or not to parse function bodies", () {
+    // ignore: deprecated_member_use_from_same_package
     var unit = parseCompilationUnit("void main() => print('Hello, world!');",
         parseFunctionBodies: false);
     expect(unit.toString(), equals("void main();"));
   });
 
   test("allows you to specify whether or not to parse function bodies 2", () {
+    // ignore: deprecated_member_use_from_same_package
     var unit = parseCompilationUnit("void main() { print('Hello, world!'); }",
         parseFunctionBodies: false);
     expect(unit.toString(), equals("void main();"));
diff --git a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
index 8222c70..f7562ed 100644
--- a/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/unlinked_api_signature_test.dart
@@ -226,11 +226,11 @@
   test_class_field_withType() {
     assertSameSignature(r'''
 class C {
-  int a = 1, b, c = 3;
+  int a = 1;
 }
 ''', r'''
 class C {
-  int a = 0, b = 2, c;
+  int a = 2;
 }
 ''');
   }
@@ -744,11 +744,11 @@
   test_mixin_field_withType() {
     assertSameSignature(r'''
 mixin M {
-  int a = 1, b, c = 3;
+  int a = 1;
 }
 ''', r'''
 mixin M {
-  int a = 0, b = 2, c;
+  int a = 2;
 }
 ''');
   }
@@ -819,9 +819,9 @@
 
   test_topLevelVariable_withType() {
     assertSameSignature(r'''
-int a = 1, b, c = 3;
+int a = 1;
 ''', r'''
-int a = 0, b = 2, c;
+int a = 2;
 ''');
   }
 
@@ -841,6 +841,22 @@
 ''');
   }
 
+  test_topLevelVariable_withType_initializer_add() {
+    assertNotSameSignature(r'''
+int a;
+''', r'''
+int a = 1;
+''');
+  }
+
+  test_topLevelVariable_withType_initializer_remove() {
+    assertNotSameSignature(r'''
+int a = 1;
+''', r'''
+int a;
+''');
+  }
+
   test_typedef_generic_parameters_type() {
     assertNotSameSignature(r'''
 typedef F = void Function(int);
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 00cf65e..0a8e03d 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -1755,6 +1755,46 @@
             ]));
   }
 
+  void test_visitExtensionOverride_prefixedName_noTypeArgs() {
+    _assertSource(
+        'p.E(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier5('p', 'E'),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_prefixedName_typeArgs() {
+    _assertSource(
+        'p.E<A>(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier5('p', 'E'),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('A')]),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_simpleName_noTypeArgs() {
+    _assertSource(
+        'E(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier3('E'),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_simpleName_typeArgs() {
+    _assertSource(
+        'E<A>(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier3('E'),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('A')]),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
   void test_visitFieldDeclaration_instance() {
     _assertSource(
         "var a;",
@@ -4521,6 +4561,46 @@
             ]));
   }
 
+  void test_visitExtensionOverride_prefixedName_noTypeArgs() {
+    _assertSource(
+        'p.E(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier5('p', 'E'),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_prefixedName_typeArgs() {
+    _assertSource(
+        'p.E<A>(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier5('p', 'E'),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('A')]),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_simpleName_noTypeArgs() {
+    _assertSource(
+        'E(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier3('E'),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
+  void test_visitExtensionOverride_simpleName_typeArgs() {
+    _assertSource(
+        'E<A>(o)',
+        AstTestFactory.extensionOverride(
+            extensionName: AstTestFactory.identifier3('E'),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('A')]),
+            argumentList: AstTestFactory.argumentList(
+                [AstTestFactory.identifier3('o')])));
+  }
+
   void test_visitFieldDeclaration_instance() {
     _assertSource(
         "var a;",
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
index 6a39734..8cd4944 100644
--- a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -2,1488 +2,204 @@
 // 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:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/type_system.dart';
-import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/ast_data_extractor.dart';
+import 'package:front_end/src/testing/id.dart' show ActualData, Id;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../util/id_equivalence_helper.dart';
 import 'driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(NullableFlowTest);
-    defineReflectiveTests(DefiniteAssignmentFlowTest);
     defineReflectiveTests(ReachableFlowTest);
-    defineReflectiveTests(TypePromotionFlowTest);
   });
 }
 
-@reflectiveTest
-class DefiniteAssignmentFlowTest extends DriverResolutionTest {
-  final List<LocalVariableElement> readBeforeWritten = [];
+class FlowTestBase extends DriverResolutionTest {
+  FlowAnalysisResult flowResult;
 
-  /// Assert that only local variables with the given names are marked as read
-  /// before being written.  All the other local variables are implicitly
-  /// considered definitely assigned.
-  void assertReadBeforeWritten(
-      [String name1, String name2, String name3, String name4]) {
-    var expected = [name1, name2, name3, name4]
-        .where((i) => i != null)
-        .map((name) => findElement.localVar(name))
-        .toList();
-    expect(readBeforeWritten, unorderedEquals(expected));
-  }
-
-  test_assignment_leftExpression() async {
-    await trackCode(r'''
-void f() {
-  List<int> v;
-  v[0] = (v = [1, 2])[1];
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_assignment_leftLocal_compound() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v += 1;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_assignment_leftLocal_compound_assignInRight() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v += (v = v);
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_assignment_leftLocal_pure_eq() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v = 0;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_assignment_leftLocal_pure_eq_self() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v = v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_assignment_leftLocal_pure_questionEq() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v ??= 0;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_assignment_leftLocal_pure_questionEq_self() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  v ??= v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_binaryExpression_ifNull_left() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  (v = 0) ?? 0;
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_binaryExpression_ifNull_right() async {
-    await trackCode(r'''
-void f(int a) {
-  int v;
-  a ?? (v = 0);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_binaryExpression_logicalAnd_left() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  ((v = 0) >= 0) && c;
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_binaryExpression_logicalAnd_right() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  c && ((v = 0) >= 0);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_binaryExpression_logicalOr_left() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  ((v = 0) >= 0) || c;
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_binaryExpression_logicalOr_right() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  c || ((v = 0) >= 0);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_binaryExpression_plus_left() async {
-    await trackCode(r'''
-main() {
-  int v;
-  (v = 0) + 1;
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_binaryExpression_plus_right() async {
-    await trackCode(r'''
-main() {
-  int v;
-  1 + (v = 0);
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_conditional_both() async {
-    await trackCode(r'''
-f(bool v) {
-  int v;
-  b ? (v = 1) : (v = 2);
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_conditional_else() async {
-    await trackCode(r'''
-f(bool v) {
-  int v;
-  b ? 1 : (v = 2);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_conditional_then() async {
-    await trackCode(r'''
-f(bool v) {
-  int v;
-  b ? (v = 1) : 2;
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_conditionalExpression_condition() async {
-    await trackCode(r'''
-main() {
-  int v;
-  (v = 0) >= 0 ? 1 : 2;
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_doWhile_break_afterAssignment() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  do {
-    v = 0;
-    v;
-    if (b) break;
-  } while (b);
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_doWhile_break_beforeAssignment() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  do {
-    if (b) break;
-    v = 0;
-  } while (b);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_doWhile_breakOuterFromInner() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2, v3;
-  L1: do {
-    do {
-      v1 = 0;
-      if (b) break L1;
-      v2 = 0;
-      v3 = 0;
-    } while (b);
-    v2;
-  } while (b);
-  v1;
-  v3;
-}
-''');
-    assertReadBeforeWritten('v3');
-  }
-
-  test_doWhile_condition() async {
-    await trackCode(r'''
-void f() {
-  int v1, v2;
-  do {
-    v1; // assigned in the condition, but not yet
-  } while ((v1 = 0) + (v2 = 0) >= 0);
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1');
-  }
-
-  test_doWhile_condition_break() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  do {
-    if (b) break;
-  } while ((v = 0) >= 0);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_doWhile_condition_break_continue() async {
-    await trackCode(r'''
-void f(bool b1, b2) {
-  int v1, v2, v3, v4, v5, v6;
-  do {
-    v1 = 0; // visible outside, visible to the condition
-    if (b1) break;
-    v2 = 0; // not visible outside, visible to the condition
-    v3 = 0; // not visible outside, visible to the condition
-    if (b2) continue;
-    v4 = 0; // not visible
-    v5 = 0; // not visible
-  } while ((v6 = v1 + v2 + v4) == 0); // has break => v6 is not visible outside
-  v1;
-  v3;
-  v5;
-  v6;
-}
-''');
-    assertReadBeforeWritten('v3', 'v4', 'v5', 'v6');
-  }
-
-  test_doWhile_condition_continue() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2, v3, v4;
-  do {
-    v1 = 0; // visible outside, visible to the condition
-    if (b) continue;
-    v2 = 0; // not visible
-    v3 = 0; // not visible
-  } while ((v4 = v1 + v2) == 0); // no break => v4 visible outside
-  v1;
-  v3;
-  v4;
-}
-''');
-    assertReadBeforeWritten('v2', 'v3');
-  }
-
-  test_doWhile_continue_beforeAssignment() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  do {
-    if (b) continue;
-    v = 0;
-  } while (b);
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_doWhile_true_assignInBreak() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  do {
-    if (b) {
-      v = 0;
-      break;
-    }
-  } while (true);
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_for_body() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  for (; b;) {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_for_break() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (; b;) {
-    v1 = 0;
-    if (b) break;
-    v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1', 'v2');
-  }
-
-  test_for_break_updaters() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (; b; v1 + v2) {
-    v1 = 0;
-    if (b) break;
-    v2 = 0;
-  }
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_for_condition() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  for (; (v = 0) >= 0;) {
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_for_continue() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (; b;) {
-    v1 = 0;
-    if (b) continue;
-    v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1', 'v2');
-  }
-
-  test_for_continue_updaters() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (; b; v1 + v2) {
-    v1 = 0;
-    if (b) continue;
-    v2 = 0;
-  }
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_for_initializer_expression() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  for (v = 0;;) {
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_for_initializer_variable() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  for (var t = (v = 0);;) {
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_for_updaters() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2, v3, v4;
-  for (; b; v1 = 0, v2 = 0, v3 = 0, v4) {
-    v1;
-  }
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1', 'v2', 'v4');
-  }
-
-  test_for_updaters_afterBody() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  for (; b; v) {
-    v = 0;
-  }
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_forEach() async {
-    await trackCode(r'''
-void f() {
-  int v1, v2;
-  for (var _ in (v1 = [0, 1, 2])) {
-    v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_forEach_break() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (var _ in [0, 1, 2]) {
-    v1 = 0;
-    if (b) break;
-    v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1', 'v2');
-  }
-
-  test_forEach_continue() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  for (var _ in [0, 1, 2]) {
-    v1 = 0;
-    if (b) continue;
-    v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v1', 'v2');
-  }
-
-  test_functionExpression_closure_read() async {
-    await trackCode(r'''
-void f() {
-  int v1, v2;
-  
-  v1 = 0;
-  
-  [0, 1, 2].forEach((t) {
-    v1;
-    v2;
-  });
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_functionExpression_closure_write() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  
-  [0, 1, 2].forEach((t) {
-    v = t;
-  });
-
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_functionExpression_localFunction_local() async {
-    await trackCode(r'''
-void f() {
-  int v;
-
-  v = 0;
-
-  void f() {
-    int v; // 1
-    v;
-  }
-}
-''');
-    var localV = findNode.simple('v; // 1').staticElement;
-    expect(readBeforeWritten, unorderedEquals([localV]));
-  }
-
-  test_functionExpression_localFunction_local2() async {
-    await trackCode(r'''
-void f() {
-  int v1;
-
-  v1 = 0;
-
-  void f() {
-    int v2, v3;
-    v2 = 0;
-    v1;
-    v2;
-    v3;
-  }
-}
-''');
-    assertReadBeforeWritten('v3');
-  }
-
-  test_functionExpression_localFunction_read() async {
-    await trackCode(r'''
-void f() {
-  int v1, v2, v3;
-
-  v1 = 0;
-
-  void f() {
-    v1;
-    v2;
-  }
-
-  v2 = 0;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_functionExpression_localFunction_write() async {
-    await trackCode(r'''
-void f() {
-  int v;
-
-  void f() {
-    v = 0;
-  }
-
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_if_condition() async {
-    await trackCode(r'''
-main() {
-  int v;
-  if ((v = 0) >= 0) {
-    v;
-  } else {
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_false() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  if (false) {
-    // not assigned
-  } else {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_logicalAnd_else() async {
-    await trackCode(r'''
-void f(bool b, int i) {
-  int v;
-  if (b && (v = i) > 0) {
-  } else {
-    v;
-  }
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_if_condition_logicalAnd_then() async {
-    await trackCode(r'''
-void f(bool b, int i) {
-  int v;
-  if (b && (v = i) > 0) {
-    v;
-  }
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_logicalOr_else() async {
-    await trackCode(r'''
-void f(bool b, int i) {
-  int v;
-  if (b || (v = i) > 0) {
-  } else {
-    v;
-  }
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_logicalOr_then() async {
-    await trackCode(r'''
-void f(bool b, int i) {
-  int v;
-  if (b || (v = i) > 0) {
-    v;
-  } else {
-  }
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_if_condition_notFalse() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  if (!false) {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_notTrue() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  if (!true) {
-    // not assigned
-  } else {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_condition_true() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  if (true) {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_then() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  if (c) {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_if_thenElse_all() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  if (c) {
-    v = 0;
-    v;
-  } else {
-    v = 0;
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_if_thenElse_else() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  if (c) {
-    // not assigned
-  } else {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_if_thenElse_then() async {
-    await trackCode(r'''
-main(bool c) {
-  int v;
-  if (c) {
-    v = 0;
-  } else {
-    // not assigned
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_switch_case1_default() async {
-    await trackCode(r'''
-void f(int e) {
-  int v;
-  switch (e) {
-    case 1:
-      v = 0;
-      break;
-    case 2:
-      // not assigned
-      break;
-    default:
-      v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_switch_case2_default() async {
-    await trackCode(r'''
-void f(int e) {
-  int v1, v2;
-  switch (e) {
-    case 1:
-      v1 = 0;
-      v2 = 0;
-      v1;
-      break;
-    default:
-      v1 = 0;
-      v1;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_switch_case_default_break() async {
-    await trackCode(r'''
-void f(bool b, int e) {
-  int v1, v2;
-  switch (e) {
-    case 1:
-      v1 = 0;
-      if (b) break;
-      v2 = 0;
-      break;
-    default:
-      v1 = 0;
-      if (b) break;
-      v2 = 0;
-  }
-  v1;
-  v2;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_switch_case_default_continue() async {
-    await trackCode(r'''
-void f(int e) {
-  int v;
-  switch (e) {
-    L: case 1:
-      v = 0;
-      break;
-    case 2:
-      continue L;
-      break;
-    default:
-      v = 0;
-  }
-  v;
-}
-''');
-    // We don't analyze to which `case` we go from `continue L`,
-    // but we don't have to. If all cases assign, then the variable is
-    // removed from the unassigned set in the `breakState`. And if there is a
-    // case when it is not assigned, then the variable will be left unassigned
-    // in the `breakState`.
-    assertReadBeforeWritten();
-  }
-
-  test_switch_case_noDefault() async {
-    await trackCode(r'''
-void f(int e) {
-  int v;
-  switch (e) {
-    case 1:
-      v = 0;
-      break;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_switch_expression() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  switch (v = 0) {}
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_tryCatch_body() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    v = 0;
-  } catch (_) {
-    // not assigned
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_tryCatch_body_catch() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    g();
-    v = 0;
-  } catch (_) {
-    v = 0;
-  }
-  v;
-}
-
-void g() {}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_tryCatch_body_catchRethrow() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    v = 0;
-  } catch (_) {
-    rethrow;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_tryCatch_catch() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    // not assigned
-  } catch (_) {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_tryCatchFinally_body() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    v = 0;
-  } catch (_) {
-    // not assigned
-  } finally {
-    // not assigned
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_tryCatchFinally_catch() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    // not assigned
-  } catch (_) {
-    v = 0;
-  } finally {
-    // not assigned
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten('v');
-  }
-
-  test_tryCatchFinally_finally() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    // not assigned
-  } catch (_) {
-    // not assigned
-  } finally {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_tryCatchFinally_useInFinally() async {
-    await trackCode(r'''
-f() {
-  int x;
-  try {
-    g(); // may throw an exception
-    x = 1;
-  } catch (_) {
-    x = 1;
-  } finally {
-    x; // BAD
-  }
-}
-
-void g() {}
-''');
-    assertReadBeforeWritten('x');
-  }
-
-  test_tryFinally_body() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    v = 0;
-  } finally {
-    // not assigned
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_tryFinally_finally() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  try {
-    // not assigned
-  } finally {
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_condition() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  while ((v = 0) >= 0) {
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_condition_notTrue() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  while (b) {
-    v1 = 0;
-    v2 = 0;
-    v1;
-  }
-  v2;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_while_true_break_afterAssignment() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  while (true) {
-    v1 = 0;
-    v1;
-    if (b) break;
-    v1;
-    v2 = 0;
-    v2;
-  }
-  v1;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_true_break_beforeAssignment() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  while (true) {
-    if (b) break;
-    v1 = 0;
-    v2 = 0;
-    v2;
-  }
-  v1;
-}
-''');
-    assertReadBeforeWritten('v1');
-  }
-
-  test_while_true_break_if() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  while (true) {
-    if (b) {
-      v = 0;
-      break;
-    } else {
-      v = 0;
-      break;
-    }
-    v;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_true_break_if2() async {
-    await trackCode(r'''
-void f(bool b) {
-  var v;
-  while (true) {
-    if (b) {
-      break;
-    } else {
-      v = 0;
-    }
-    v;
-  }
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_true_break_if3() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2;
-  while (true) {
-    if (b) {
-      v1 = 0;
-      v2 = 0;
-      if (b) break;
-    } else {
-      if (b) break;
-      v1 = 0;
-      v2 = 0;
-    }
-    v1;
-  }
-  v2;
-}
-''');
-    assertReadBeforeWritten('v2');
-  }
-
-  test_while_true_breakOuterFromInner() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v1, v2, v3;
-  L1: while (true) {
-    L2: while (true) {
-      v1 = 0;
-      if (b) break L1;
-      v2 = 0;
-      v3 = 0;
-      if (b) break L2;
-    }
-    v2;
-  }
-  v1;
-  v3;
-}
-''');
-    assertReadBeforeWritten('v3');
-  }
-
-  test_while_true_continue() async {
-    await trackCode(r'''
-void f(bool b) {
-  int v;
-  while (true) {
-    if (b) continue;
-    v = 0;
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  test_while_true_noBreak() async {
-    await trackCode(r'''
-void f() {
-  int v;
-  while (true) {
-    // No assignment, but no break.
-    // So, we don't exit the loop.
-    // So, all variables are assigned.
-  }
-  v;
-}
-''');
-    assertReadBeforeWritten();
-  }
-
-  /// Resolve the given [code] and track assignments in the unit.
+  /// Resolve the given [code] and track nullability in the unit.
   Future<void> trackCode(String code) async {
+    if (await checkTests(
+        code, _resultComputer, const _FlowAnalysisDataComputer())) {
+      fail('Failure(s)');
+    }
+  }
+
+  Future<ResolvedUnitResult> _resultComputer(String code) async {
     addTestFile(code);
     await resolveTestFile();
-
     var unit = result.unit;
-
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      readBeforeWritten,
-      [],
-      [],
-      [],
-      [],
-    ));
+    flowResult = FlowAnalysisResult.getFromNode(unit);
+    return result;
   }
 }
 
 @reflectiveTest
-class NullableFlowTest extends DriverResolutionTest {
-  final List<AstNode> nullableNodes = [];
-  final List<AstNode> nonNullableNodes = [];
-
-  void assertNonNullable([
-    String search1,
-    String search2,
-    String search3,
-    String search4,
-    String search5,
-  ]) {
-    var expected = [search1, search2, search3, search4, search5]
-        .where((i) => i != null)
-        .map((search) => findNode.simple(search))
-        .toList();
-    expect(nonNullableNodes, unorderedEquals(expected));
-  }
-
-  void assertNullable([
-    String search1,
-    String search2,
-    String search3,
-    String search4,
-    String search5,
-  ]) {
-    var expected = [search1, search2, search3, search4, search5]
-        .where((i) => i != null)
-        .map((search) => findNode.simple(search))
-        .toList();
-    expect(nullableNodes, unorderedEquals(expected));
-  }
+class NullableFlowTest extends FlowTestBase {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
 
   test_assign_toNonNull() async {
     await trackCode(r'''
 void f(int x) {
   if (x != null) return;
-  x; // 1
+  /*nullable*/ x;
   x = 0;
-  x; // 2
+  /*nonNullable*/ x;
 }
 ''');
-    assertNullable('x; // 1');
-    assertNonNullable('x; // 2');
   }
 
   test_assign_toNull() async {
     await trackCode(r'''
 void f(int x) {
   if (x == null) return;
-  x; // 1
+  /*nonNullable*/ x;
   x = null;
-  x; // 2
+  /*nullable*/ x;
 }
 ''');
-    assertNullable('x; // 2');
-    assertNonNullable('x; // 1');
   }
 
   test_assign_toUnknown_fromNotNull() async {
     await trackCode(r'''
 void f(int a, int b) {
   if (a == null) return;
-  a; // 1
+  /*nonNullable*/ a;
   a = b;
-  a; // 2
+  a;
 }
 ''');
-    assertNullable();
-    assertNonNullable('a; // 1');
   }
 
   test_assign_toUnknown_fromNull() async {
     await trackCode(r'''
 void f(int a, int b) {
   if (a != null) return;
-  a; // 1
+  /*nullable*/ a;
   a = b;
-  a; // 2
+  a;
 }
 ''');
-    assertNullable('a; // 1');
-    assertNonNullable();
   }
 
   test_binaryExpression_logicalAnd() async {
     await trackCode(r'''
 void f(int x) {
-  x == null && x.isEven;
+  x == null && /*nullable*/ x.isEven;
 }
 ''');
-    assertNullable('x.isEven');
-    assertNonNullable();
   }
 
   test_binaryExpression_logicalOr() async {
     await trackCode(r'''
 void f(int x) {
-  x == null || x.isEven;
+  x == null || /*nonNullable*/ x.isEven;
 }
 ''');
-    assertNullable();
-    assertNonNullable('x.isEven');
+  }
+
+  test_constructor_if_then_else() async {
+    await trackCode(r'''
+class C {
+  C(int x) {
+    if (x == null) {
+      /*nullable*/ x;
+    } else {
+      /*nonNullable*/ x;
+    }
+  }
+}
+''');
   }
 
   test_if_joinThenElse_ifNull() async {
     await trackCode(r'''
 void f(int a, int b) {
   if (a == null) {
-    a; // 1
+    /*nullable*/ a;
     if (b == null) return;
-    b; // 2
+    /*nonNullable*/ b;
   } else {
-    a; // 3
+    /*nonNullable*/ a;
     if (b == null) return;
-    b; // 4
+    /*nonNullable*/ b;
   }
-  a; // 5
-  b; // 6
+  a;
+  /*nonNullable*/ b;
 }
 ''');
-    assertNullable('a; // 1');
-    assertNonNullable('b; // 2', 'a; // 3', 'b; // 4', 'b; // 6');
   }
 
-  test_if_notNull_thenExit() async {
+  test_if_notNull_thenExit_left() async {
+    await trackCode(r'''
+void f(int x) {
+  if (null != x) return;
+  /*nullable*/ x;
+}
+''');
+  }
+
+  test_if_notNull_thenExit_right() async {
     await trackCode(r'''
 void f(int x) {
   if (x != null) return;
-  x; // 1
+  /*nullable*/ x;
 }
 ''');
-    assertNullable('x; // 1');
-    assertNonNullable();
   }
 
-  test_if_null_thenExit() async {
+  test_if_null_thenExit_left() async {
+    await trackCode(r'''
+void f(int x) {
+  if (null == x) return;
+  /*nonNullable*/ x;
+}
+''');
+  }
+
+  test_if_null_thenExit_right() async {
     await trackCode(r'''
 void f(int x) {
   if (x == null) return;
-  x; // 1
+  /*nonNullable*/ x;
 }
 ''');
-    assertNullable();
-    assertNonNullable('x; // 1');
   }
 
   test_if_then_else() async {
     await trackCode(r'''
 void f(int x) {
   if (x == null) {
-    x; // 1
+    /*nullable*/ x;
   } else {
-    x; // 2
+    /*nonNullable*/ x;
   }
 }
 ''');
-    assertNullable('x; // 1');
-    assertNonNullable('x; // 2');
+  }
+
+  test_method_if_then_else() async {
+    await trackCode(r'''
+class C {
+  void f(int x) {
+    if (x == null) {
+      /*nullable*/ x;
+    } else {
+      /*nonNullable*/ x;
+    }
+  }
+}
+''');
   }
 
   test_potentiallyMutatedInClosure() async {
@@ -1494,14 +210,12 @@
   }
 
   if (a == null) {
-    a; // 1
+    a;
     localFunction();
-    a; // 2
+    a;
   }
 }
 ''');
-    assertNullable();
-    assertNonNullable();
   }
 
   test_tryFinally_eqNullExit_body() async {
@@ -1509,31 +223,27 @@
 void f(int x) {
   try {
     if (x == null) return;
-    x; // 1
+    /*nonNullable*/ x;
   } finally {
-    x; // 2
+    x;
   }
-  x; // 3
+  /*nonNullable*/ x;
 }
 ''');
-    assertNullable();
-    assertNonNullable('x; // 1', 'x; // 3');
   }
 
   test_tryFinally_eqNullExit_finally() async {
     await trackCode(r'''
 void f(int x) {
   try {
-    x; // 1
+    x;
   } finally {
     if (x == null) return;
-    x; // 2
+    /*nonNullable*/ x;
   }
-  x; // 3
+  /*nonNullable*/ x;
 }
 ''');
-    assertNullable();
-    assertNonNullable('x; // 2', 'x; // 3');
   }
 
   test_tryFinally_outerEqNotNullExit_assignUnknown_body() async {
@@ -1541,17 +251,15 @@
 void f(int a, int b) {
   if (a != null) return;
   try {
-    a; // 1
+    /*nullable*/ a;
     a = b;
-    a; // 2
+    a;
   } finally {
-    a; // 3
+    a;
   }
-  a; // 4
+  a;
 }
 ''');
-    assertNullable('a; // 1');
-    assertNonNullable();
   }
 
   test_tryFinally_outerEqNullExit_assignUnknown_body() async {
@@ -1559,17 +267,15 @@
 void f(int a, int b) {
   if (a == null) return;
   try {
-    a; // 1
+    /*nonNullable*/ a;
     a = b;
-    a; // 2
+    a;
   } finally {
-    a; // 3
+    a;
   }
-  a; // 4
+  a;
 }
 ''');
-    assertNullable();
-    assertNonNullable('a; // 1');
   }
 
   test_tryFinally_outerEqNullExit_assignUnknown_finally() async {
@@ -1577,179 +283,130 @@
 void f(int a, int b) {
   if (a == null) return;
   try {
-    a; // 1
+    /*nonNullable*/ a;
   } finally {
-    a; // 2
+    /*nonNullable*/ a;
     a = b;
-    a; // 3
+    a;
   }
-  a; // 4
+  a;
 }
 ''');
-    assertNullable();
-    assertNonNullable('a; // 1', 'a; // 2');
   }
 
   test_while_eqNull() async {
     await trackCode(r'''
 void f(int x) {
   while (x == null) {
-    x; // 1
+    /*nullable*/ x;
   }
-  x; // 2
+  /*nonNullable*/ x;
 }
 ''');
-    assertNullable('x; // 1');
-    assertNonNullable('x; // 2');
   }
 
   test_while_notEqNull() async {
     await trackCode(r'''
 void f(int x) {
   while (x != null) {
-    x; // 1
+    /*nonNullable*/ x;
   }
-  x; // 2
+  /*nullable*/ x;
 }
 ''');
-    assertNullable('x; // 2');
-    assertNonNullable('x; // 1');
-  }
-
-  /// Resolve the given [code] and track nullability in the unit.
-  Future<void> trackCode(String code) async {
-    addTestFile(code);
-    await resolveTestFile();
-
-    var unit = result.unit;
-
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      [],
-      nullableNodes,
-      nonNullableNodes,
-      [],
-      [],
-    ));
   }
 }
 
 @reflectiveTest
-class ReachableFlowTest extends DriverResolutionTest {
-  final List<AstNode> unreachableNodes = [];
-  final List<FunctionBody> functionBodiesThatDontComplete = [];
+class ReachableFlowTest extends FlowTestBase {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
 
   test_conditional_false() async {
     await trackCode(r'''
 void f() {
-  false ? 1 : 2;
+  false ? /*unreachable*/ 1 : 2;
 }
 ''');
-    verify(unreachableExpressions: ['1']);
   }
 
   test_conditional_true() async {
     await trackCode(r'''
 void f() {
-  true ? 1 : 2;
+  true ? 1 : /*unreachable*/ 2;
 }
 ''');
-    verify(unreachableExpressions: ['2']);
   }
 
   test_do_false() async {
     await trackCode(r'''
 void f() {
-  do (true) {
+  do {
     1;
   } while (false);
   2;
 }
 ''');
-    verify();
   }
 
   test_do_true() async {
     await trackCode(r'''
-void f() { // f
-  do (true) {
+/*member: f:doesNotComplete*/
+void f() {
+  do {
     1;
   } while (true);
-  2;
+  /*stmt: unreachable*/ 2;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_exit_beforeSplitStatement() async {
     await trackCode(r'''
-void f(bool b, int i) { // f
+/*member: f:doesNotComplete*/
+void f(bool b, int i) {
   return;
-  do {} while (b);
-  for (;;) {}
-  for (_ in []) {}
-  if (b) {}
-  switch (i) {}
-  try {} finally {}
-  while (b) {}
+  /*stmt: unreachable*/ Object _;
+  /*stmt: unreachable*/ do {} while (b);
+  /*stmt: unreachable*/ for (;;) {}
+  /*stmt: unreachable*/ for (_ in []) {}
+  /*stmt: unreachable*/ if (b) {}
+  /*stmt: unreachable*/ switch (i) {}
+  /*stmt: unreachable*/ try {} finally {}
+  /*stmt: unreachable*/ while (b) {}
 }
 ''');
-    verify(
-      unreachableStatements: [
-        'do {}',
-        'for (;;',
-        'for (_',
-        'if (b)',
-        'try {',
-        'switch (i)',
-        'while (b) {}'
-      ],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_for_condition_true() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   for (; true;) {
     1;
   }
-  2;
+  /*stmt: unreachable*/ 2;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_for_condition_true_implicit() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   for (;;) {
     1;
   }
-  2;
+  /*stmt: unreachable*/ 2;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_forEach() async {
     await trackCode(r'''
 void f() {
+  Object _;
   for (_ in [0, 1, 2]) {
     1;
     return;
@@ -1757,16 +414,15 @@
   2;
 }
 ''');
-    verify();
   }
 
   test_functionBody_hasReturn() async {
     await trackCode(r'''
-int f() { // f
+/*member: f:doesNotComplete*/
+int f() {
   return 42;
 }
 ''');
-    verify(functionBodiesThatDontComplete: ['{ // f']);
   }
 
   test_functionBody_noReturn() async {
@@ -1775,7 +431,6 @@
   1;
 }
 ''');
-    verify();
   }
 
   test_if_condition() async {
@@ -1789,67 +444,59 @@
   3;
 }
 ''');
-    verify();
   }
 
   test_if_false_then_else() async {
     await trackCode(r'''
 void f() {
-  if (false) { // 1
+  if (false) /*stmt: unreachable*/ {
     1;
-  } else { // 2
+  } else {
   }
   3;
 }
 ''');
-    verify(unreachableStatements: ['{ // 1']);
   }
 
   test_if_true_return() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   1;
   if (true) {
     return;
   }
-  2;
+  /*stmt: unreachable*/ 2;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_if_true_then_else() async {
     await trackCode(r'''
 void f() {
-  if (true) { // 1
-  } else { // 2
+  if (true) {
+  } else /*stmt: unreachable*/ {
     2;
   }
   3;
 }
 ''');
-    verify(unreachableStatements: ['{ // 2']);
   }
 
   test_logicalAnd_leftFalse() async {
     await trackCode(r'''
 void f(int x) {
-  false && (x == 1);
+  false && /*unreachable*/ (x == 1);
 }
 ''');
-    verify(unreachableExpressions: ['(x == 1)']);
   }
 
   test_logicalOr_leftTrue() async {
     await trackCode(r'''
 void f(int x) {
-  true || (x == 1);
+  true || /*unreachable*/ (x == 1);
 }
 ''');
-    verify(unreachableExpressions: ['(x == 1)']);
   }
 
   test_switch_case_neverCompletes() async {
@@ -1863,12 +510,11 @@
       } else {
         return;
       }
-      2;
+      /*stmt: unreachable*/ 2;
   }
   3;
 }
 ''');
-    verify(unreachableStatements: ['2;']);
   }
 
   test_tryCatch() async {
@@ -1882,7 +528,6 @@
   3;
 }
 ''');
-    verify();
   }
 
   test_tryCatch_return_body() async {
@@ -1891,14 +536,13 @@
   try {
     1;
     return;
-    2;
+    /*stmt: unreachable*/ 2;
   } catch (_) {
     3;
   }
   4;
 }
 ''');
-    verify(unreachableStatements: ['2;']);
   }
 
   test_tryCatch_return_catch() async {
@@ -1909,12 +553,11 @@
   } catch (_) {
     2;
     return;
-    3;
+    /*stmt: unreachable*/ 3;
   }
   4;
 }
 ''');
-    verify(unreachableStatements: ['3;']);
   }
 
   test_tryCatchFinally_return_body() async {
@@ -1931,12 +574,12 @@
   4;
 }
 ''');
-    verify();
   }
 
   test_tryCatchFinally_return_bodyCatch() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   try {
     1;
     return;
@@ -1946,13 +589,9 @@
   } finally {
     3;
   }
-  4;
+  /*stmt: unreachable*/ 4;
 }
 ''');
-    verify(
-      unreachableStatements: ['4;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_tryCatchFinally_return_catch() async {
@@ -1969,53 +608,45 @@
   4;
 }
 ''');
-    verify();
   }
 
   test_tryFinally_return_body() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   try {
     1;
     return;
   } finally {
     2;
   }
-  3;
+  /*stmt: unreachable*/ 3;
 }
 ''');
-    verify(
-      unreachableStatements: ['3;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_while_false() async {
     await trackCode(r'''
 void f() {
-  while (false) { // 1
+  while (false) /*stmt: unreachable*/ {
     1;
   }
   2;
 }
 ''');
-    verify(unreachableStatements: ['{ // 1']);
   }
 
   test_while_true() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   while (true) {
     1;
   }
-  2;
-  3;
+  /*stmt: unreachable*/ 2;
+  /*stmt: unreachable*/ 3;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;', '3;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
   }
 
   test_while_true_break() async {
@@ -2024,12 +655,11 @@
   while (true) {
     1;
     break;
-    2;
+    /*stmt: unreachable*/ 2;
   }
   3;
 }
 ''');
-    verify(unreachableStatements: ['2;']);
   }
 
   test_while_true_breakIf() async {
@@ -2043,1553 +673,115 @@
   3;
 }
 ''');
-    verify();
   }
 
   test_while_true_continue() async {
     await trackCode(r'''
-void f() { // f
+/*member: f:doesNotComplete*/
+void f() {
   while (true) {
     1;
     continue;
-    2;
+    /*stmt: unreachable*/ 2;
   }
-  3;
+  /*stmt: unreachable*/ 3;
 }
 ''');
-    verify(
-      unreachableStatements: ['2;', '3;'],
-      functionBodiesThatDontComplete: ['{ // f'],
-    );
-  }
-
-  /// Resolve the given [code] and track unreachable nodes in the unit.
-  Future<void> trackCode(String code) async {
-    addTestFile(code);
-    await resolveTestFile();
-
-    var unit = result.unit;
-
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
-      typeSystem,
-      assignedVariables,
-      {},
-      [],
-      [],
-      [],
-      unreachableNodes,
-      functionBodiesThatDontComplete,
-    ));
-  }
-
-  void verify({
-    List<String> unreachableExpressions = const [],
-    List<String> unreachableStatements = const [],
-    List<String> functionBodiesThatDontComplete = const [],
-  }) {
-    var expectedUnreachableNodes = <AstNode>[];
-    expectedUnreachableNodes.addAll(
-      unreachableStatements.map((search) => findNode.statement(search)),
-    );
-    expectedUnreachableNodes.addAll(
-      unreachableExpressions.map((search) => findNode.expression(search)),
-    );
-
-    expect(
-      this.unreachableNodes,
-      unorderedEquals(expectedUnreachableNodes),
-    );
-    expect(
-      this.functionBodiesThatDontComplete,
-      unorderedEquals(
-        functionBodiesThatDontComplete
-            .map((search) => findNode.functionBody(search))
-            .toList(),
-      ),
-    );
   }
 }
 
-@reflectiveTest
-class TypePromotionFlowTest extends DriverResolutionTest {
-  final Map<AstNode, DartType> promotedTypes = {};
-
-  void assertNotPromoted(String search) {
-    var node = findNode.simple(search);
-    var actualType = promotedTypes[node];
-    expect(actualType, isNull, reason: search);
-  }
-
-  void assertPromoted(String search, String expectedType) {
-    var node = findNode.simple(search);
-    var actualType = promotedTypes[node];
-    if (actualType == null) {
-      fail('$expectedType expected, but actually not promoted\n$search');
-    }
-    assertElementTypeString(actualType, expectedType);
-  }
-
-  test_assignment() async {
-    await trackCode(r'''
-f(Object x) {
-  if (x is String) {
-    x = 42;
-    x; // 1
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_binaryExpression_ifNull() async {
-    await trackCode(r'''
-void f(Object x) {
-  ((x is num) || (throw 1)) ?? ((x is int) || (throw 2));
-  x; // 1
-}
-''');
-    assertPromoted('x; // 1', 'num');
-  }
-
-  test_binaryExpression_ifNull_rightUnPromote() async {
-    await trackCode(r'''
-void f(Object x, Object y, Object z) {
-  if (x is int) {
-    x; // 1
-    y ?? (x = z);
-    x; // 2
-  }
-}
-''');
-    assertPromoted('x; // 1', 'int');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_conditional_both() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  b ? ((x is num) || (throw 1)) : ((x is int) || (throw 2));
-  x; // 1
-}
-''');
-    assertPromoted('x; // 1', 'num');
-  }
-
-  test_conditional_else() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  b ? 0 : ((x is int) || (throw 2));
-  x; // 1
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_conditional_then() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  b ? ((x is num) || (throw 1)) : 0;
-  x; // 1
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_do_condition_isNotType() async {
-    await trackCode(r'''
-void f(Object x) {
-  do {
-    x; // 1
-    x = '';
-  } while (x is! String)
-  x; // 2
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertPromoted('x; // 2', 'String');
-  }
-
-  test_do_condition_isType() async {
-    await trackCode(r'''
-void f(Object x) {
-  do {
-    x; // 1
-  } while (x is String)
-  x; // 2
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_do_outerIsType() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    do {
-      x; // 1
-    } while (b);
-    x; // 2
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-  }
-
-  test_do_outerIsType_loopAssigned_body() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    do {
-      x; // 1
-      x = x.length;
-    } while (b);
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_do_outerIsType_loopAssigned_condition() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    do {
-      x; // 1
-      x = x.length;
-    } while (x != 0);
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x != 0');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_do_outerIsType_loopAssigned_condition2() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    do {
-      x; // 1
-    } while ((x = 1) != 0);
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_for_outerIsType() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    for (; b;) {
-      x; // 1
-    }
-    x; // 2
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-  }
-
-  test_for_outerIsType_loopAssigned_body() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    for (; b;) {
-      x; // 1
-      x = 42;
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_for_outerIsType_loopAssigned_condition() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    for (; (x = 42) > 0;) {
-      x; // 1
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_for_outerIsType_loopAssigned_updaters() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    for (; b; x = 42) {
-      x; // 1
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_forEach_outerIsType_loopAssigned() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    for (var _ in (v1 = [0, 1, 2])) {
-      x; // 1
-      x = 42;
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_functionExpression_isType() async {
-    await trackCode(r'''
-void f() {
-  void g(Object x) {
-    if (x is String) {
-      x; // 1
-    }
-    x = 42;
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-  }
-
-  test_functionExpression_isType_mutatedInClosure2() async {
-    await trackCode(r'''
-void f() {
-  void g(Object x) {
-    if (x is String) {
-      x; // 1
-    }
-    
-    void h() {
-      x = 42;
-    }
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_functionExpression_outerIsType_assignedOutside() async {
-    await trackCode(r'''
-void f(Object x) {
-  void Function() g;
-  
-  if (x is String) {
-    x; // 1
-
-    g = () {
-      x; // 2
-    }
-  }
-
-  x = 42;
-  x; // 3
-  g();
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-    assertNotPromoted('x; // 3');
-  }
-
-  test_if_combine_empty() async {
-    await trackCode(r'''
-main(bool b, Object v) {
-  if (b) {
-    v is int || (throw 1);
-  } else {
-    v is String || (throw 2);
-  }
-  v; // 3
-}
-''');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_conditional_isNotType() async {
-    await trackCode(r'''
-f(bool b, Object v) {
-  if (b ? (v is! int) : (v is! num)) {
-    v; // 1
-  } else {
-    v; // 2
-  }
-  v; // 3
-}
-''');
-    assertNotPromoted('v; // 1');
-    assertPromoted('v; // 2', 'num');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_conditional_isType() async {
-    await trackCode(r'''
-f(bool b, Object v) {
-  if (b ? (v is int) : (v is num)) {
-    v; // 1
-  } else {
-    v; // 2
-  }
-  v; // 3
-}
-''');
-    assertPromoted('v; // 1', 'num');
-    assertNotPromoted('v; // 2');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_isNotType() async {
-    await trackCode(r'''
-main(v) {
-  if (v is! String) {
-    v; // 1
-  } else {
-    v; // 2
-  }
-  v; // 3
-}
-''');
-    assertNotPromoted('v; // 1');
-    assertPromoted('v; // 2', 'String');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_isNotType_return() async {
-    await trackCode(r'''
-main(v) {
-  if (v is! String) return;
-  v; // ref
-}
-''');
-    assertPromoted('v; // ref', 'String');
-  }
-
-  test_if_isNotType_throw() async {
-    await trackCode(r'''
-main(v) {
-  if (v is! String) throw 42;
-  v; // ref
-}
-''');
-    assertPromoted('v; // ref', 'String');
-  }
-
-  test_if_isType() async {
-    await trackCode(r'''
-main(v) {
-  if (v is String) {
-    v; // 1
-  } else {
-    v; // 2
-  }
-  v; // 3
-}
-''');
-    assertPromoted('v; // 1', 'String');
-    assertNotPromoted('v; // 2');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_isType_thenNonBoolean() async {
-    await trackCode(r'''
-f(Object x) {
-  if ((x is String) != 3) {
-    x; // 1
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_if_logicalNot_isType() async {
-    await trackCode(r'''
-main(v) {
-  if (!(v is String)) {
-    v; // 1
-  } else {
-    v; // 2
-  }
-  v; // 3
-}
-''');
-    assertNotPromoted('v; // 1');
-    assertPromoted('v; // 2', 'String');
-    assertNotPromoted('v; // 3');
-  }
-
-  test_if_then_isNotType_return() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (b) {
-    if (x is! String) return;
-  }
-  x; // 1
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_logicalOr_throw() async {
-    await trackCode(r'''
-main(v) {
-  v is String || (throw 42);
-  v; // ref
-}
-''');
-    assertPromoted('v; // ref', 'String');
-  }
-
-  test_potentiallyMutatedInClosure() async {
-    await trackCode(r'''
-f(Object x) {
-  localFunction() {
-    x = 42;
-  }
-
-  if (x is String) {
-    localFunction();
-    x; // 1
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-  }
-
-  test_potentiallyMutatedInScope() async {
-    await trackCode(r'''
-f(Object x) {
-  if (x is String) {
-    x; // 1
-  }
-
-  x = 42;
-}
-''');
-    assertPromoted('x; // 1', 'String');
-  }
-
-  test_switch_outerIsType_assignedInCase() async {
-    await trackCode(r'''
-void f(int e, Object x) {
-  if (x is String) {
-    switch (e) {
-      L: case 1:
-        x; // 1
-        break;
-      case 2: // no label
-        x; // 2
-        break;
-      case 3:
-        x = 42;
-        continue L;
-    }
-    x; // 3
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertPromoted('x; // 2', 'String');
-    assertNotPromoted('x; // 3');
-  }
-
-  test_tryCatch_assigned_body() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is! String) return;
-  x; // 1
-  try {
-    x = 42;
-    g(); // might throw
-    if (x is! String) return;
-    x; // 2
-  } catch (_) {}
-  x; // 3
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-    assertNotPromoted('x; // 3');
-  }
-
-  test_tryCatch_isNotType_exit_body() async {
-    await trackCode(r'''
-void f(Object x) {
-  try {
-    if (x is! String) return;
-    x; // 1
-  } catch (_) {}
-  x; // 2
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_tryCatch_isNotType_exit_body_catch() async {
-    await trackCode(r'''
-void f(Object x) {
-  try {
-    if (x is! String) return;
-    x; // 1
-  } catch (_) {
-    if (x is! String) return;
-    x; // 2
-  }
-  x; // 3
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-    assertPromoted('x; // 3', 'String');
-  }
-
-  test_tryCatch_isNotType_exit_body_catchRethrow() async {
-    await trackCode(r'''
-void f(Object x) {
-  try {
-    if (x is! String) return;
-    x; // 1
-  } catch (_) {
-    x; // 2
-    rethrow;
-  }
-  x; // 3
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-    assertPromoted('x; // 3', 'String');
-  }
-
-  test_tryCatch_isNotType_exit_catch() async {
-    await trackCode(r'''
-void f(Object x) {
-  try {
-  } catch (_) {
-    if (x is! String) return;
-    x; // 1
-  }
-  x; // 2
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_tryCatchFinally_outerIsType() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    try {
-      x; // 1
-    } catch (_) {
-      x; // 2
-    } finally {
-      x; // 3
-    }
-    x; // 4
-  }
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-    assertPromoted('x; // 3', 'String');
-    assertPromoted('x; // 4', 'String');
-  }
-
-  test_tryCatchFinally_outerIsType_assigned_body() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    try {
-      x; // 1
-      x = 42;
-      g();
-    } catch (_) {
-      x; // 2
-    } finally {
-      x; // 3
-    }
-    x; // 4
-  }
-}
-
-void g() {}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-    assertNotPromoted('x; // 3');
-    assertNotPromoted('x; // 4');
-  }
-
-  test_tryCatchFinally_outerIsType_assigned_catch() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    try {
-      x; // 1
-    } catch (_) {
-      x; // 2
-      x = 42;
-    } finally {
-      x; // 3
-    }
-    x; // 4
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-    assertNotPromoted('x; // 3');
-    assertNotPromoted('x; // 4');
-  }
-
-  test_tryFinally_outerIsType_assigned_body() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    try {
-      x; // 1
-      x = 42;
-    } finally {
-      x; // 2
-    }
-    x; // 3
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-    assertNotPromoted('x; // 3');
-  }
-
-  test_tryFinally_outerIsType_assigned_finally() async {
-    await trackCode(r'''
-void f(Object x) {
-  if (x is String) {
-    try {
-      x; // 1
-    } finally {
-      x; // 2
-      x = 42;
-    }
-    x; // 3
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-    assertNotPromoted('x; // 3');
-  }
-
-  test_while_condition_false() async {
-    await trackCode(r'''
-void f(Object x) {
-  while (x is! String) {
-    x; // 1
-  }
-  x; // 2
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertPromoted('x; // 2', 'String');
-  }
-
-  test_while_condition_true() async {
-    await trackCode(r'''
-void f(Object x) {
-  while (x is String) {
-    x; // 1
-  }
-  x; // 2
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_while_outerIsType() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    while (b) {
-      x; // 1
-    }
-    x; // 2
-  }
-}
-''');
-    assertPromoted('x; // 1', 'String');
-    assertPromoted('x; // 2', 'String');
-  }
-
-  test_while_outerIsType_loopAssigned_body() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    while (b) {
-      x; // 1
-      x = x.length;
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  test_while_outerIsType_loopAssigned_condition() async {
-    await trackCode(r'''
-void f(bool b, Object x) {
-  if (x is String) {
-    while (x != 0) {
-      x; // 1
-      x = x.length;
-    }
-    x; // 2
-  }
-}
-''');
-    assertNotPromoted('x != 0');
-    assertNotPromoted('x; // 1');
-    assertNotPromoted('x; // 2');
-  }
-
-  /// Resolve the given [code] and track assignments in the unit.
-  Future<void> trackCode(String code) async {
-    addTestFile(code);
-    await resolveTestFile();
-
-    var unit = result.unit;
-
-    var assignedVariables = AssignedVariables<Statement, VariableElement>();
-    unit.accept(_AssignedVariablesVisitor(assignedVariables));
-
-    var typeSystem = unit.declaredElement.context.typeSystem;
-    unit.accept(_AstVisitor(
-      typeSystem,
-      assignedVariables,
-      promotedTypes,
-      [],
-      [],
-      [],
-      [],
-      [],
-    ));
-  }
-}
-
-class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
-  final AssignedVariables assignedVariables;
-
-  _AssignedVariablesVisitor(this.assignedVariables);
+class _FlowAnalysisDataComputer extends DataComputer<Set<_FlowAssertion>> {
+  const _FlowAnalysisDataComputer();
 
   @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
+  DataInterpreter<Set<_FlowAssertion>> get dataValidator =>
+      const _FlowAnalysisDataInterpreter();
 
-    super.visitAssignmentExpression(node);
+  @override
+  void computeUnitData(CompilationUnit unit,
+      Map<Id, ActualData<Set<_FlowAssertion>>> actualMap) {
+    var flowResult = FlowAnalysisResult.getFromNode(unit);
+    _FlowAnalysisDataExtractor(
+            unit.declaredElement.source.uri, actualMap, flowResult)
+        .run(unit);
+  }
+}
 
-    if (left is SimpleIdentifier) {
-      var element = left.staticElement;
-      if (element is VariableElement) {
-        assignedVariables.write(element);
+class _FlowAnalysisDataExtractor extends AstDataExtractor<Set<_FlowAssertion>> {
+  FlowAnalysisResult _flowResult;
+
+  _FlowAnalysisDataExtractor(Uri uri,
+      Map<Id, ActualData<Set<_FlowAssertion>>> actualMap, this._flowResult)
+      : super(uri, actualMap);
+
+  @override
+  Set<_FlowAssertion> computeNodeValue(Id id, AstNode node) {
+    Set<_FlowAssertion> result = {};
+    if (_flowResult.nullableNodes.contains(node)) {
+      // We sometimes erroneously annotate a node as both nullable and
+      // non-nullable.  Ignore for now.  TODO(paulberry): fix this.
+      if (!_flowResult.nonNullableNodes.contains(node)) {
+        result.add(_FlowAssertion.nullable);
       }
     }
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    assignedVariables.beginLoop();
-    super.visitDoStatement(node);
-    assignedVariables.endLoop(node);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    var forLoopParts = node.forLoopParts;
-    if (forLoopParts is ForParts) {
-      if (forLoopParts is ForPartsWithExpression) {
-        forLoopParts.initialization?.accept(this);
-      } else if (forLoopParts is ForPartsWithDeclarations) {
-        forLoopParts.variables?.accept(this);
-      } else {
-        throw new StateError('Unrecognized for loop parts');
+    if (_flowResult.nonNullableNodes.contains(node)) {
+      // We sometimes erroneously annotate a node as both nullable and
+      // non-nullable.  Ignore for now.  TODO(paulberry): fix this.
+      if (!_flowResult.nullableNodes.contains(node)) {
+        result.add(_FlowAssertion.nonNullable);
       }
+    }
+    if (_flowResult.unreachableNodes.contains(node)) {
+      result.add(_FlowAssertion.unreachable);
+    }
+    if (node is FunctionDeclaration) {
+      var body = node.functionExpression.body;
+      if (body != null &&
+          _flowResult.functionBodiesThatDontComplete.contains(body)) {
+        result.add(_FlowAssertion.doesNotComplete);
+      }
+    }
+    return result.isEmpty ? null : result;
+  }
+}
 
-      assignedVariables.beginLoop();
-      forLoopParts.condition?.accept(this);
-      node.body.accept(this);
-      forLoopParts.updaters?.accept(this);
-      assignedVariables.endLoop(node);
-    } else if (forLoopParts is ForEachParts) {
-      var iterable = forLoopParts.iterable;
-      var body = node.body;
+class _FlowAnalysisDataInterpreter
+    implements DataInterpreter<Set<_FlowAssertion>> {
+  const _FlowAnalysisDataInterpreter();
 
-      iterable.accept(this);
+  @override
+  String getText(Set<_FlowAssertion> actualData) =>
+      _sortedRepresentation(_toStrings(actualData));
 
-      assignedVariables.beginLoop();
-      body.accept(this);
-      assignedVariables.endLoop(node);
+  @override
+  String isAsExpected(Set<_FlowAssertion> actualData, String expectedData) {
+    var actualStrings = _toStrings(actualData);
+    var actualSorted = _sortedRepresentation(actualStrings);
+    var expectedSorted = _sortedRepresentation(expectedData?.split(','));
+    if (actualSorted == expectedSorted) {
+      return null;
     } else {
-      throw new StateError('Unrecognized for loop parts');
+      return 'Expected $expectedData, got $actualSorted';
     }
   }
 
   @override
-  void visitSwitchStatement(SwitchStatement node) {
-    var expression = node.expression;
-    var members = node.members;
+  bool isEmpty(Set<_FlowAssertion> actualData) => actualData.isEmpty;
 
-    expression.accept(this);
-
-    assignedVariables.beginLoop();
-    members.accept(this);
-    assignedVariables.endLoop(node);
+  String _sortedRepresentation(Iterable<String> values) {
+    var list = values == null || values.isEmpty ? ['none'] : values.toList();
+    list.sort();
+    return list.join(',');
   }
 
-  @override
-  void visitTryStatement(TryStatement node) {
-    assignedVariables.beginLoop();
-    node.body.accept(this);
-    assignedVariables.endLoop(node.body);
-
-    node.catchClauses.accept(this);
-
-    var finallyBlock = node.finallyBlock;
-    if (finallyBlock != null) {
-      assignedVariables.beginLoop();
-      finallyBlock.accept(this);
-      assignedVariables.endLoop(finallyBlock);
-    }
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    assignedVariables.beginLoop();
-    super.visitWhileStatement(node);
-    assignedVariables.endLoop(node);
-  }
+  List<String> _toStrings(Set<_FlowAssertion> actualData) => actualData
+      .map((flowAssertion) => flowAssertion.toString().split('.')[1])
+      .toList();
 }
 
-/// [AstVisitor] that drives the [flow] in the way we expect the resolver
-/// will do in production.
-class _AstVisitor extends GeneralizingAstVisitor<void> {
-  static final trueLiteral = astFactory.booleanLiteral(null, true);
-
-  final NodeOperations<Expression> nodeOperations;
-  final TypeOperations<VariableElement, DartType> typeOperations;
-  final AssignedVariables assignedVariables;
-  final Map<AstNode, DartType> promotedTypes;
-  final List<LocalVariableElement> readBeforeWritten;
-  final List<AstNode> nullableNodes;
-  final List<AstNode> nonNullableNodes;
-  final List<AstNode> unreachableNodes;
-  final List<FunctionBody> functionBodiesThatDontComplete;
-
-  FlowAnalysis<Statement, Expression, VariableElement, DartType> flow;
-
-  _AstVisitor(
-      TypeSystem typeSystem,
-      this.assignedVariables,
-      this.promotedTypes,
-      this.readBeforeWritten,
-      this.nullableNodes,
-      this.nonNullableNodes,
-      this.unreachableNodes,
-      this.functionBodiesThatDontComplete)
-      : nodeOperations = _NodeOperations(),
-        typeOperations = _TypeSystemTypeOperations(typeSystem);
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var left = node.leftHandSide;
-    var right = node.rightHandSide;
-
-    VariableElement localElement;
-    if (left is SimpleIdentifier) {
-      var element = left.staticElement;
-      if (element is VariableElement) {
-        localElement = element;
-      }
-    }
-
-    if (localElement != null) {
-      var isPure = node.operator.type == TokenType.EQ;
-      if (!isPure) {
-        flow.read(localElement);
-      }
-      right.accept(this);
-      flow.write(
-        localElement,
-        isNull: _isNull(right),
-        isNonNull: _isNonNull(right),
-      );
-    } else {
-      left.accept(this);
-      right.accept(this);
-    }
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var left = node.leftOperand;
-    var right = node.rightOperand;
-
-    var operator = node.operator.type;
-
-    if (operator == TokenType.AMPERSAND_AMPERSAND) {
-      left.accept(this);
-
-      flow.logicalAnd_rightBegin(node, node.leftOperand);
-      _checkUnreachableNode(node.rightOperand);
-      right.accept(this);
-
-      flow.logicalAnd_end(node, node.rightOperand);
-    } else if (operator == TokenType.BAR_BAR) {
-      left.accept(this);
-
-      flow.logicalOr_rightBegin(node, node.leftOperand);
-      _checkUnreachableNode(node.rightOperand);
-      right.accept(this);
-
-      flow.logicalOr_end(node, node.rightOperand);
-    } else if (operator == TokenType.BANG_EQ) {
-      left.accept(this);
-      right.accept(this);
-      if (right is NullLiteral) {
-        if (left is SimpleIdentifier) {
-          var element = left.staticElement;
-          if (element is VariableElement) {
-            flow.conditionNotEqNull(node, element);
-          }
-        }
-      }
-    } else if (operator == TokenType.EQ_EQ) {
-      left.accept(this);
-      right.accept(this);
-      if (right is NullLiteral) {
-        if (left is SimpleIdentifier) {
-          var element = left.staticElement;
-          if (element is VariableElement) {
-            flow.conditionEqNull(node, element);
-          }
-        }
-      }
-    } else if (operator == TokenType.QUESTION_QUESTION) {
-      left.accept(this);
-
-      flow.ifNullExpression_rightBegin();
-      right.accept(this);
-
-      flow.ifNullExpression_end();
-    } else {
-      left.accept(this);
-      right.accept(this);
-    }
-  }
-
-  @override
-  void visitBlockFunctionBody(BlockFunctionBody node) {
-    var isFlowOwner = flow == null;
-
-    if (isFlowOwner) {
-      flow = FlowAnalysis<Statement, Expression, VariableElement, DartType>(
-        nodeOperations,
-        typeOperations,
-        _FunctionBodyAccess(node),
-      );
-
-      var function = node.parent;
-      if (function is FunctionExpression) {
-        var parameters = function.parameters;
-        if (parameters != null) {
-          for (var parameter in parameters?.parameters) {
-            flow.add(parameter.declaredElement, assigned: true);
-          }
-        }
-      }
-    }
-
-    super.visitBlockFunctionBody(node);
-
-    if (isFlowOwner) {
-      for (var variable in flow.readBeforeWritten) {
-        assert(variable is LocalVariableElement);
-        readBeforeWritten.add(variable);
-      }
-
-      if (!flow.isReachable) {
-        functionBodiesThatDontComplete.add(node);
-      }
-
-      flow.verifyStackEmpty();
-      flow = null;
-    }
-  }
-
-  @override
-  void visitBooleanLiteral(BooleanLiteral node) {
-    super.visitBooleanLiteral(node);
-    if (_isFalseLiteral(node)) {
-      flow.falseLiteral(node);
-    }
-    if (_isTrueLiteral(node)) {
-      flow.trueLiteral(node);
-    }
-  }
-
-  @override
-  void visitBreakStatement(BreakStatement node) {
-    super.visitBreakStatement(node);
-    var target = _getLabelTarget(node, node.label?.staticElement);
-    flow.handleBreak(target);
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    var condition = node.condition;
-    var thenExpression = node.thenExpression;
-    var elseExpression = node.elseExpression;
-
-    condition.accept(this);
-
-    flow.conditional_thenBegin(node, node.condition);
-    _checkUnreachableNode(node.thenExpression);
-    thenExpression.accept(this);
-    var isBool = thenExpression.staticType.isDartCoreBool;
-
-    flow.conditional_elseBegin(node, node.thenExpression, isBool);
-    _checkUnreachableNode(node.elseExpression);
-    elseExpression.accept(this);
-
-    flow.conditional_end(node, node.elseExpression, isBool);
-  }
-
-  @override
-  void visitContinueStatement(ContinueStatement node) {
-    super.visitContinueStatement(node);
-    var target = _getLabelTarget(node, node.label?.staticElement);
-    flow.handleContinue(target);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    _checkUnreachableNode(node);
-
-    var body = node.body;
-    var condition = node.condition;
-
-    flow.doStatement_bodyBegin(node, assignedVariables[node]);
-    body.accept(this);
-
-    flow.doStatement_conditionBegin();
-    condition.accept(this);
-
-    flow.doStatement_end(node, node.condition);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    _checkUnreachableNode(node);
-
-    ForLoopParts parts = node.forLoopParts;
-    if (parts is ForEachParts) {
-      parts.iterable?.accept(this);
-
-      flow.forEachStatement_bodyBegin(assignedVariables[node]);
-
-      node.body.accept(this);
-
-      flow.forEachStatement_end();
-      return;
-    }
-    VariableDeclarationList variables;
-    Expression initialization;
-    Expression condition;
-    NodeList<Expression> updaters;
-    if (parts is ForPartsWithDeclarations) {
-      variables = parts.variables;
-      condition = parts.condition;
-      updaters = parts.updaters;
-    } else if (parts is ForPartsWithExpression) {
-      initialization = parts.initialization;
-      condition = parts.condition;
-      updaters = parts.updaters;
-    }
-    initialization?.accept(this);
-    variables?.accept(this);
-
-    flow.forStatement_conditionBegin(assignedVariables[node]);
-    if (condition != null) {
-      condition.accept(this);
-    } else {
-      flow.trueLiteral(trueLiteral);
-    }
-
-    flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
-    node.body.accept(this);
-
-    flow.forStatement_updaterBegin();
-    updaters?.accept(this);
-
-    flow.forStatement_end();
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    flow?.functionExpression_begin();
-    super.visitFunctionExpression(node);
-    flow?.functionExpression_end();
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    _checkUnreachableNode(node);
-
-    var condition = node.condition;
-    var thenStatement = node.thenStatement;
-    var elseStatement = node.elseStatement;
-
-    condition.accept(this);
-
-    flow.ifStatement_thenBegin(node, node.condition);
-    thenStatement.accept(this);
-
-    if (elseStatement != null) {
-      flow.ifStatement_elseBegin();
-      elseStatement.accept(this);
-    }
-
-    flow.ifStatement_end(elseStatement != null);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    super.visitIsExpression(node);
-    var expression = node.expression;
-    var typeAnnotation = node.type;
-
-    if (expression is SimpleIdentifier) {
-      var element = expression.staticElement;
-      if (element is VariableElement) {
-        flow.isExpression_end(
-          node,
-          element,
-          node.notOperator != null,
-          typeAnnotation.type,
-        );
-      }
-    }
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    var operand = node.operand;
-
-    var operator = node.operator.type;
-    if (operator == TokenType.BANG) {
-      operand.accept(this);
-      flow.logicalNot_end(node, node.operand);
-    } else {
-      operand.accept(this);
-    }
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression node) {
-    super.visitRethrowExpression(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    super.visitReturnStatement(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    var element = node.staticElement;
-    var isLocalVariable = element is LocalVariableElement;
-    if (isLocalVariable || element is ParameterElement) {
-      if (node.inGetterContext() && !node.inDeclarationContext()) {
-        if (isLocalVariable) {
-          flow.read(element);
-        }
-
-        if (flow.isNullable(element)) {
-          nullableNodes?.add(node);
-        }
-
-        if (flow.isNonNullable(element)) {
-          nonNullableNodes?.add(node);
-        }
-
-        var promotedType = flow?.promotedType(element);
-        if (promotedType != null) {
-          promotedTypes[node] = promotedType;
-        }
-      }
-    }
-
-    super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  void visitStatement(Statement node) {
-    _checkUnreachableNode(node);
-    super.visitStatement(node);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    _checkUnreachableNode(node);
-
-    node.expression.accept(this);
-    flow.switchStatement_expressionEnd(node);
-
-    var assignedInCases = assignedVariables[node];
-
-    var members = node.members;
-    var membersLength = members.length;
-    var hasDefault = false;
-    for (var i = 0; i < membersLength; i++) {
-      var member = members[i];
-
-      flow.switchStatement_beginCase(
-        member.labels.isNotEmpty ? assignedInCases : assignedVariables.emptySet,
-      );
-      member.accept(this);
-
-      // Implicit `break` at the end of `default`.
-      if (member is SwitchDefault) {
-        hasDefault = true;
-        flow.handleBreak(node);
-      }
-    }
-
-    flow.switchStatement_end(node, hasDefault);
-  }
-
-  @override
-  void visitThrowExpression(ThrowExpression node) {
-    super.visitThrowExpression(node);
-    flow.handleExit();
-  }
-
-  @override
-  void visitTryStatement(TryStatement node) {
-    _checkUnreachableNode(node);
-
-    var body = node.body;
-    var catchClauses = node.catchClauses;
-    var finallyBlock = node.finallyBlock;
-
-    if (finallyBlock != null) {
-      flow.tryFinallyStatement_bodyBegin();
-    }
-
-    flow.tryCatchStatement_bodyBegin();
-    body.accept(this);
-    flow.tryCatchStatement_bodyEnd(assignedVariables[body]);
-
-    var catchLength = catchClauses.length;
-    for (var i = 0; i < catchLength; ++i) {
-      var catchClause = catchClauses[i];
-      flow.tryCatchStatement_catchBegin();
-      catchClause.accept(this);
-      flow.tryCatchStatement_catchEnd();
-    }
-
-    flow.tryCatchStatement_end();
-
-    if (finallyBlock != null) {
-      flow.tryFinallyStatement_finallyBegin(assignedVariables[body]);
-      finallyBlock.accept(this);
-      flow.tryFinallyStatement_end(assignedVariables[finallyBlock]);
-    }
-  }
-
-  @override
-  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    var variables = node.variables.variables;
-    for (var i = 0; i < variables.length; ++i) {
-      var variable = variables[i];
-      flow.add(variable.declaredElement,
-          assigned: variable.initializer != null);
-    }
-
-    super.visitVariableDeclarationStatement(node);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    _checkUnreachableNode(node);
-
-    var condition = node.condition;
-    var body = node.body;
-
-    flow.whileStatement_conditionBegin(assignedVariables[node]);
-    condition.accept(this);
-
-    flow.whileStatement_bodyBegin(node, node.condition);
-    body.accept(this);
-
-    flow.whileStatement_end();
-  }
-
-  /// Mark the [node] as unreachable if it is not covered by another node that
-  /// is already known to be unreachable.
-  void _checkUnreachableNode(AstNode node) {
-    if (flow.isReachable) return;
-
-    // Ignore the [node] if it is fully covered by the last unreachable.
-    if (unreachableNodes.isNotEmpty) {
-      var last = unreachableNodes.last;
-      if (node.offset >= last.offset && node.end <= last.end) return;
-    }
-
-    unreachableNodes.add(node);
-  }
-
-  /// This code has OK performance for tests, but think if there is something
-  /// better when using in production.
-  AstNode _getLabelTarget(AstNode node, LabelElement element) {
-    for (; node != null; node = node.parent) {
-      if (node is DoStatement ||
-          node is ForStatement ||
-          node is SwitchStatement ||
-          node is WhileStatement) {
-        if (element == null) {
-          return node;
-        }
-        var parent = node.parent;
-        if (parent is LabeledStatement) {
-          for (var nodeLabel in parent.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
-              return node;
-            }
-          }
-        }
-      }
-      if (element != null && node is SwitchStatement) {
-        for (var member in node.members) {
-          for (var nodeLabel in member.labels) {
-            if (identical(nodeLabel.label.staticElement, element)) {
-              return node;
-            }
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  static bool _isFalseLiteral(AstNode node) {
-    return node is BooleanLiteral && !node.value;
-  }
-
-  static bool _isNonNull(Expression node) {
-    if (node is NullLiteral) return false;
-
-    return node is Literal;
-  }
-
-  static bool _isNull(Expression node) {
-    return node is NullLiteral;
-  }
-
-  static bool _isTrueLiteral(AstNode node) {
-    return node is BooleanLiteral && node.value;
-  }
-}
-
-class _FunctionBodyAccess implements FunctionBodyAccess<VariableElement> {
-  final FunctionBody node;
-
-  _FunctionBodyAccess(this.node);
-
-  @override
-  bool isPotentiallyMutatedInClosure(VariableElement variable) {
-    return node.isPotentiallyMutatedInClosure(variable);
-  }
-
-  @override
-  bool isPotentiallyMutatedInScope(VariableElement variable) {
-    return node.isPotentiallyMutatedInScope(variable);
-  }
-}
-
-class _NodeOperations implements NodeOperations<Expression> {
-  @override
-  Expression unwrapParenthesized(Expression node) {
-    while (node is ParenthesizedExpression) {
-      node = (node as ParenthesizedExpression).expression;
-    }
-    return node;
-  }
-}
-
-class _TypeSystemTypeOperations
-    implements TypeOperations<VariableElement, DartType> {
-  final TypeSystem typeSystem;
-
-  _TypeSystemTypeOperations(this.typeSystem);
-
-  @override
-  DartType elementType(VariableElement element) {
-    return element.type;
-  }
-
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType) {
-    return typeSystem.isSubtypeOf(leftType, rightType);
-  }
-
-  @override
-  bool isLocalVariable(VariableElement element) {
-    return element is LocalVariableElement;
-  }
+enum _FlowAssertion {
+  doesNotComplete,
+  nonNullable,
+  nullable,
+  unreachable,
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
new file mode 100644
index 0000000..929f0533
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/local_variable_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(LocalVariableResolutionTest);
+    defineReflectiveTests(LocalVariableResolutionTest_NNBD);
+  });
+}
+
+@reflectiveTest
+class LocalVariableResolutionTest extends DriverResolutionTest {
+  test_element() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int x = 0;
+}
+''');
+
+    var x = findElement.localVar('x');
+    expect(x.isConst, isFalse);
+    expect(x.isFinal, isFalse);
+    expect(x.isLate, isFalse);
+    expect(x.isStatic, isFalse);
+  }
+
+  test_element_const() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  const int x = 0;
+}
+''');
+
+    var x = findElement.localVar('x');
+    expect(x.isConst, isTrue);
+    expect(x.isFinal, isFalse);
+    expect(x.isLate, isFalse);
+    expect(x.isStatic, isFalse);
+  }
+
+  test_element_final() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  final int x = 0;
+}
+''');
+
+    var x = findElement.localVar('x');
+    expect(x.isConst, isFalse);
+    expect(x.isFinal, isTrue);
+    expect(x.isLate, isFalse);
+    expect(x.isStatic, isFalse);
+  }
+}
+
+@reflectiveTest
+class LocalVariableResolutionTest_NNBD extends LocalVariableResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+  test_element_late() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  late int x = 0;
+}
+''');
+
+    var x = findElement.localVar('x');
+    expect(x.isConst, isFalse);
+    expect(x.isFinal, isFalse);
+    expect(x.isLate, isTrue);
+    expect(x.isStatic, isFalse);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 56deafe..4040944 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -419,8 +419,10 @@
     expect(node.staticType, isNull);
   }
 
-  ExpectedError error(ErrorCode code, int offset, int length) =>
-      new ExpectedError(code, offset, length);
+  ExpectedError error(ErrorCode code, int offset, int length,
+          {List<ExpectedMessage> expectedMessages =
+              const <ExpectedMessage>[]}) =>
+      ExpectedError(code, offset, length, expectedMessages: expectedMessages);
 
   Element getNodeElement(AstNode node) {
     if (node is Annotation) {
@@ -450,6 +452,9 @@
     }
   }
 
+  ExpectedMessage message(String filePath, int offset, int length) =>
+      ExpectedMessage(convertPath(filePath), offset, length);
+
   Future<ResolvedUnitResult> resolveFile(String path);
 
   Future<void> resolveTestFile() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 95539c2..c03f65c 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -27,6 +27,7 @@
     as instance_member_inference_class;
 import 'instance_member_inference_mixin_test.dart'
     as instance_member_inference_mixin;
+import 'local_variable_test.dart' as local_variable;
 import 'metadata_test.dart' as metadata;
 import 'method_invocation_test.dart' as method_invocation;
 import 'mixin_test.dart' as mixin_resolution;
@@ -36,6 +37,7 @@
 import 'property_access_test.dart' as property_access;
 import 'top_type_inference_test.dart' as top_type_inference;
 import 'type_inference/test_all.dart' as type_inference;
+import 'type_promotion_test.dart' as type_promotion;
 
 main() {
   defineReflectiveSuite(() {
@@ -59,6 +61,7 @@
     instance_creation.main();
     instance_member_inference_class.main();
     instance_member_inference_mixin.main();
+    local_variable.main();
     metadata.main();
     method_invocation.main();
     mixin_resolution.main();
@@ -67,6 +70,7 @@
     optional_const.main();
     property_access.main();
     top_type_inference.main();
+    type_promotion.main();
     type_inference.main();
   }, name: 'resolution');
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart b/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart
new file mode 100644
index 0000000..ff73bd4
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_promotion_test.dart
@@ -0,0 +1,757 @@
+// Copyright (c) 2019, 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:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/ast_data_extractor.dart';
+import 'package:front_end/src/testing/id.dart' show ActualData, Id;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../util/id_equivalence_helper.dart';
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypePromotionTest);
+  });
+}
+
+@reflectiveTest
+class TypePromotionTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+  Future<void> resolveCode(String code) async {
+    if (await checkTests(
+        code, _resultComputer, const _TypePromotionDataComputer())) {
+      fail('Failure(s)');
+    }
+  }
+
+  test_assignment() async {
+    await resolveCode(r'''
+f(Object x) {
+  if (x is String) {
+    x = 42;
+    x;
+  }
+}
+''');
+  }
+
+  test_binaryExpression_ifNull() async {
+    await resolveCode(r'''
+void f(Object x) {
+  ((x is num) || (throw 1)) ?? ((/*num*/ x is int) || (throw 2));
+  /*num*/ x;
+}
+''');
+  }
+
+  test_binaryExpression_ifNull_rightUnPromote() async {
+    await resolveCode(r'''
+void f(Object x, Object y, Object z) {
+  if (x is int) {
+    /*int*/ x;
+    y ?? (x = z);
+    x;
+  }
+}
+''');
+  }
+
+  test_conditional_both() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  b ? ((x is num) || (throw 1)) : ((x is int) || (throw 2));
+  /*num*/ x;
+}
+''');
+  }
+
+  test_conditional_else() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  b ? 0 : ((x is int) || (throw 2));
+  x;
+}
+''');
+  }
+
+  test_conditional_then() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  b ? ((x is num) || (throw 1)) : 0;
+  x;
+}
+''');
+  }
+
+  test_do_condition_isNotType() async {
+    await resolveCode(r'''
+void f(Object x) {
+  do {
+    x;
+  } while (x is! String);
+  /*String*/ x;
+}
+''');
+  }
+
+  test_do_condition_isType() async {
+    await resolveCode(r'''
+void f(Object x) {
+  do {
+    x;
+  } while (x is String);
+  x;
+}
+''');
+  }
+
+  test_do_outerIsType() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      /*String*/ x;
+    } while (b);
+    /*String*/ x;
+  }
+}
+''');
+  }
+
+  test_do_outerIsType_loopAssigned_body() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x;
+      x = x.length;
+    } while (b);
+    x;
+  }
+}
+''');
+  }
+
+  test_do_outerIsType_loopAssigned_condition() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x;
+      x = x.length;
+    } while (x != 0);
+    x;
+  }
+}
+''');
+  }
+
+  test_do_outerIsType_loopAssigned_condition2() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x;
+    } while ((x = 1) != 0);
+    x;
+  }
+}
+''');
+  }
+
+  test_for_outerIsType() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b;) {
+      /*String*/ x;
+    }
+    /*String*/ x;
+  }
+}
+''');
+  }
+
+  test_for_outerIsType_loopAssigned_body() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b;) {
+      x;
+      x = 42;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_for_outerIsType_loopAssigned_condition() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    for (; (x = 42) > 0;) {
+      x;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_for_outerIsType_loopAssigned_updaters() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b; x = 42) {
+      x;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_forEach_outerIsType_loopAssigned() async {
+    await resolveCode(r'''
+void f(Object x) {
+  Object v1;
+  if (x is String) {
+    for (var _ in (v1 = [0, 1, 2])) {
+      x;
+      x = 42;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_functionExpression_isType() async {
+    await resolveCode(r'''
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      /*String*/ x;
+    }
+    x = 42;
+  }
+}
+''');
+  }
+
+  test_functionExpression_isType_mutatedInClosure2() async {
+    await resolveCode(r'''
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      x;
+    }
+    
+    void h() {
+      x = 42;
+    }
+  }
+}
+''');
+  }
+
+  test_functionExpression_outerIsType_assignedOutside() async {
+    await resolveCode(r'''
+void f(Object x) {
+  void Function() g;
+  
+  if (x is String) {
+    /*String*/ x;
+
+    g = () {
+      x;
+    };
+  }
+
+  x = 42;
+  x;
+  g();
+}
+''');
+  }
+
+  test_if_combine_empty() async {
+    await resolveCode(r'''
+main(bool b, Object v) {
+  if (b) {
+    v is int || (throw 1);
+  } else {
+    v is String || (throw 2);
+  }
+  v;
+}
+''');
+  }
+
+  test_if_conditional_isNotType() async {
+    await resolveCode(r'''
+f(bool b, Object v) {
+  if (b ? (v is! int) : (v is! num)) {
+    v;
+  } else {
+    /*num*/ v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_conditional_isType() async {
+    await resolveCode(r'''
+f(bool b, Object v) {
+  if (b ? (v is int) : (v is num)) {
+    /*num*/ v;
+  } else {
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_isNotType() async {
+    await resolveCode(r'''
+main(v) {
+  if (v is! String) {
+    v;
+  } else {
+    /*String*/ v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_isNotType_return() async {
+    await resolveCode(r'''
+main(v) {
+  if (v is! String) return;
+  /*String*/ v;
+}
+''');
+  }
+
+  test_if_isNotType_throw() async {
+    await resolveCode(r'''
+main(v) {
+  if (v is! String) throw 42;
+  /*String*/ v;
+}
+''');
+  }
+
+  test_if_isType() async {
+    await resolveCode(r'''
+main(v) {
+  if (v is String) {
+    /*String*/ v;
+  } else {
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_isType_thenNonBoolean() async {
+    await resolveCode(r'''
+f(Object x) {
+  if ((x is String) != 3) {
+    x;
+  }
+}
+''');
+  }
+
+  test_if_logicalNot_isType() async {
+    await resolveCode(r'''
+main(v) {
+  if (!(v is String)) {
+    v;
+  } else {
+    /*String*/ v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_then_isNotType_return() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (b) {
+    if (x is! String) return;
+  }
+  x;
+}
+''');
+  }
+
+  test_logicalOr_throw() async {
+    await resolveCode(r'''
+main(v) {
+  v is String || (throw 42);
+  /*String*/ v;
+}
+''');
+  }
+
+  test_potentiallyMutatedInClosure() async {
+    await resolveCode(r'''
+f(Object x) {
+  localFunction() {
+    x = 42;
+  }
+
+  if (x is String) {
+    localFunction();
+    x;
+  }
+}
+''');
+  }
+
+  test_potentiallyMutatedInScope() async {
+    await resolveCode(r'''
+f(Object x) {
+  if (x is String) {
+    /*String*/ x;
+  }
+
+  x = 42;
+}
+''');
+  }
+
+  test_switch_outerIsType_assignedInCase() async {
+    await resolveCode(r'''
+void f(int e, Object x) {
+  if (x is String) {
+    switch (e) {
+      L: case 1:
+        x;
+        break;
+      case 2: // no label
+        /*String*/ x;
+        break;
+      case 3:
+        x = 42;
+        continue L;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_tryCatch_assigned_body() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is! String) return;
+  /*String*/ x;
+  try {
+    x = 42;
+    g(); // might throw
+    if (x is! String) return;
+    /*String*/ x;
+  } catch (_) {}
+  x;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatch_isNotType_exit_body() async {
+    await resolveCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    /*String*/ x;
+  } catch (_) {}
+  x;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatch_isNotType_exit_body_catch() async {
+    await resolveCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    /*String*/ x;
+  } catch (_) {
+    if (x is! String) return;
+    /*String*/ x;
+  }
+  /*String*/ x;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatch_isNotType_exit_body_catchRethrow() async {
+    await resolveCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    /*String*/ x;
+  } catch (_) {
+    x;
+    rethrow;
+  }
+  /*String*/ x;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatch_isNotType_exit_catch() async {
+    await resolveCode(r'''
+void f(Object x) {
+  try {
+  } catch (_) {
+    if (x is! String) return;
+    /*String*/ x;
+  }
+  x;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatchFinally_outerIsType() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      /*String*/ x;
+    } catch (_) {
+      /*String*/ x;
+    } finally {
+      /*String*/ x;
+    }
+    /*String*/ x;
+  }
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatchFinally_outerIsType_assigned_body() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      /*String*/ x;
+      x = 42;
+      g();
+    } catch (_) {
+      x;
+    } finally {
+      x;
+    }
+    x;
+  }
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatchFinally_outerIsType_assigned_catch() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      /*String*/ x;
+    } catch (_) {
+      /*String*/ x;
+      x = 42;
+    } finally {
+      x;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_tryFinally_outerIsType_assigned_body() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      /*String*/ x;
+      x = 42;
+    } finally {
+      x;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_tryFinally_outerIsType_assigned_finally() async {
+    await resolveCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      /*String*/ x;
+    } finally {
+      /*String*/ x;
+      x = 42;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_while_condition_false() async {
+    await resolveCode(r'''
+void f(Object x) {
+  while (x is! String) {
+    x;
+  }
+  /*String*/ x;
+}
+''');
+  }
+
+  test_while_condition_true() async {
+    await resolveCode(r'''
+void f(Object x) {
+  while (x is String) {
+    /*String*/ x;
+  }
+  x;
+}
+''');
+  }
+
+  test_while_outerIsType() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (b) {
+      /*String*/ x;
+    }
+    /*String*/ x;
+  }
+}
+''');
+  }
+
+  test_while_outerIsType_loopAssigned_body() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (b) {
+      x;
+      x = x.length;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  test_while_outerIsType_loopAssigned_condition() async {
+    await resolveCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (x != 0) {
+      x;
+      x = x.length;
+    }
+    x;
+  }
+}
+''');
+  }
+
+  Future<ResolvedUnitResult> _resultComputer(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+    return result;
+  }
+}
+
+class _TypePromotionDataComputer extends DataComputer<DartType> {
+  const _TypePromotionDataComputer();
+
+  @override
+  DataInterpreter<DartType> get dataValidator =>
+      const _TypePromotionDataInterpreter();
+
+  @override
+  void computeUnitData(
+      CompilationUnit unit, Map<Id, ActualData<DartType>> actualMap) {
+    _TypePromotionDataExtractor(unit.declaredElement.source.uri, actualMap)
+        .run(unit);
+  }
+}
+
+class _TypePromotionDataExtractor extends AstDataExtractor<DartType> {
+  _TypePromotionDataExtractor(Uri uri, Map<Id, ActualData<DartType>> actualMap)
+      : super(uri, actualMap);
+
+  @override
+  DartType computeNodeValue(Id id, AstNode node) {
+    if (node is SimpleIdentifier && node.inGetterContext()) {
+      var element = node.staticElement;
+      if (element is VariableElement &&
+          (element is LocalVariableElement || element is ParameterElement)) {
+        var promotedType = node.staticType;
+        if (promotedType != element.type) {
+          return promotedType;
+        }
+      }
+    }
+    return null;
+  }
+}
+
+class _TypePromotionDataInterpreter implements DataInterpreter<DartType> {
+  const _TypePromotionDataInterpreter();
+
+  @override
+  String getText(DartType actualData) => actualData.toString();
+
+  @override
+  String isAsExpected(DartType actualData, String expectedData) {
+    if (actualData.toString() == expectedData) {
+      return null;
+    } else {
+      return 'Expected $expectedData, got $actualData';
+    }
+  }
+
+  @override
+  bool isEmpty(DartType actualData) => actualData == null;
+}
diff --git a/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
index 30e9267..c47a2fd 100644
--- a/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/default_list_constructor_mismatch_test.dart
@@ -22,6 +22,15 @@
     ..contextFeatures = new FeatureSet.forTesting(
         sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
 
+  test_inferredType() async {
+    await assertErrorsInCode('''
+class C {}
+List<C> v = List(5);
+''', [
+      error(CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR_MISMATCH, 23, 4),
+    ]);
+  }
+
   test_nonNullableType() async {
     await assertErrorsInCode('''
 var l = new List<int>(3);
@@ -36,13 +45,11 @@
 ''');
   }
 
-  test_inferredType() async {
-    await assertErrorsInCode('''
-class C {}
-List<C> v = List(5);
-''', [
-      error(CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR_MISMATCH, 23, 4),
-    ]);
+  test_optOut() async {
+    await assertNoErrorsInCode('''
+// @dart = 2.2
+var l = new List<int>(3);
+''');
   }
 
   test_typeParameter() async {
diff --git a/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
new file mode 100644
index 0000000..548d473
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/not_assigned_potentially_non_nullable_local_variable_test.dart
@@ -0,0 +1,1426 @@
+// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/test_support.dart';
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(
+      NotInitializedPotentiallyNonNullableLocalVariableTest,
+    );
+  });
+}
+
+@reflectiveTest
+class NotInitializedPotentiallyNonNullableLocalVariableTest
+    extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions =>
+      AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
+
+  test_assignment_leftExpression() async {
+    await assertErrorsInCode(r'''
+void f() {
+  List<int> v;
+  v[0] = (v = [1, 2])[1];
+  v;
+}
+''', [
+      _notAssignedError(28, 1),
+    ]);
+  }
+
+  test_assignment_leftLocal_compound() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  v += 1;
+  v;
+}
+''', [
+      _notAssignedError(22, 1),
+    ]);
+  }
+
+  test_assignment_leftLocal_compound_assignInRight() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  v += (v = v);
+}
+''', [
+      _notAssignedError(22, 1),
+      _notAssignedError(32, 1),
+    ]);
+  }
+
+  test_assignment_leftLocal_pure_eq() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  v = 0;
+  v;
+}
+''');
+  }
+
+  test_assignment_leftLocal_pure_eq_self() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  v = v;
+}
+''', [
+      _notAssignedError(26, 1),
+    ]);
+  }
+
+  test_assignment_leftLocal_pure_questionEq() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  v ??= 0;
+}
+''', [
+      _notAssignedError(22, 1),
+      error(HintCode.DEAD_CODE, 28, 1),
+    ]);
+  }
+
+  test_assignment_leftLocal_pure_questionEq_self() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  v ??= v;
+}
+''', [
+      _notAssignedError(22, 1),
+      error(HintCode.DEAD_CODE, 28, 1),
+      _notAssignedError(28, 1),
+    ]);
+  }
+
+  test_basic() async {
+    await assertNoErrorsInCode('''
+void f() {
+  int v;
+  v = 0;
+  v;
+}
+''');
+  }
+
+  test_binaryExpression_ifNull_left() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  (v = 0) ?? 0;
+  v;
+}
+''', [error(HintCode.DEAD_CODE, 33, 1)]);
+  }
+
+  test_binaryExpression_ifNull_right() async {
+    await assertErrorsInCode(r'''
+void f(int a) {
+  int v;
+  a ?? (v = 0);
+  v;
+}
+''', [
+      error(HintCode.DEAD_CODE, 32, 7),
+      _notAssignedError(43, 1),
+    ]);
+  }
+
+  test_binaryExpression_logicalAnd_left() async {
+    await assertNoErrorsInCode(r'''
+main(bool c) {
+  int v;
+  ((v = 0) >= 0) && c;
+  v;
+}
+''');
+  }
+
+  test_binaryExpression_logicalAnd_right() async {
+    await assertErrorsInCode(r'''
+main(bool c) {
+  int v;
+  c && ((v = 0) >= 0);
+  v;
+}
+''', [
+      _notAssignedError(49, 1),
+    ]);
+  }
+
+  test_binaryExpression_logicalOr_left() async {
+    await assertNoErrorsInCode(r'''
+main(bool c) {
+  int v;
+  ((v = 0) >= 0) || c;
+  v;
+}
+''');
+  }
+
+  test_binaryExpression_logicalOr_right() async {
+    await assertErrorsInCode(r'''
+main(bool c) {
+  int v;
+  c || ((v = 0) >= 0);
+  v;
+}
+''', [
+      _notAssignedError(49, 1),
+    ]);
+  }
+
+  test_binaryExpression_plus_left() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  int v;
+  (v = 0) + 1;
+  v;
+}
+''');
+  }
+
+  test_binaryExpression_plus_right() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  int v;
+  1 + (v = 0);
+  v;
+}
+''');
+  }
+
+  test_conditional_both() async {
+    await assertNoErrorsInCode(r'''
+f(bool b) {
+  int v;
+  b ? (v = 1) : (v = 2);
+  v;
+}
+''');
+  }
+
+  test_conditional_else() async {
+    await assertErrorsInCode(r'''
+f(bool b) {
+  int v;
+  b ? 1 : (v = 2);
+  v;
+}
+''', [
+      _notAssignedError(42, 1),
+    ]);
+  }
+
+  test_conditional_then() async {
+    await assertErrorsInCode(r'''
+f(bool b) {
+  int v;
+  b ? (v = 1) : 2;
+  v;
+}
+''', [
+      _notAssignedError(42, 1),
+    ]);
+  }
+
+  test_conditionalExpression_condition() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  int v;
+  (v = 0) >= 0 ? 1 : 2;
+  v;
+}
+''');
+  }
+
+  test_doWhile_break_afterAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    v = 0;
+    v;
+    if (b) break;
+  } while (b);
+  v;
+}
+''');
+  }
+
+  test_doWhile_break_beforeAssignment() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) break;
+    v = 0;
+  } while (b);
+  v;
+}
+''', [
+      _notAssignedError(79, 1),
+    ]);
+  }
+
+  test_doWhile_breakOuterFromInner() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2, v3;
+  L1: do {
+    do {
+      v1 = 0;
+      if (b) break L1;
+      v2 = 0;
+      v3 = 0;
+    } while (b);
+    v2;
+  } while (b);
+  v1;
+  v3;
+}
+''', [
+      _notAssignedError(168, 2),
+    ]);
+  }
+
+  test_doWhile_condition() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v1, v2;
+  do {
+    v1; // assigned in the condition, but not yet
+  } while ((v1 = 0) + (v2 = 0) >= 0);
+  v2;
+}
+''', [
+      _notAssignedError(36, 2),
+    ]);
+  }
+
+  test_doWhile_condition_break() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) break;
+  } while ((v = 0) >= 0);
+  v;
+}
+''', [
+      _notAssignedError(79, 1),
+    ]);
+  }
+
+  test_doWhile_condition_break_continue() async {
+    await assertErrorsInCode(r'''
+void f(bool b1, b2) {
+  int v1, v2, v3, v4, v5, v6;
+  do {
+    v1 = 0; // visible outside, visible to the condition
+    if (b1) break;
+    v2 = 0; // not visible outside, visible to the condition
+    v3 = 0; // not visible outside, visible to the condition
+    if (b2) continue;
+    v4 = 0; // not visible
+    v5 = 0; // not visible
+  } while ((v6 = v1 + v2 + v4) == 0); // has break => v6 is not visible outside
+  v1;
+  v3;
+  v5;
+  v6;
+}
+''', [
+      _notAssignedError(360, 2),
+      _notAssignedError(421, 2),
+      _notAssignedError(427, 2),
+      _notAssignedError(433, 2),
+    ]);
+  }
+
+  test_doWhile_condition_continue() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2, v3, v4;
+  do {
+    v1 = 0; // visible outside, visible to the condition
+    if (b) continue;
+    v2 = 0; // not visible
+    v3 = 0; // not visible
+  } while ((v4 = v1 + v2) == 0); // no break => v4 visible outside
+  v1;
+  v3;
+  v4;
+}
+''', [
+      _notAssignedError(200, 2),
+      _notAssignedError(253, 2),
+    ]);
+  }
+
+  test_doWhile_continue_beforeAssignment() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) continue;
+    v = 0;
+  } while (b);
+  v;
+}
+''', [
+      _notAssignedError(82, 1),
+    ]);
+  }
+
+  test_doWhile_true_assignInBreak() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) {
+      v = 0;
+      break;
+    }
+  } while (true);
+  v;
+}
+''');
+  }
+
+  test_for_body() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  for (; b;) {
+    v = 0;
+  }
+  v;
+}
+''', [
+      _notAssignedError(58, 1),
+    ]);
+  }
+
+  test_for_break() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b;) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(94, 2),
+      _notAssignedError(100, 2),
+    ]);
+  }
+
+  test_for_break_updaters() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b; v1 + v2) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+}
+''');
+  }
+
+  test_for_condition() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  for (; (v = 0) >= 0;) {
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_for_continue() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b;) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(97, 2),
+      _notAssignedError(103, 2),
+    ]);
+  }
+
+  test_for_continue_updaters() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b; v1 + v2) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+}
+''', [
+      _notAssignedError(48, 2),
+    ]);
+  }
+
+  test_for_initializer_expression() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  for (v = 0;;) {
+    v;
+  }
+  v;
+}
+''', [
+      error(HintCode.DEAD_CODE, 51, 2),
+    ]);
+  }
+
+  test_for_initializer_variable() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  for (var t = (v = 0);;) {
+    v;
+  }
+  v;
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 31, 1),
+      error(HintCode.DEAD_CODE, 61, 2),
+    ]);
+  }
+
+  test_for_updaters() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2, v3, v4;
+  for (; b; v1 = 0, v2 = 0, v3 = 0, v4) {
+    v1;
+  }
+  v2;
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 31, 2),
+      _notAssignedError(75, 2),
+      _notAssignedError(85, 2),
+      _notAssignedError(95, 2),
+    ]);
+  }
+
+  test_for_updaters_afterBody() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  for (; b; v) {
+    v = 0;
+  }
+}
+''');
+  }
+
+  test_forEach() async {
+    await assertErrorsInCode(r'''
+void f() {
+  List<int> v1;
+  int v2;
+  for (var _ in (v1 = [0, 1, 2])) {
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(97, 2),
+    ]);
+  }
+
+  test_forEach_break() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (var _ in [0, 1, 2]) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(108, 2),
+      _notAssignedError(114, 2),
+    ]);
+  }
+
+  test_forEach_continue() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (var _ in [0, 1, 2]) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(111, 2),
+      _notAssignedError(117, 2),
+    ]);
+  }
+
+  test_functionExpression_closure_read() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v1, v2;
+
+  v1 = 0;
+
+  [0, 1, 2].forEach((t) {
+    v1;
+    v2;
+  });
+}
+''', [
+      _notAssignedError(75, 2),
+    ]);
+  }
+
+  test_functionExpression_closure_write() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+
+  [0, 1, 2].forEach((t) {
+    v = t;
+  });
+
+  v;
+}
+''', [
+      _notAssignedError(67, 1),
+    ]);
+  }
+
+  test_functionExpression_localFunction_local() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+
+  v = 0;
+
+  void f() {
+    int v; // 1
+    v;
+  }
+}
+''', [
+      error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+      error(HintCode.UNUSED_ELEMENT, 38, 1),
+      _notAssignedError(64, 1),
+    ]);
+  }
+
+  test_functionExpression_localFunction_local2() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v1;
+
+  v1 = 0;
+
+  void f() {
+    int v2, v3;
+    v2 = 0;
+    v1;
+    v2;
+    v3;
+  }
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 40, 1),
+      _notAssignedError(94, 2),
+    ]);
+  }
+
+  test_functionExpression_localFunction_read() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v1, v2;
+
+  v1 = 0;
+
+  void f() {
+    v1;
+    v2;
+  }
+
+  v2 = 0;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 44, 1),
+      _notAssignedError(62, 2),
+    ]);
+  }
+
+  test_functionExpression_localFunction_write() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+
+  void f() {
+    v = 0;
+  }
+
+  v;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 28, 1),
+      _notAssignedError(52, 1),
+    ]);
+  }
+
+  test_futureOr_questionArgument_none() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+
+f() {
+  FutureOr<int?> v;
+}
+''');
+  }
+
+  test_hasInitializer() async {
+    await assertNoErrorsInCode('''
+f() {
+  int v = 0;
+  v;
+}
+''');
+  }
+
+  test_if_condition() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  int v;
+  if ((v = 0) >= 0) {
+    v;
+  } else {
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_condition_false() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  if (false) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''', [
+      error(HintCode.DEAD_CODE, 33, 25),
+    ]);
+  }
+
+  test_if_condition_logicalAnd() async {
+    await assertErrorsInCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b && (v = i) > 0) {
+    v;
+  } else {
+    v;
+  }
+  v;
+}
+''', [
+      _notAssignedError(81, 1),
+      _notAssignedError(90, 1),
+    ]);
+  }
+
+  test_if_condition_logicalOr() async {
+    await assertErrorsInCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b || (v = i) > 0) {
+    v;
+  } else {
+    v;
+  }
+  v;
+}
+''', [
+      _notAssignedError(63, 1),
+      _notAssignedError(90, 1),
+    ]);
+  }
+
+  test_if_condition_notFalse() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  if (!false) {
+    v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_condition_notTrue() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  if (!true) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_condition_true() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  if (true) {
+    v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_then() async {
+    await assertErrorsInCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+  }
+  v;
+}
+''', [
+      _notAssignedError(52, 1),
+    ]);
+  }
+
+  test_if_thenElse_all() async {
+    await assertNoErrorsInCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+    v;
+  } else {
+    v = 0;
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_if_thenElse_else() async {
+    await assertErrorsInCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''', [
+      _notAssignedError(83, 1),
+    ]);
+  }
+
+  test_if_thenElse_then() async {
+    await assertErrorsInCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+  } else {
+    // not assigned
+  }
+  v;
+}
+''', [
+      _notAssignedError(83, 1),
+    ]);
+  }
+
+  test_late() async {
+    await assertNoErrorsInCode('''
+f() {
+  late int v;
+  v;
+}
+''');
+  }
+
+  test_noInitializer() async {
+    await assertErrorsInCode('''
+f() {
+  int v;
+  v;
+}
+''', [
+      _notAssignedError(17, 1),
+    ]);
+  }
+
+  test_noInitializer_typeParameter() async {
+    await assertErrorsInCode('''
+f<T>() {
+  T v;
+  v;
+}
+''', [
+      _notAssignedError(18, 1),
+    ]);
+  }
+
+  test_notUsed() async {
+    await assertNoErrorsInCode('''
+void f() {
+  int v;
+}
+''');
+  }
+
+  test_nullable() async {
+    await assertNoErrorsInCode('''
+f() {
+  int? v;
+  v;
+}
+''');
+  }
+
+  test_switch_case1_default() async {
+    await assertErrorsInCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    case 1:
+      v = 0;
+      break;
+    case 2:
+      // not assigned
+      break;
+    default:
+      v = 0;
+  }
+  v;
+}
+''', [
+      _notAssignedError(157, 1),
+    ]);
+  }
+
+  test_switch_case2_default() async {
+    await assertErrorsInCode(r'''
+void f(int e) {
+  int v1, v2;
+  switch (e) {
+    case 1:
+      v1 = 0;
+      v2 = 0;
+      v1;
+      break;
+    default:
+      v1 = 0;
+      v1;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(157, 2),
+    ]);
+  }
+
+  test_switch_case_default_break() async {
+    await assertErrorsInCode(r'''
+void f(bool b, int e) {
+  int v1, v2;
+  switch (e) {
+    case 1:
+      v1 = 0;
+      if (b) break;
+      v2 = 0;
+      break;
+    default:
+      v1 = 0;
+      if (b) break;
+      v2 = 0;
+  }
+  v1;
+  v2;
+}
+''', [
+      _notAssignedError(199, 2),
+    ]);
+  }
+
+  test_switch_case_default_continue() async {
+    // We don't analyze to which `case` we go from `continue L`,
+    // but we don't have to. If all cases assign, then the variable is
+    // removed from the unassigned set in the `breakState`. And if there is a
+    // case when it is not assigned, then the variable will be left unassigned
+    // in the `breakState`.
+    await assertNoErrorsInCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    L: case 1:
+      v = 0;
+      break;
+    case 2:
+      continue L;
+      break;
+    default:
+      v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_switch_case_noDefault() async {
+    await assertErrorsInCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    case 1:
+      v = 0;
+      break;
+  }
+  v;
+}
+''', [
+      _notAssignedError(84, 1),
+    ]);
+  }
+
+  test_switch_expression() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  switch (v = 0) {}
+  v;
+}
+''');
+  }
+
+  test_tryCatch_body() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    // not assigned
+  }
+  v;
+}
+''', [
+      _notAssignedError(81, 1),
+    ]);
+  }
+
+  test_tryCatch_body_catch() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    g();
+    v = 0;
+  } catch (_) {
+    v = 0;
+  }
+  v;
+}
+
+void g() {}
+''');
+  }
+
+  test_tryCatch_body_catchRethrow() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    rethrow;
+  }
+  v;
+}
+''');
+  }
+
+  test_tryCatch_catch() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    v = 0;
+  }
+  v;
+}
+''', [
+      _notAssignedError(81, 1),
+    ]);
+  }
+
+  test_tryCatchFinally_body() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    // not assigned
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''', [
+      _notAssignedError(115, 1),
+    ]);
+  }
+
+  test_tryCatchFinally_catch() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    v = 0;
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''', [
+      _notAssignedError(115, 1),
+    ]);
+  }
+
+  test_tryCatchFinally_finally() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    // not assigned
+  } finally {
+    v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_tryCatchFinally_useInFinally() async {
+    await assertErrorsInCode(r'''
+f() {
+  int x;
+  try {
+    g(); // may throw an exception
+    x = 1;
+  } catch (_) {
+    x = 1;
+  } finally {
+    x; // BAD
+  }
+}
+
+void g() {}
+''', [
+      _notAssignedError(114, 1),
+    ]);
+  }
+
+  test_tryFinally_body() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''');
+  }
+
+  test_tryFinally_finally() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } finally {
+    v = 0;
+  }
+  v;
+}
+''');
+  }
+
+  test_type_dynamic() async {
+    await assertNoErrorsInCode('''
+f() {
+  dynamic v;
+}
+''');
+  }
+
+  test_type_dynamicImplicit() async {
+    await assertNoErrorsInCode('''
+f() {
+  var v;
+}
+''');
+  }
+
+  test_type_void() async {
+    await assertNoErrorsInCode('''
+f() {
+  void v;
+}
+''');
+  }
+
+  test_while_condition() async {
+    await assertNoErrorsInCode(r'''
+void f() {
+  int v;
+  while ((v = 0) >= 0) {
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_while_condition_notTrue() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  while (b) {
+    v = 0;
+    v;
+  }
+  v;
+}
+''', [
+      _notAssignedError(64, 1),
+    ]);
+  }
+
+  test_while_true_break_afterAssignment() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (true) {
+    v1 = 0;
+    v1;
+    if (b) break;
+    v2 = 0;
+    v1;
+    v2;
+  }
+  v1;
+}
+''');
+  }
+
+  test_while_true_break_beforeAssignment() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  while (true) {
+    if (b) break;
+    v = 0;
+    v;
+  }
+  v;
+}
+''', [
+      _notAssignedError(85, 1),
+    ]);
+  }
+
+  test_while_true_break_if() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  while (true) {
+    if (b) {
+      v = 0;
+      break;
+    } else {
+      v = 0;
+      break;
+    }
+    v;
+  }
+  v;
+}
+''');
+  }
+
+  test_while_true_break_if2() async {
+    await assertNoErrorsInCode(r'''
+void f(bool b) {
+  var v;
+  while (true) {
+    if (b) {
+      break;
+    } else {
+      v = 0;
+    }
+    v;
+  }
+}
+''');
+  }
+
+  test_while_true_break_if3() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (true) {
+    if (b) {
+      v1 = 0;
+      v2 = 0;
+      if (b) break;
+    } else {
+      if (b) break;
+      v1 = 0;
+      v2 = 0;
+    }
+    v1;
+  }
+  v2;
+}
+''', [
+      _notAssignedError(190, 2),
+    ]);
+  }
+
+  test_while_true_breakOuterFromInner() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v1, v2, v3;
+  L1: while (true) {
+    L2: while (true) {
+      v1 = 0;
+      if (b) break L1;
+      v2 = 0;
+      v3 = 0;
+      if (b) break L2;
+    }
+    v2;
+  }
+  v1;
+  v3;
+}
+''', [
+      _notAssignedError(193, 2),
+    ]);
+  }
+
+  test_while_true_continue() async {
+    await assertErrorsInCode(r'''
+void f(bool b) {
+  int v;
+  while (true) {
+    if (b) continue;
+    v = 0;
+  }
+  v;
+}
+''', [
+      error(HintCode.DEAD_CODE, 81, 2),
+    ]);
+  }
+
+  test_while_true_noBreak() async {
+    await assertErrorsInCode(r'''
+void f() {
+  int v;
+  while (true) {
+    // No assignment, but no break.
+    // So, we don't exit the loop.
+    // So, all variables are assigned.
+  }
+  v;
+}
+''', [
+      error(HintCode.DEAD_CODE, 153, 2),
+    ]);
+  }
+
+  ExpectedError _notAssignedError(int offset, int length) {
+    return error(
+        CompileTimeErrorCode
+            .NOT_ASSIGNED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
+        offset,
+        length);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
similarity index 60%
rename from pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
rename to pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
index 373e9b5..233eb2b 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_potentially_non_nullable_local_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_static_field_test.dart
@@ -11,93 +11,84 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(
-      NotInitializedPotentiallyNonNullableLocalVariableTest,
-    );
+    defineReflectiveTests(NotInitializedNonNullableStaticFieldTest);
   });
 }
 
 @reflectiveTest
-class NotInitializedPotentiallyNonNullableLocalVariableTest
-    extends DriverResolutionTest {
+class NotInitializedNonNullableStaticFieldTest extends DriverResolutionTest {
   @override
   AnalysisOptionsImpl get analysisOptions =>
       AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
 
-  test_hasInitializer() async {
+  test_futureOr_questionArgument_none() async {
     assertNoErrorsInCode('''
-f() {
-  int v = 0;
+import 'dart:async';
+
+class A {
+  static FutureOr<int?> v;
 }
 ''');
   }
 
-  test_late() async {
+  test_hasInitializer() async {
     assertNoErrorsInCode('''
-f() {
-  late int v;
+class A {
+  static int v = 0;
 }
 ''');
   }
 
   test_noInitializer() async {
     assertErrorsInCode('''
-f() {
-  int v;
+class A {
+  static int x = 0, y, z = 2;
 }
 ''', [
-      error(
-          CompileTimeErrorCode
-              .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
-          12,
+      error(CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD, 30,
           1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 12, 1),
-    ]);
-  }
-
-  test_noInitializer_typeParameter() async {
-    assertErrorsInCode('''
-f<T>() {
-  T v;
-}
-''', [
-      error(
-          CompileTimeErrorCode
-              .NOT_INITIALIZED_POTENTIALLY_NON_NULLABLE_LOCAL_VARIABLE,
-          13,
-          1),
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 13, 1),
     ]);
   }
 
   test_nullable() async {
     assertNoErrorsInCode('''
-f() {
-  int? v;
+class A {
+  static int? v;
 }
 ''');
   }
 
   test_type_dynamic() async {
     assertNoErrorsInCode('''
-f() {
-  dynamic v;
+class A {
+  static dynamic v;
 }
 ''');
   }
 
-  test_type_dynamicImplicit() async {
+  test_type_dynamic_implicit() async {
     assertNoErrorsInCode('''
-f() {
-  var v;
+class A {
+  static var v;
 }
 ''');
   }
 
+  test_type_never() async {
+    assertErrorsInCode('''
+class A {
+  static Never v;
+}
+''', [
+      error(CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_STATIC_FIELD, 25,
+          1),
+    ]);
+  }
+
   test_type_void() async {
     assertNoErrorsInCode('''
-f() {
-  void v;
+class A {
+  static void v;
 }
 ''');
   }
diff --git a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
index 9399e70..218e4ef 100644
--- a/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_initialized_non_nullable_top_level_variable_test.dart
@@ -22,6 +22,14 @@
   AnalysisOptionsImpl get analysisOptions =>
       AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
 
+  test_futureOr_questionArgument_none() async {
+    assertNoErrorsInCode('''
+import 'dart:async';
+
+FutureOr<int?> v;
+''');
+  }
+
   test_hasInitializer() async {
     assertNoErrorsInCode('''
 int v = 0;
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 61643d4..810392d 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -96,10 +96,12 @@
 import 'non_constant_spread_expression_from_deferred_library_test.dart'
     as non_constant_spread_expression_from_deferred_library;
 import 'non_null_opt_out_test.dart' as non_null_opt_out;
+import 'not_assigned_potentially_non_nullable_local_variable_test.dart'
+    as not_assigned_potentially_non_nullable_local_variable;
+import 'not_initialized_non_nullable_static_field_test.dart'
+    as not_initialized_non_nullable_static_field;
 import 'not_initialized_non_nullable_top_level_variable_test.dart'
     as not_initialized_non_nullable_top_level_variable;
-import 'not_initialized_potentially_non_nullable_local_variable_test.dart'
-    as not_initialized_potentially_non_nullable_local_variable;
 import 'not_iterable_spread_test.dart' as not_iterable_spread;
 import 'not_map_spread_test.dart' as not_map_spread;
 import 'not_null_aware_null_spread_test.dart' as not_null_aware_null_spread;
@@ -239,8 +241,9 @@
     non_constant_set_element_from_deferred_library.main();
     non_constant_spread_expression_from_deferred_library.main();
     non_null_opt_out.main();
+    not_assigned_potentially_non_nullable_local_variable.main();
+    not_initialized_non_nullable_static_field.main();
     not_initialized_non_nullable_top_level_variable.main();
-    not_initialized_potentially_non_nullable_local_variable.main();
     not_iterable_spread.main();
     not_map_spread.main();
     not_null_aware_null_spread.main();
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 3a24bb1..8d7a3e5 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -327,7 +327,7 @@
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
     var field = cls.fields[0];
-    expect(field.type.toString(), 'int Function(Never)');
+    expect(field.type.toString(), 'int Function<T>(T)');
   }
 
   void test_inferredType_instanceField_dynamic() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 282c385..3ab3089 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -136,14 +136,6 @@
     return elementFactory.libraryOfUri('${source.uri}');
   }
 
-  @override
-  @failingTest
-  test_syntheticFunctionType_genericClosure() async {
-    // TODO(scheglov) Bug in TypeSystem.getLeastUpperBound().
-    // LUB(<T>(T) → int, <T>(T) → int) gives `(T) → int`, note absence of `<T>`.
-    await super.test_syntheticFunctionType_genericClosure();
-  }
-
   void _addLibraryUnits(
     Source definingSource,
     CompilationUnit definingUnit,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index f4c870d..4e184c6 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9431,7 +9431,7 @@
 bool f() => true;
 ''');
     checkElementText(library, r'''
-final int Function(Never) v;
+final int Function<T>(T) v;
 bool f() {}
 ''');
   }
@@ -9580,6 +9580,21 @@
 ''');
   }
 
+  test_type_inference_fieldFormal_depends_onField() async {
+    var library = await checkLibrary('''
+class A<T> {
+  var f = 0;
+  A(this.f);
+}
+''');
+    checkElementText(library, r'''
+class A<T> {
+  int f;
+  A(int this.f);
+}
+''');
+  }
+
   test_type_inference_multiplyDefinedElement() async {
     addLibrarySource('/a.dart', 'class C {}');
     addLibrarySource('/b.dart', 'class C {}');
@@ -9622,6 +9637,34 @@
 ''');
   }
 
+  test_type_inference_topVariable_depends_onFieldFormal() async {
+    var library = await checkLibrary('''
+class A {}
+
+class B extends A {}
+
+class C<T extends A> {
+  final T f;
+  const C(this.f);
+}
+
+final b = B();
+final c = C(b);
+''');
+    checkElementText(library, r'''
+class A {
+}
+class B extends A {
+}
+class C<T extends A> {
+  final T f;
+  const C(T this.f);
+}
+final B b;
+final C<B> c;
+''');
+  }
+
   test_type_invalid_topLevelVariableElement_asType() async {
     var library = await checkLibrary('''
 class C<T extends V> {}
diff --git a/pkg/analyzer/test/util/id_equivalence_helper.dart b/pkg/analyzer/test/util/id_equivalence_helper.dart
new file mode 100644
index 0000000..20ace3c
--- /dev/null
+++ b/pkg/analyzer/test/util/id_equivalence_helper.dart
@@ -0,0 +1,474 @@
+// Copyright (c) 2019, 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.
+
+// Note: this file contains code that was mostly copied from
+// tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+// and then tweaked to work with the analyzer.
+// TODO(paulberry,johnniwinther): share this code between the analyzer and
+// dart2js.
+
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart' hide Annotation;
+import 'package:front_end/src/testing/annotated_code_helper.dart';
+import 'package:front_end/src/testing/id.dart'
+    show ActualData, Id, IdValue, MemberId, NodeId;
+
+/// Checks [compiledData] against the expected data in [expectedMap] derived
+/// from [code].
+Future<bool> checkCode<T>(
+    String mode,
+    Uri mainFileUri,
+    Map<Uri, AnnotatedCode> code,
+    MemberAnnotations<IdValue> expectedMaps,
+    CompiledData compiledData,
+    DataInterpreter<T> dataValidator,
+    {bool filterActualData(IdValue expected, ActualData<T> actualData),
+    bool fatalErrors: true}) async {
+  IdData<T> data = new IdData<T>(code, expectedMaps, compiledData);
+  bool hasFailure = false;
+  Set<Uri> neededDiffs = new Set<Uri>();
+
+  void checkActualMap(
+      Map<Id, ActualData<T>> actualMap, Map<Id, IdValue> expectedMap,
+      [Uri uri]) {
+    bool hasLocalFailure = false;
+    actualMap.forEach((Id id, ActualData<T> actualData) {
+      T actual = actualData.value;
+      String actualText = dataValidator.getText(actual);
+
+      if (!expectedMap.containsKey(id)) {
+        if (!dataValidator.isEmpty(actual)) {
+          reportError(
+              actualData.offset,
+              'EXTRA $mode DATA for ${id.descriptor}:\n '
+              'object   : ${actualData.objectText}\n '
+              'actual   : ${colorizeActual('${IdValue.idToString(id, actualText)}')}\n '
+              'Data was expected for these ids: ${expectedMap.keys}');
+          if (filterActualData == null || filterActualData(null, actualData)) {
+            hasLocalFailure = true;
+          }
+        }
+      } else {
+        IdValue expected = expectedMap[id];
+        String unexpectedMessage =
+            dataValidator.isAsExpected(actual, expected.value);
+        if (unexpectedMessage != null) {
+          reportError(
+              actualData.offset,
+              'UNEXPECTED $mode DATA for ${id.descriptor}:\n '
+              'detail  : ${colorizeMessage(unexpectedMessage)}\n '
+              'object  : ${actualData.objectText}\n '
+              'expected: ${colorizeExpected('$expected')}\n '
+              'actual  : ${colorizeActual('${IdValue.idToString(id, actualText)}')}');
+          if (filterActualData == null ||
+              filterActualData(expected, actualData)) {
+            hasLocalFailure = true;
+          }
+        }
+      }
+    });
+    if (hasLocalFailure) {
+      hasFailure = true;
+      if (uri != null) {
+        neededDiffs.add(uri);
+      }
+    }
+  }
+
+  data.actualMaps.forEach((Uri uri, Map<Id, ActualData<T>> actualMap) {
+    checkActualMap(actualMap, data.expectedMaps[uri], uri);
+  });
+  checkActualMap(data.actualMaps.globalData, data.expectedMaps.globalData);
+
+  Set<Id> missingIds = new Set<Id>();
+  void checkMissing(
+      Map<Id, IdValue> expectedMap, Map<Id, ActualData<T>> actualMap,
+      [Uri uri]) {
+    expectedMap.forEach((Id id, IdValue expected) {
+      if (!actualMap.containsKey(id)) {
+        missingIds.add(id);
+        String message = 'MISSING $mode DATA for ${id.descriptor}: '
+            'Expected ${colorizeExpected('$expected')}';
+        if (uri != null) {
+          var begin = data.getOffsetFromId(id, uri);
+          reportError(begin, message);
+        } else {
+          print(message);
+        }
+      }
+    });
+    if (missingIds.isNotEmpty && uri != null) {
+      neededDiffs.add(uri);
+    }
+  }
+
+  data.expectedMaps.forEach((Uri uri, Map<Id, IdValue> expectedMap) {
+    checkMissing(expectedMap, data.actualMaps[uri], uri);
+  });
+  checkMissing(data.expectedMaps.globalData, data.actualMaps.globalData);
+  for (Uri uri in neededDiffs) {
+    print('--annotations diff [${uri.pathSegments.last}]-------------');
+    print(data.diffCode(uri, dataValidator));
+    print('----------------------------------------------------------');
+  }
+  if (missingIds.isNotEmpty) {
+    print("MISSING ids: $missingIds.");
+    hasFailure = true;
+  }
+  if (hasFailure && fatalErrors) {
+    throw StateError('Errors found.');
+  }
+  return hasFailure;
+}
+
+Future<bool> checkTests<T>(
+    String rawCode,
+    Future<ResolvedUnitResult> resultComputer(String rawCode),
+    DataComputer<T> dataComputer) async {
+  AnnotatedCode code =
+      new AnnotatedCode.fromText(rawCode, commentStart, commentEnd);
+  var result = await resultComputer(code.sourceCode);
+  var uri = result.libraryElement.source.uri;
+  var marker = 'normal';
+  Map<String, MemberAnnotations<IdValue>> expectedMaps = {
+    marker: new MemberAnnotations<IdValue>(),
+  };
+  computeExpectedMap(uri, code, expectedMaps);
+  MemberAnnotations<IdValue> annotations = expectedMaps[marker];
+  Map<Id, ActualData<T>> actualMap = {};
+  dataComputer.computeUnitData(result.unit, actualMap);
+  var compiledData = CompiledData<T>(uri, {uri: actualMap}, {});
+  return await checkCode(marker, uri, {uri: code}, annotations, compiledData,
+      dataComputer.dataValidator);
+}
+
+/// Colorize the actual annotation [text], if ANSI colors are supported.
+String colorizeActual(String text) {
+  return text;
+}
+
+/// Colorize annotation delimiters [start] and [end] surrounding [text], if
+/// ANSI colors are supported.
+String colorizeAnnotation(String start, String text, String end) {
+  return '${colorizeDelimiter(start)}$text${colorizeDelimiter(end)}';
+}
+
+/// Colorize delimiter [text], if ANSI colors are supported.
+String colorizeDelimiter(String text) {
+  return text;
+}
+
+/// Colorize diffs [expected] and [actual] and [delimiter], if ANSI colors are
+/// supported.
+String colorizeDiff(String expected, String delimiter, String actual) {
+  return '${colorizeExpected(expected)}'
+      '${colorizeDelimiter(delimiter)}${colorizeActual(actual)}';
+}
+
+/// Colorize an expected annotation [text], if ANSI colors are supported.
+String colorizeExpected(String text) {
+  return text;
+}
+
+/// Colorize a matching annotation [text], if ANSI colors are supported.
+String colorizeMatch(String text) {
+  return text;
+}
+
+/// Colorize a message [text], if ANSI colors are supported.
+String colorizeMessage(String text) {
+  return text;
+}
+
+/// Compute three [MemberAnnotations] objects from [code] specifying the
+/// expected annotations we anticipate encountering; one corresponding to the
+/// old implementation, one for the new implementation, and one for the new
+/// implementation using strong mode.
+///
+/// If an annotation starts with 'ast.' it is only expected for the old
+/// implementation, if it starts with 'kernel.' it is only expected for the
+/// new implementation, and if it starts with 'strong.' it is only expected for
+/// strong mode (using the common frontend). Otherwise it is expected for all
+/// implementations.
+///
+/// Most nodes have the same and expectations should match this by using
+/// annotations without prefixes.
+void computeExpectedMap(Uri sourceUri, AnnotatedCode code,
+    Map<String, MemberAnnotations<IdValue>> maps) {
+  List<String> mapKeys = maps.keys.toList();
+  Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys);
+
+  split.forEach((String marker, AnnotatedCode code) {
+    MemberAnnotations<IdValue> fileAnnotations = maps[marker];
+    assert(fileAnnotations != null, "No annotations for $marker in $maps");
+    Map<Id, IdValue> expectedValues = fileAnnotations[sourceUri];
+    for (Annotation annotation in code.annotations) {
+      String text = annotation.text;
+      IdValue idValue = IdValue.decode(annotation.offset, text);
+      if (idValue.id.isGlobal) {
+        _expectFalse(
+            fileAnnotations.globalData.containsKey(idValue.id),
+            "Duplicate annotations for ${idValue.id} in $marker: "
+            "$idValue and ${fileAnnotations.globalData[idValue.id]}.");
+        fileAnnotations.globalData[idValue.id] = idValue;
+      } else {
+        _expectFalse(
+            expectedValues.containsKey(idValue.id),
+            "Duplicate annotations for ${idValue.id} in $marker: "
+            "$idValue and ${expectedValues[idValue.id]}.");
+        expectedValues[idValue.id] = idValue;
+      }
+    }
+  });
+}
+
+/// Reports [message] as an error using [spannable] as error location.
+void reportError(int offset, String message) {
+  print('$offset: $message');
+}
+
+String withAnnotations(String sourceCode, Map<int, List<String>> annotations) {
+  StringBuffer sb = new StringBuffer();
+  int end = 0;
+  for (int offset in annotations.keys.toList()..sort()) {
+    if (offset >= sourceCode.length) {
+      sb.write('...');
+      return sb.toString();
+    }
+    if (offset > end) {
+      sb.write(sourceCode.substring(end, offset));
+    }
+    for (String annotation in annotations[offset]) {
+      sb.write(colorizeAnnotation('/*', annotation, '*/'));
+    }
+    end = offset;
+  }
+  if (end < sourceCode.length) {
+    sb.write(sourceCode.substring(end));
+  }
+  return sb.toString();
+}
+
+void _expectFalse(bool b, String message) {
+  if (b) {
+    throw StateError(message);
+  }
+}
+
+class CompiledData<T> {
+  final Uri mainUri;
+  final Map<Uri, Map<Id, ActualData<T>>> actualMaps;
+  final Map<Id, ActualData<T>> globalData;
+
+  CompiledData(this.mainUri, this.actualMaps, this.globalData);
+
+  Map<int, List<String>> computeAnnotations(Uri uri) {
+    Map<Id, ActualData<T>> thisMap = actualMaps[uri];
+    Map<int, List<String>> annotations = <int, List<String>>{};
+    thisMap.forEach((Id id, ActualData<T> data1) {
+      String value1 = '${data1.value}';
+      annotations
+          .putIfAbsent(data1.offset, () => [])
+          .add(colorizeActual(value1));
+    });
+    return annotations;
+  }
+
+  Map<int, List<String>> computeDiffAnnotationsAgainst(
+      Map<Id, ActualData<T>> thisMap, Map<Id, ActualData<T>> otherMap, Uri uri,
+      {bool includeMatches: false}) {
+    Map<int, List<String>> annotations = <int, List<String>>{};
+    thisMap.forEach((Id id, ActualData<T> data1) {
+      ActualData<T> data2 = otherMap[id];
+      String value1 = '${data1.value}';
+      if (data1.value != data2?.value) {
+        String value2 = '${data2?.value ?? '---'}';
+        annotations
+            .putIfAbsent(data1.offset, () => [])
+            .add(colorizeDiff(value1, ' | ', value2));
+      } else if (includeMatches) {
+        annotations
+            .putIfAbsent(data1.offset, () => [])
+            .add(colorizeMatch(value1));
+      }
+    });
+    otherMap.forEach((Id id, ActualData<T> data2) {
+      if (!thisMap.containsKey(id)) {
+        String value1 = '---';
+        String value2 = '${data2.value}';
+        annotations
+            .putIfAbsent(data2.offset, () => [])
+            .add(colorizeDiff(value1, ' | ', value2));
+      }
+    });
+    return annotations;
+  }
+}
+
+abstract class DataComputer<T> {
+  const DataComputer();
+
+  DataInterpreter<T> get dataValidator;
+
+  /// Function that computes a data mapping for [unit].
+  ///
+  /// Fills [actualMap] with the data and [sourceSpanMap] with the source spans
+  /// for the data origin.
+  void computeUnitData(CompilationUnit unit, Map<Id, ActualData<T>> actualMap);
+}
+
+/// Interface used for interpreting annotations.
+abstract class DataInterpreter<T> {
+  /// Returns a textual representation of [actualData].
+  String getText(T actualData);
+
+  /// Returns `null` if [actualData] satisfies the [expectedData] annotation.
+  /// Otherwise, a message is returned contain the information about the
+  /// problems found.
+  String isAsExpected(T actualData, String expectedData);
+
+  /// Returns `true` if [actualData] corresponds to empty data.
+  bool isEmpty(T actualData);
+}
+
+/// Data collected by [computeData].
+class IdData<T> {
+  final Map<Uri, AnnotatedCode> code;
+  final MemberAnnotations<IdValue> expectedMaps;
+  final CompiledData _compiledData;
+  final MemberAnnotations<ActualData<T>> _actualMaps = new MemberAnnotations();
+
+  IdData(this.code, this.expectedMaps, this._compiledData) {
+    for (Uri uri in code.keys) {
+      _actualMaps[uri] = _compiledData.actualMaps[uri] ?? <Id, ActualData<T>>{};
+    }
+    _actualMaps.globalData.addAll(_compiledData.globalData);
+  }
+
+  MemberAnnotations<ActualData<T>> get actualMaps => _actualMaps;
+  Uri get mainUri => _compiledData.mainUri;
+
+  String actualCode(Uri uri) {
+    Map<int, List<String>> annotations = <int, List<String>>{};
+    actualMaps[uri].forEach((Id id, ActualData<T> data) {
+      annotations.putIfAbsent(data.offset, () => []).add('${data.value}');
+    });
+    return withAnnotations(code[uri].sourceCode, annotations);
+  }
+
+  String diffCode(Uri uri, DataInterpreter<T> dataValidator) {
+    Map<int, List<String>> annotations = <int, List<String>>{};
+    actualMaps[uri].forEach((Id id, ActualData<T> data) {
+      IdValue expectedValue = expectedMaps[uri][id];
+      T actualValue = data.value;
+      String unexpectedMessage =
+          dataValidator.isAsExpected(actualValue, expectedValue?.value);
+      if (unexpectedMessage != null) {
+        String expected = expectedValue?.toString() ?? '';
+        String actual = dataValidator.getText(actualValue);
+        int offset = getOffsetFromId(id, uri);
+        if (offset != null) {
+          String value1 = '$expected';
+          String value2 = IdValue.idToString(id, '$actual');
+          annotations
+              .putIfAbsent(offset, () => [])
+              .add(colorizeDiff(value1, ' | ', value2));
+        }
+      }
+    });
+    expectedMaps[uri].forEach((Id id, IdValue expected) {
+      if (!actualMaps[uri].containsKey(id)) {
+        int offset = getOffsetFromId(id, uri);
+        if (offset != null) {
+          String value1 = '$expected';
+          String value2 = '---';
+          annotations
+              .putIfAbsent(offset, () => [])
+              .add(colorizeDiff(value1, ' | ', value2));
+        }
+      }
+    });
+    return withAnnotations(code[uri].sourceCode, annotations);
+  }
+
+  int getOffsetFromId(Id id, Uri uri) {
+    if (id is NodeId) {
+      return id.value;
+    } else if (id is MemberId) {
+      if (id.className != null) {
+        throw UnimplementedError('TODO(paulberry): handle class members');
+      }
+      var name = id.memberName;
+      var unit =
+          parseString(content: code[uri].sourceCode, throwIfDiagnostics: false)
+              .unit;
+      for (var declaration in unit.declarations) {
+        if (declaration is FunctionDeclaration) {
+          if (declaration.name.name == name) {
+            return declaration.offset;
+          }
+        }
+      }
+      throw StateError('Member not found: $name');
+    } else {
+      throw StateError('Unexpected id ${id.runtimeType}');
+    }
+  }
+}
+
+/// Encapsulates the member data computed for each source file of interest.
+/// It's a glorified wrapper around a map of maps, but written this way to
+/// provide a little more information about what it's doing. [DataType] refers
+/// to the type this map is holding -- it is either [IdValue] or [ActualData].
+class MemberAnnotations<DataType> {
+  /// For each Uri, we create a map associating an element id with its
+  /// corresponding annotations.
+  final Map<Uri, Map<Id, DataType>> _computedDataForEachFile =
+      new Map<Uri, Map<Id, DataType>>();
+
+  /// Member or class annotations that don't refer to any of the user files.
+  final Map<Id, DataType> globalData = <Id, DataType>{};
+
+  Map<Id, DataType> operator [](Uri file) {
+    if (!_computedDataForEachFile.containsKey(file)) {
+      _computedDataForEachFile[file] = <Id, DataType>{};
+    }
+    return _computedDataForEachFile[file];
+  }
+
+  void operator []=(Uri file, Map<Id, DataType> computedData) {
+    _computedDataForEachFile[file] = computedData;
+  }
+
+  void forEach(void f(Uri file, Map<Id, DataType> computedData)) {
+    _computedDataForEachFile.forEach(f);
+  }
+
+  @override
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('MemberAnnotations(');
+    String comma = '';
+    if (_computedDataForEachFile.isNotEmpty &&
+        (_computedDataForEachFile.length > 1 ||
+            _computedDataForEachFile.values.single.isNotEmpty)) {
+      sb.write('data:{');
+      _computedDataForEachFile.forEach((Uri uri, Map<Id, DataType> data) {
+        sb.write(comma);
+        sb.write('$uri:');
+        sb.write(data);
+        comma = ',';
+      });
+      sb.write('}');
+    }
+    if (globalData.isNotEmpty) {
+      sb.write(comma);
+      sb.write('global:');
+      sb.write(globalData);
+    }
+    sb.write(')');
+    return sb.toString();
+  }
+}
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 07190a4..37bc80a 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -216,7 +216,7 @@
  */
 class TypeAssertions {
   // TODO(leafp): Make these matchers.
-  // https://www.dartdocs.org/documentation/matcher/0.12.0%2B1/matcher/Matcher-class.html
+  // https://pub.dev/documentation/matcher/latest/matcher/Matcher-class.html
 
   /**
    * Provides primitive types for basic type assertions.
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index b218815..7a9f931 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -393,8 +393,8 @@
         NullValue.Metadata);
   }
 
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     debugEvent("Method");
     pop(); // Body
     pop(); // Initializers
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 617bdf9..2d88a91 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -46,7 +46,7 @@
   final Set<String> files = new Set<String>();
 
   /// All [AnalysisErrorInfo]s in the analyzed library.
-  final List<AnalysisErrorInfo> errorInfos = new List<AnalysisErrorInfo>();
+  final List<ErrorsResult> errorsResults = [];
 
   /// If the file specified on the command line is part of a package, the name
   /// of that package.  Otherwise `null`.  This allows us to analyze the file
@@ -108,8 +108,8 @@
   /// Returns the maximal [ErrorSeverity] of the recorded errors.
   ErrorSeverity computeMaxErrorSeverity() {
     ErrorSeverity status = ErrorSeverity.NONE;
-    for (AnalysisErrorInfo errorInfo in errorInfos) {
-      for (AnalysisError error in errorInfo.errors) {
+    for (ErrorsResult result in errorsResults) {
+      for (AnalysisError error in result.errors) {
         if (_defaultSeverityProcessor(error) == null) {
           continue;
         }
@@ -119,7 +119,7 @@
     return status;
   }
 
-  /// Fills [errorInfos] using [files].
+  /// Fills [errorsResults] using [files].
   Future<void> prepareErrors() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -127,8 +127,7 @@
     try {
       for (String path in files) {
         ErrorsResult errorsResult = await analysisDriver.getErrors(path);
-        errorInfos.add(new AnalysisErrorInfoImpl(
-            errorsResult.errors, errorsResult.lineInfo));
+        errorsResults.add(errorsResult);
       }
     } finally {
       previous.makeCurrent();
@@ -145,7 +144,7 @@
   /// Setup local fields such as the analysis context for analysis.
   void setupForAnalysis() {
     files.clear();
-    errorInfos.clear();
+    errorsResults.clear();
     Uri libraryUri = libraryFile.uri;
     if (libraryUri.scheme == 'package' && libraryUri.pathSegments.length > 0) {
       _selfPackageName = libraryUri.pathSegments[0];
@@ -170,7 +169,7 @@
 
     // Print errors and performance numbers.
     if (printMode == 1) {
-      formatter.formatErrors(errorInfos);
+      formatter.formatErrors(errorsResults);
     } else if (printMode == 2) {
       _printColdPerf();
     }
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index c50528d..dd86768 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -633,9 +633,7 @@
               severityProcessor: severityProcessor);
       for (Source source in explicitSources) {
         var result = await analysisDriver.getErrors(source.fullName);
-        var errorInfo =
-            new AnalysisErrorInfoImpl(result.errors, result.lineInfo);
-        formatter.formatErrors([errorInfo]);
+        formatter.formatErrors([result]);
       }
       formatter.flush();
       if (!options.machineFormat) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index bd54543..9252730 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -23,8 +24,8 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart'
     show PerformanceTag;
-import 'package:analyzer/src/plugin/resolver_provider.dart';
 import 'package:analyzer/src/manifest/manifest_validator.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/source/path_filter.dart';
@@ -350,7 +351,10 @@
           LineInfo lineInfo = new LineInfo.fromContent(content);
           List<AnalysisError> errors = analyzeAnalysisOptions(
               file.createSource(), content, analysisDriver.sourceFactory);
-          formatter.formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+          formatter.formatErrors([
+            ErrorsResultImpl(analysisDriver.currentSession, path, null,
+                lineInfo, false, errors)
+          ]);
           for (AnalysisError error in errors) {
             ErrorSeverity severity = determineProcessedSeverity(
                 error, options, analysisDriver.analysisOptions);
@@ -368,8 +372,10 @@
                   new PubspecValidator(resourceProvider, file.createSource());
               LineInfo lineInfo = new LineInfo.fromContent(content);
               List<AnalysisError> errors = validator.validate(node.nodes);
-              formatter
-                  .formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+              formatter.formatErrors([
+                ErrorsResultImpl(analysisDriver.currentSession, path, null,
+                    lineInfo, false, errors)
+              ]);
               for (AnalysisError error in errors) {
                 ErrorSeverity severity = determineProcessedSeverity(
                     error, options, analysisDriver.analysisOptions);
@@ -388,8 +394,10 @@
             LineInfo lineInfo = new LineInfo.fromContent(content);
             List<AnalysisError> errors = validator.validate(
                 content, analysisDriver.analysisOptions.chromeOsManifestChecks);
-            formatter
-                .formatErrors([new AnalysisErrorInfoImpl(errors, lineInfo)]);
+            formatter.formatErrors([
+              ErrorsResultImpl(analysisDriver.currentSession, path, null,
+                  lineInfo, false, errors)
+            ]);
             for (AnalysisError error in errors) {
               ErrorSeverity severity = determineProcessedSeverity(
                   error, options, analysisDriver.analysisOptions);
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index e6e61f4..51e1333 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -2,9 +2,10 @@
 // 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:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_cli/src/ansi.dart';
 import 'package:analyzer_cli/src/options.dart';
@@ -109,6 +110,7 @@
   final int line;
   final int column;
   final String message;
+  final List<ContextMessage> contextMessages;
   final String errorCode;
   final String correction;
   final String url;
@@ -120,6 +122,7 @@
     this.line,
     this.column,
     this.message,
+    this.contextMessages,
     this.errorCode,
     this.correction,
     this.url,
@@ -161,6 +164,14 @@
   }
 }
 
+class ContextMessage {
+  final String filePath;
+  final String message;
+  final int line;
+  final int column;
+  ContextMessage(this.filePath, this.message, this.line, this.column);
+}
+
 /// Helper for formatting [AnalysisError]s.
 ///
 /// The two format options are a user consumable format and a machine consumable
@@ -181,19 +192,18 @@
   void flush();
 
   void formatError(
-      Map<AnalysisError, LineInfo> errorToLine, AnalysisError error);
+      Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error);
 
-  void formatErrors(List<AnalysisErrorInfo> errorInfos) {
-    stats.unfilteredCount += errorInfos.length;
+  void formatErrors(List<ErrorsResult> results) {
+    stats.unfilteredCount += results.length;
 
     List<AnalysisError> errors = new List<AnalysisError>();
-    Map<AnalysisError, LineInfo> errorToLine =
-        new Map<AnalysisError, LineInfo>();
-    for (AnalysisErrorInfo errorInfo in errorInfos) {
-      for (AnalysisError error in errorInfo.errors) {
+    Map<AnalysisError, ErrorsResult> errorToLine = {};
+    for (ErrorsResult result in results) {
+      for (AnalysisError error in result.errors) {
         if (_computeSeverity(error) != null) {
           errors.add(error);
-          errorToLine[error] = errorInfo.lineInfo;
+          errorToLine[error] = result;
         }
       }
     }
@@ -253,6 +263,11 @@
       // If verbose, also print any associated correction and URL.
       if (options.verbose) {
         String padding = ' '.padLeft(error.severity.length + 2);
+        for (var message in error.contextMessages) {
+          out.write('$padding${message.message} ');
+          out.write('at ${message.filePath}');
+          out.writeln(':${message.line}:${message.column}');
+        }
         if (error.correction != null) {
           out.writeln('$padding${error.correction}');
         }
@@ -267,9 +282,10 @@
   }
 
   void formatError(
-      Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+      Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
     Source source = error.source;
-    var location = errorToLine[error].getLocation(error.offset);
+    var result = errorToLine[error];
+    var location = result.lineInfo.getLocation(error.offset);
 
     ErrorSeverity severity = _severityProcessor(error);
 
@@ -300,6 +316,17 @@
     } else {
       sourcePath = _relative(source.fullName);
     }
+    List<ContextMessage> contextMessages = [];
+    for (var message in error.contextMessages) {
+      var session = result.session.analysisContext;
+      if (session is DriverBasedAnalysisContext) {
+        LineInfo lineInfo =
+            session.driver.getFileSync(message.filePath)?.lineInfo;
+        var location = lineInfo.getLocation(message.offset);
+        contextMessages.add(ContextMessage(message.filePath, message.message,
+            location.lineNumber, location.columnNumber));
+      }
+    }
 
     batchedErrors.add(new CLIError(
       severity: errorType,
@@ -308,6 +335,7 @@
       line: location.lineNumber,
       column: location.columnNumber,
       message: message,
+      contextMessages: contextMessages,
       errorCode: error.errorCode.name.toLowerCase(),
       correction: error.correction,
       url: error.errorCode.url,
@@ -330,13 +358,13 @@
   void flush() {}
 
   void formatError(
-      Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
+      Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
     // Ensure we don't over-report (#36062).
     if (!_seenErrors.add(error)) {
       return;
     }
     Source source = error.source;
-    var location = errorToLine[error].getLocation(error.offset);
+    var location = errorToLine[error].lineInfo.getLocation(error.offset);
     int length = error.length;
 
     ErrorSeverity severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index b5e5627..0095948 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -23,15 +23,12 @@
   String message;
 
   @override
-  bool isStaticOnly;
-
-  @override
   int length;
 
   MockAnalysisError(this.source, this.errorCode, this.offset, this.message);
 
   @override
-  List<DiagnosticMessage> get contextMessages => null;
+  List<DiagnosticMessage> get contextMessages => const [];
 
   @override
   String get correction => null;
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 26d37ac..e7f359b 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer_cli/src/ansi.dart' as ansi;
 import 'package:analyzer_cli/src/error_formatter.dart';
 import 'package:test/test.dart' hide ErrorFormatter;
@@ -39,8 +39,8 @@
     });
 
     test('error', () {
-      AnalysisErrorInfo error =
-          mockError(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
+      ErrorsResultImpl error =
+          mockResult(ErrorType.SYNTACTIC_ERROR, ErrorSeverity.ERROR);
       reporter.formatErrors([error]);
       reporter.flush();
 
@@ -49,7 +49,7 @@
     });
 
     test('hint', () {
-      AnalysisErrorInfo error = mockError(ErrorType.HINT, ErrorSeverity.INFO);
+      ErrorsResultImpl error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
       reporter.formatErrors([error]);
       reporter.flush();
 
@@ -58,7 +58,7 @@
     });
 
     test('stats', () {
-      AnalysisErrorInfo error = mockError(ErrorType.HINT, ErrorSeverity.INFO);
+      ErrorsResultImpl error = mockResult(ErrorType.HINT, ErrorSeverity.INFO);
       reporter.formatErrors([error]);
       reporter.flush();
       stats.print(out);
@@ -70,7 +70,7 @@
   });
 }
 
-MockAnalysisErrorInfo mockError(ErrorType type, ErrorSeverity severity) {
+ErrorsResultImpl mockResult(ErrorType type, ErrorSeverity severity) {
   // ErrorInfo
   var location = new CharacterLocation(3, 3);
   var lineInfo = new MockLineInfo(defaultLocation: location);
@@ -80,5 +80,6 @@
   var source = new MockSource('/foo/bar/baz.dart');
   var error = new MockAnalysisError(source, code, 20, 'MSG');
 
-  return new MockAnalysisErrorInfo(lineInfo, [error]);
+  return ErrorsResultImpl(
+      null, source.fullName, null, lineInfo, false, [error]);
 }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index 99bb973..87c832c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -131,7 +131,7 @@
         _visitTypeParameters(declaration, declaration.typeParameters);
         _visitTypeParameters(
           declaration.functionType,
-          declaration.functionType.typeParameters,
+          declaration.functionType?.typeParameters,
         );
       } else if (declaration is MixinDeclaration) {
         declaredMixin(declaration);
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 801a18f..ebc6182 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -100,6 +100,9 @@
   /// Flag for a combination of flags for 'production' mode.
   static const String benchmarkingProduction = '--benchmarking-production';
 
+  /// Flag for a combination of flags for benchmarking 'experiment' mode.
+  static const String benchmarkingExperiment = '--benchmarking-x';
+
   static const String conditionalDirectives = '--conditional-directives';
 
   // The syntax-only level of support for generic methods is included in the
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 2778f65..d21986b 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -16,6 +16,7 @@
 import 'js_backend/native_data.dart' show NativeBasicData;
 import 'js_model/locals.dart';
 import 'kernel/dart2js_target.dart';
+import 'options.dart';
 import 'universe/selector.dart' show Selector;
 
 /// The common elements and types in Dart.
@@ -481,6 +482,9 @@
   // From dart:_rti
 
   FunctionEntity get findType;
+  FunctionEntity get instanceType;
+  FunctionEntity get typeLiteralMaker;
+  FunctionEntity get checkTypeBound;
   FieldEntity get rtiAsField;
   FieldEntity get rtiCheckField;
   FieldEntity get rtiIsField;
@@ -613,8 +617,9 @@
 class CommonElementsImpl
     implements CommonElements, KCommonElements, JCommonElements {
   final ElementEnvironment _env;
+  final CompilerOptions _options;
 
-  CommonElementsImpl(this._env);
+  CommonElementsImpl(this._env, this._options);
 
   ClassEntity _objectClass;
   @override
@@ -1442,7 +1447,9 @@
   ClassEntity _typeLiteralClass;
   @override
   ClassEntity get typeLiteralClass =>
-      _typeLiteralClass ??= _findHelperClass('TypeImpl');
+      _typeLiteralClass ??= _options.experimentNewRti
+          ? _findRtiClass('_Type')
+          : _findHelperClass('TypeImpl');
 
   ClassEntity _constMapLiteralClass;
   @override
@@ -1729,8 +1736,9 @@
       _findHelperFunction('throwNoSuchMethod');
 
   @override
-  FunctionEntity get createRuntimeType =>
-      _findHelperFunction('createRuntimeType');
+  FunctionEntity get createRuntimeType => _options.experimentNewRti
+      ? _findRtiFunction('_createRuntimeType')
+      : _findHelperFunction('createRuntimeType');
 
   @override
   FunctionEntity get fallThroughError =>
@@ -1804,6 +1812,8 @@
 
   // From dart:_rti
 
+  ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name);
+
   FunctionEntity _findRtiFunction(String name) =>
       _findLibraryMember(rtiLibrary, name);
 
@@ -1811,6 +1821,21 @@
   @override
   FunctionEntity get findType => _findType ??= _findRtiFunction('findType');
 
+  FunctionEntity _instanceType;
+  @override
+  FunctionEntity get instanceType =>
+      _instanceType ??= _findRtiFunction('instanceType');
+
+  FunctionEntity _typeLiteralMaker;
+  @override
+  FunctionEntity get typeLiteralMaker =>
+      _typeLiteralMaker ??= _findRtiFunction('typeLiteral');
+
+  FunctionEntity _checkTypeBound;
+  @override
+  FunctionEntity get checkTypeBound =>
+      _checkTypeBound ??= _findRtiFunction('checkTypeBound');
+
   ClassEntity get _rtiImplClass => _findClass(rtiLibrary, 'Rti');
   FieldEntity _findRtiClassField(String name) =>
       _findClassMember(_rtiImplClass, name);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 7348d20..f961525 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -456,6 +456,7 @@
     new OptionHandler(Flags.omitAsCasts, passThrough),
     new OptionHandler(Flags.laxRuntimeTypeToString, passThrough),
     new OptionHandler(Flags.benchmarkingProduction, passThrough),
+    new OptionHandler(Flags.benchmarkingExperiment, passThrough),
 
     // TODO(floitsch): remove conditional directives flag.
     // We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 118d4ed..437ff2a 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -1336,7 +1336,8 @@
     Map<ClassEntity, OutputUnit> classToUnit = source.readClassMap(() {
       return outputUnits[source.readInt()];
     });
-    Map<MemberEntity, OutputUnit> memberToUnit = source.readMemberMap(() {
+    Map<MemberEntity, OutputUnit> memberToUnit =
+        source.readMemberMap((MemberEntity member) {
       return outputUnits[source.readInt()];
     });
     Map<ConstantValue, OutputUnit> constantToUnit = source.readConstantMap(() {
@@ -1387,7 +1388,8 @@
     sink.writeClassMap(_classToUnit, (OutputUnit outputUnit) {
       sink.writeInt(outputUnitIndices[outputUnit]);
     });
-    sink.writeMemberMap(_memberToUnit, (OutputUnit outputUnit) {
+    sink.writeMemberMap(_memberToUnit,
+        (MemberEntity member, OutputUnit outputUnit) {
       sink.writeInt(outputUnitIndices[outputUnit]);
     });
     sink.writeConstantMap(_constantToUnit, (OutputUnit outputUnit) {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index d34c1d0..200d368 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1125,6 +1125,14 @@
 
   /// Try to find the length given to a fixed array constructor call.
   int _findLength(ir.Arguments arguments) {
+    int finish(int length) {
+      // Filter out lengths that should not be tracked.
+      if (length < 0) return null;
+      // Serialization limit.
+      if (length >= (1 << 30)) return null;
+      return length;
+    }
+
     ir.Expression firstArgument = arguments.positional.first;
     if (firstArgument is ir.ConstantExpression &&
         firstArgument.constant is ir.DoubleConstant) {
@@ -1132,10 +1140,10 @@
       double doubleValue = constant.value;
       int truncatedValue = doubleValue.truncate();
       if (doubleValue == truncatedValue) {
-        return truncatedValue;
+        return finish(truncatedValue);
       }
     } else if (firstArgument is ir.IntLiteral) {
-      return firstArgument.value;
+      return finish(firstArgument.value);
     } else if (firstArgument is ir.StaticGet) {
       MemberEntity member = _elementMap.getMember(firstArgument.target);
       if (member.isField) {
@@ -1143,7 +1151,9 @@
             _closedWorld.fieldAnalysis.getFieldData(member);
         if (fieldData.isEffectivelyConstant && fieldData.constantValue.isInt) {
           IntConstantValue intValue = fieldData.constantValue;
-          return intValue.intValue.toInt();
+          if (intValue.intValue.isValidInt) {
+            return finish(intValue.intValue.toInt());
+          }
         }
       }
     }
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 6266882..bf214c1 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -1433,49 +1433,59 @@
 
   /// Deserializes a [GlobalTypeInferenceElementData] object from [source].
   factory KernelGlobalTypeInferenceElementData.readFromDataSource(
-      DataSource source, AbstractValueDomain abstractValueDomain) {
-    source.begin(tag);
-    Map<ir.TreeNode, AbstractValue> sendMap = source.readTreeNodeMap(
-        () => abstractValueDomain.readAbstractValueFromDataSource(source),
-        emptyAsNull: true);
-    Map<ir.ForInStatement, AbstractValue> iteratorMap = source.readTreeNodeMap(
-        () => abstractValueDomain.readAbstractValueFromDataSource(source),
-        emptyAsNull: true);
-    Map<ir.ForInStatement, AbstractValue> currentMap = source.readTreeNodeMap(
-        () => abstractValueDomain.readAbstractValueFromDataSource(source),
-        emptyAsNull: true);
-    Map<ir.ForInStatement, AbstractValue> moveNextMap = source.readTreeNodeMap(
-        () => abstractValueDomain.readAbstractValueFromDataSource(source),
-        emptyAsNull: true);
-    source.end(tag);
-    return new KernelGlobalTypeInferenceElementData.internal(
-        sendMap, iteratorMap, currentMap, moveNextMap);
+      DataSource source,
+      ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    return source.inMemberContext(context, () {
+      source.begin(tag);
+      Map<ir.TreeNode, AbstractValue> sendMap = source.readTreeNodeMapInContext(
+          () => abstractValueDomain.readAbstractValueFromDataSource(source),
+          emptyAsNull: true);
+      Map<ir.ForInStatement, AbstractValue> iteratorMap =
+          source.readTreeNodeMapInContext(
+              () => abstractValueDomain.readAbstractValueFromDataSource(source),
+              emptyAsNull: true);
+      Map<ir.ForInStatement, AbstractValue> currentMap =
+          source.readTreeNodeMapInContext(
+              () => abstractValueDomain.readAbstractValueFromDataSource(source),
+              emptyAsNull: true);
+      Map<ir.ForInStatement, AbstractValue> moveNextMap =
+          source.readTreeNodeMapInContext(
+              () => abstractValueDomain.readAbstractValueFromDataSource(source),
+              emptyAsNull: true);
+      source.end(tag);
+      return new KernelGlobalTypeInferenceElementData.internal(
+          sendMap, iteratorMap, currentMap, moveNextMap);
+    });
   }
 
   @override
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
-    sink.begin(tag);
-    sink.writeTreeNodeMap(
-        _sendMap,
-        (AbstractValue value) =>
-            abstractValueDomain.writeAbstractValueToDataSink(sink, value),
-        allowNull: true);
-    sink.writeTreeNodeMap(
-        _iteratorMap,
-        (AbstractValue value) =>
-            abstractValueDomain.writeAbstractValueToDataSink(sink, value),
-        allowNull: true);
-    sink.writeTreeNodeMap(
-        _currentMap,
-        (AbstractValue value) =>
-            abstractValueDomain.writeAbstractValueToDataSink(sink, value),
-        allowNull: true);
-    sink.writeTreeNodeMap(
-        _moveNextMap,
-        (AbstractValue value) =>
-            abstractValueDomain.writeAbstractValueToDataSink(sink, value),
-        allowNull: true);
-    sink.end(tag);
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
+    sink.inMemberContext(context, () {
+      sink.begin(tag);
+      sink.writeTreeNodeMapInContext(
+          _sendMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _iteratorMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _currentMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.writeTreeNodeMapInContext(
+          _moveNextMap,
+          (AbstractValue value) =>
+              abstractValueDomain.writeAbstractValueToDataSink(sink, value),
+          allowNull: true);
+      sink.end(tag);
+    });
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/types.dart b/pkg/compiler/lib/src/inferrer/types.dart
index f68b519..374f01a 100644
--- a/pkg/compiler/lib/src/inferrer/types.dart
+++ b/pkg/compiler/lib/src/inferrer/types.dart
@@ -11,6 +11,7 @@
 import '../compiler.dart' show Compiler;
 import '../elements/entities.dart';
 import '../js_backend/inferred_data.dart';
+import '../js_model/element_map.dart';
 import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
 import '../serialization/serialization.dart';
 import '../universe/selector.dart' show Selector;
@@ -30,12 +31,13 @@
 /// based queries (the runtime value could be anything).
 abstract class GlobalTypeInferenceMemberResult {
   /// Deserializes a [GlobalTypeInferenceMemberResult] object from [source].
-  factory GlobalTypeInferenceMemberResult.readFromDataSource(
-          DataSource source, AbstractValueDomain abstractValueDomain) =
+  factory GlobalTypeInferenceMemberResult.readFromDataSource(DataSource source,
+          ir.Member context, AbstractValueDomain abstractValueDomain) =
       GlobalTypeInferenceMemberResultImpl.readFromDataSource;
 
   /// Serializes this [GlobalTypeInferenceMemberResult] to [sink].
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain);
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain);
 
   /// The inferred type when this result belongs to a field, null otherwise.
   AbstractValue get type;
@@ -72,12 +74,13 @@
 /// a single element.
 abstract class GlobalTypeInferenceElementData {
   /// Deserializes a [GlobalTypeInferenceElementData] object from [source].
-  factory GlobalTypeInferenceElementData.readFromDataSource(
-          DataSource source, AbstractValueDomain abstractValueDomain) =
+  factory GlobalTypeInferenceElementData.readFromDataSource(DataSource source,
+          ir.Member context, AbstractValueDomain abstractValueDomain) =
       KernelGlobalTypeInferenceElementData.readFromDataSource;
 
   /// Serializes this [GlobalTypeInferenceElementData] to [sink].
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain);
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain);
 
   /// Compresses the inner representation by removing [AbstractValue] mappings
   /// to `null`. Returns the data object itself or `null` if the data object
@@ -109,17 +112,20 @@
 abstract class GlobalTypeInferenceResults {
   /// Deserializes a [GlobalTypeInferenceResults] object from [source].
   factory GlobalTypeInferenceResults.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld, InferredData inferredData) {
+      DataSource source,
+      JsToElementMap elementMap,
+      JClosedWorld closedWorld,
+      InferredData inferredData) {
     bool isTrivial = source.readBool();
     if (isTrivial) {
       return new TrivialGlobalTypeInferenceResults(closedWorld);
     }
     return new GlobalTypeInferenceResultsImpl.readFromDataSource(
-        source, closedWorld, inferredData);
+        source, elementMap, closedWorld, inferredData);
   }
 
   /// Serializes this [GlobalTypeInferenceResults] to [sink].
-  void writeToDataSink(DataSink sink);
+  void writeToDataSink(DataSink sink, JsToElementMap elementMap);
 
   JClosedWorld get closedWorld;
 
@@ -217,12 +223,17 @@
         _trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
 
   factory GlobalTypeInferenceResultsImpl.readFromDataSource(
-      DataSource source, JClosedWorld closedWorld, InferredData inferredData) {
+      DataSource source,
+      JsToElementMap elementMap,
+      JClosedWorld closedWorld,
+      InferredData inferredData) {
     source.begin(tag);
     Map<MemberEntity, GlobalTypeInferenceMemberResult> memberResults =
-        source.readMemberMap(() =>
+        source.readMemberMap((MemberEntity member) =>
             new GlobalTypeInferenceMemberResult.readFromDataSource(
-                source, closedWorld.abstractValueDomain));
+                source,
+                elementMap.getMemberContextNode(member),
+                closedWorld.abstractValueDomain));
     Map<Local, AbstractValue> parameterResults = source.readLocalMap(() =>
         closedWorld.abstractValueDomain
             .readAbstractValueFromDataSource(source));
@@ -244,13 +255,16 @@
   }
 
   @override
-  void writeToDataSink(DataSink sink) {
+  void writeToDataSink(DataSink sink, JsToElementMap elementMap) {
     sink.writeBool(false); // Is _not_ trivial.
     sink.begin(tag);
     sink.writeMemberMap(
         memberResults,
-        (GlobalTypeInferenceMemberResult result) =>
-            result.writeToDataSink(sink, closedWorld.abstractValueDomain));
+        (MemberEntity member, GlobalTypeInferenceMemberResult result) =>
+            result.writeToDataSink(
+                sink,
+                elementMap.getMemberContextNode(member),
+                closedWorld.abstractValueDomain));
     sink.writeLocalMap(
         parameterResults,
         (AbstractValue value) => closedWorld.abstractValueDomain
@@ -395,11 +409,13 @@
       {this.throwsAlways, this.isCalledOnce});
 
   factory GlobalTypeInferenceMemberResultImpl.readFromDataSource(
-      DataSource source, AbstractValueDomain abstractValueDomain) {
+      DataSource source,
+      ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
     source.begin(tag);
     GlobalTypeInferenceElementData data = source.readValueOrNull(() {
       return new GlobalTypeInferenceElementData.readFromDataSource(
-          source, abstractValueDomain);
+          source, context, abstractValueDomain);
     });
     AbstractValue returnType =
         abstractValueDomain.readAbstractValueFromDataSource(source);
@@ -413,10 +429,11 @@
   }
 
   @override
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
     sink.begin(tag);
     sink.writeValueOrNull(_data, (GlobalTypeInferenceElementData data) {
-      data.writeToDataSink(sink, abstractValueDomain);
+      data.writeToDataSink(sink, context, abstractValueDomain);
     });
     abstractValueDomain.writeAbstractValueToDataSink(sink, returnType);
     abstractValueDomain.writeAbstractValueToDataSink(sink, type);
@@ -453,7 +470,7 @@
         _trivialParameterResult = closedWorld.abstractValueDomain.dynamicType;
 
   @override
-  void writeToDataSink(DataSink sink) {
+  void writeToDataSink(DataSink sink, JsToElementMap elementMap) {
     sink.writeBool(true); // Is trivial.
   }
 
@@ -516,7 +533,8 @@
   bool get isCalledOnce => false;
 
   @override
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
     throw new UnsupportedError(
         "TrivialGlobalTypeInferenceMemberResult.writeToDataSink");
   }
@@ -559,7 +577,8 @@
   bool get isCalledOnce => false;
 
   @override
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
     throw new UnsupportedError(
         "DeadFieldGlobalTypeInferenceResult.writeToDataSink");
   }
@@ -602,7 +621,8 @@
   bool get isCalledOnce => false;
 
   @override
-  void writeToDataSink(DataSink sink, AbstractValueDomain abstractValueDomain) {
+  void writeToDataSink(DataSink sink, ir.Member context,
+      AbstractValueDomain abstractValueDomain) {
     throw new UnsupportedError(
         "DeadFieldGlobalTypeInferenceResult.writeToDataSink");
   }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 79a7960..7276ae4 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -574,7 +574,7 @@
         emptyAsNull: true);
     _fieldInitializers = source.readMemberNodes(emptyAsNull: true);
     _fieldConstantInitializers =
-        source.readMemberMap(() => source.readTreeNodes(), emptyAsNull: true);
+        source.readMemberNodeMap(source.readTreeNodes, emptyAsNull: true);
     _typeLiterals = source.readList(
         () => new _TypeLiteral.fromDataSource(source),
         emptyAsNull: true);
diff --git a/pkg/compiler/lib/src/ir/static_type_cache.dart b/pkg/compiler/lib/src/ir/static_type_cache.dart
index 64cf6b8..2e25d65 100644
--- a/pkg/compiler/lib/src/ir/static_type_cache.dart
+++ b/pkg/compiler/lib/src/ir/static_type_cache.dart
@@ -19,22 +19,28 @@
   const StaticTypeCache(
       [this._expressionTypes = const {}, this._forInIteratorTypes]);
 
-  factory StaticTypeCache.readFromDataSource(DataSource source) {
-    source.begin(tag);
-    Map<ir.Expression, ir.DartType> expressionTypes =
-        source.readTreeNodeMap(source.readDartTypeNode);
-    Map<ir.ForInStatement, ir.DartType> forInIteratorTypes =
-        source.readTreeNodeMap(source.readDartTypeNode, emptyAsNull: true);
-    source.end(tag);
-    return new StaticTypeCache(expressionTypes, forInIteratorTypes);
+  factory StaticTypeCache.readFromDataSource(
+      DataSource source, ir.Member context) {
+    return source.inMemberContext(context, () {
+      source.begin(tag);
+      Map<ir.Expression, ir.DartType> expressionTypes =
+          source.readTreeNodeMapInContext(source.readDartTypeNode);
+      Map<ir.ForInStatement, ir.DartType> forInIteratorTypes = source
+          .readTreeNodeMapInContext(source.readDartTypeNode, emptyAsNull: true);
+      source.end(tag);
+      return new StaticTypeCache(expressionTypes, forInIteratorTypes);
+    });
   }
 
-  void writeToDataSink(DataSink sink) {
-    sink.begin(tag);
-    sink.writeTreeNodeMap(_expressionTypes, sink.writeDartTypeNode);
-    sink.writeTreeNodeMap(_forInIteratorTypes, sink.writeDartTypeNode,
-        allowNull: true);
-    sink.end(tag);
+  void writeToDataSink(DataSink sink, ir.Member context) {
+    sink.inMemberContext(context, () {
+      sink.begin(tag);
+      sink.writeTreeNodeMapInContext(_expressionTypes, sink.writeDartTypeNode);
+      sink.writeTreeNodeMapInContext(
+          _forInIteratorTypes, sink.writeDartTypeNode,
+          allowNull: true);
+      sink.end(tag);
+    });
   }
 
   ir.DartType operator [](ir.Expression node) => _expressionTypes[node];
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 1464c0b..97678ca 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -268,7 +268,8 @@
   factory AnnotationsDataImpl.readFromDataSource(DataSource source) {
     source.begin(tag);
     Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations =
-        source.readMemberMap(() => new EnumSet.fromValue(source.readInt()));
+        source.readMemberMap(
+            (MemberEntity member) => new EnumSet.fromValue(source.readInt()));
     source.end(tag);
     return new AnnotationsDataImpl(pragmaAnnotations);
   }
@@ -276,7 +277,8 @@
   @override
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
-    sink.writeMemberMap(pragmaAnnotations, (EnumSet<PragmaAnnotation> set) {
+    sink.writeMemberMap(pragmaAnnotations,
+        (MemberEntity member, EnumSet<PragmaAnnotation> set) {
       sink.writeInt(set.value);
     });
     sink.end(tag);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 5e22b23..b367d3a 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -20,6 +20,7 @@
 import 'checked_mode_helpers.dart';
 import 'namer.dart';
 import 'runtime_types.dart';
+import 'runtime_types_new.dart';
 
 abstract class FunctionCompiler {
   void initialize(
@@ -305,6 +306,7 @@
   CheckedModeHelpers get checkedModeHelpers;
   RuntimeTypesSubstitutions get rtiSubstitutions;
   RuntimeTypesEncoder get rtiEncoder;
+  RecipeEncoder get rtiRecipeEncoder;
   Tracer get tracer;
   RuntimeTypeTags get rtiTags;
   FixedNames get fixedNames;
@@ -321,6 +323,9 @@
   final RuntimeTypesEncoder rtiEncoder;
 
   @override
+  final RecipeEncoder rtiRecipeEncoder;
+
+  @override
   final Tracer tracer;
 
   @override
@@ -329,6 +334,6 @@
   @override
   final FixedNames fixedNames;
 
-  CodegenInputsImpl(this.rtiSubstitutions, this.rtiEncoder, this.tracer,
-      this.rtiTags, this.fixedNames);
+  CodegenInputsImpl(this.rtiSubstitutions, this.rtiEncoder,
+      this.rtiRecipeEncoder, this.tracer, this.rtiTags, this.fixedNames);
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 9f683b7..f1ff33f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -101,7 +101,7 @@
       _commonElements.getRuntimeTypeArgumentIntercepted,
       _commonElements.getRuntimeTypeArgument,
       _commonElements.getTypeArgumentByIndex,
-    ]);
+    ], otherImpacts: newRtiImpacts('getRuntimeTypeArgument'));
   }
 
   BackendImpact _computeSignature;
@@ -165,7 +165,8 @@
   BackendImpact get typeVariableBoundCheck {
     return _typeVariableBoundCheck ??= new BackendImpact(staticUses: [
       _commonElements.throwTypeError,
-      _commonElements.assertIsSubtype
+      _commonElements.assertIsSubtype,
+      if (_newRti) _commonElements.checkTypeBound,
     ]);
   }
 
@@ -189,7 +190,7 @@
   BackendImpact get asCheck {
     return _asCheck ??= new BackendImpact(staticUses: [
       _commonElements.throwRuntimeError,
-    ], otherImpacts: _newRti ? [usesNewRti] : []);
+    ], otherImpacts: newRtiImpacts('asCheck'));
   }
 
   BackendImpact _throwNoSuchMethod;
@@ -423,9 +424,12 @@
   BackendImpact _typeLiteral;
 
   BackendImpact get typeLiteral {
-    return _typeLiteral ??= new BackendImpact(
-        instantiatedClasses: [_commonElements.typeLiteralClass],
-        staticUses: [_commonElements.createRuntimeType]);
+    return _typeLiteral ??= new BackendImpact(instantiatedClasses: [
+      _commonElements.typeLiteralClass
+    ], staticUses: [
+      _commonElements.createRuntimeType,
+      if (_newRti) _commonElements.typeLiteralMaker,
+    ]);
   }
 
   BackendImpact _stackTraceInCatch;
@@ -762,15 +766,17 @@
         _commonElements.getInstantiationClass(typeArgumentCount),
       ]);
 
-  BackendImpact _usesNewRti;
-
   /// Backend impact for --experiment-new-rti.
-  BackendImpact get usesNewRti {
-    // TODO(sra): Can this be broken down into more selective impacts?
-    return _usesNewRti ??= BackendImpact(staticUses: [
-      _commonElements.findType,
-      _commonElements.rtiEvalMethod,
-      _commonElements.rtiBindMethod,
-    ]);
+  List<BackendImpact> newRtiImpacts(String what) {
+    if (!_newRti) return [];
+    // TODO(sra): Split into refined impacts.
+    return [
+      BackendImpact(staticUses: [
+        _commonElements.findType,
+        _commonElements.instanceType,
+        _commonElements.rtiEvalMethod,
+        _commonElements.rtiBindMethod,
+      ])
+    ];
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 2306ad6..c77257b 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -182,12 +182,10 @@
             helper, helper.parameterStructure.callStructure));
       }
       if (type.element == _commonElements.typeLiteralClass) {
-        // If we use a type literal in a constant, the compile time
-        // constant emitter will generate a call to the createRuntimeType
-        // helper so we register a use of that.
-        FunctionEntity helper = _commonElements.createRuntimeType;
-        impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            helper, helper.parameterStructure.callStructure));
+        // If we use a type literal in a constant, the compile time constant
+        // emitter will generate a call to a helper so we register the impact
+        // that contains that call.
+        _impacts.typeLiteral.registerImpact(impactBuilder, _elementEnvironment);
       }
     }
   }
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 06ec784..943b3932 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -13,9 +13,11 @@
 import '../js/js.dart' show js;
 import '../js_backend/field_analysis.dart';
 import '../js_emitter/code_emitter_task.dart';
+import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
 import '../options.dart';
 import 'field_analysis.dart' show JFieldAnalysis;
 import 'runtime_types.dart';
+import 'runtime_types_new.dart' show RecipeEncoder;
 
 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
 
@@ -205,6 +207,7 @@
   final JElementEnvironment _elementEnvironment;
   final RuntimeTypesNeed _rtiNeed;
   final RuntimeTypesEncoder _rtiEncoder;
+  final RecipeEncoder _rtiRecipeEncoder;
   final JFieldAnalysis _fieldAnalysis;
   final Emitter _emitter;
   final _ConstantReferenceGenerator _constantReferenceGenerator;
@@ -219,6 +222,7 @@
       this._elementEnvironment,
       this._rtiNeed,
       this._rtiEncoder,
+      this._rtiRecipeEncoder,
       this._fieldAnalysis,
       this._emitter,
       this._constantReferenceGenerator,
@@ -354,19 +358,34 @@
   jsAst.Expression visitType(TypeConstantValue constant, [_]) {
     DartType type = constant.representedType.unaliased;
 
-    jsAst.Expression unexpected(TypeVariableType _variable) {
-      TypeVariableType variable = _variable;
-      throw failedAt(
-          NO_LOCATION_SPANNABLE,
-          "Unexpected type variable '${variable}'"
-          " in constant '${constant.toDartText()}'");
+    if (_options.experimentNewRti) {
+      assert(!type.containsTypeVariables);
+
+      jsAst.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
+          _emitter, TypeExpressionRecipe(type));
+
+      // Generate  `typeLiteral(recipe)`.
+
+      // TODO(sra): `typeLiteral(r)` calls `createRuntimeType(findType(r))`.
+      // Find a way to share the `findType` call with methods that also use the
+      // type.
+      return js('#(#)',
+          [getHelperProperty(_commonElements.typeLiteralMaker), recipe]);
+    } else {
+      jsAst.Expression unexpected(TypeVariableType _variable) {
+        TypeVariableType variable = _variable;
+        throw failedAt(
+            NO_LOCATION_SPANNABLE,
+            "Unexpected type variable '${variable}'"
+            " in constant '${constant.toDartText()}'");
+      }
+
+      jsAst.Expression rti =
+          _rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
+
+      return new jsAst.Call(
+          getHelperProperty(_commonElements.createRuntimeType), [rti]);
     }
-
-    jsAst.Expression rti =
-        _rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
-
-    return new jsAst.Call(
-        getHelperProperty(_commonElements.createRuntimeType), [rti]);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 77aa43e..aa2c328 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -235,8 +235,8 @@
   factory JFieldAnalysis.readFromDataSource(
       DataSource source, CompilerOptions options) {
     source.begin(tag);
-    Map<FieldEntity, FieldAnalysisData> fieldData = source
-        .readMemberMap(() => new FieldAnalysisData.fromDataSource(source));
+    Map<FieldEntity, FieldAnalysisData> fieldData = source.readMemberMap(
+        (MemberEntity member) => new FieldAnalysisData.fromDataSource(source));
     source.end(tag);
     return new JFieldAnalysis._(fieldData);
   }
@@ -245,7 +245,9 @@
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
     sink.writeMemberMap(
-        _fieldData, (FieldAnalysisData data) => data.writeToDataSink(sink));
+        _fieldData,
+        (MemberEntity member, FieldAnalysisData data) =>
+            data.writeToDataSink(sink));
     sink.end(tag);
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/inferred_data.dart b/pkg/compiler/lib/src/js_backend/inferred_data.dart
index be9b3dc..b84035c 100644
--- a/pkg/compiler/lib/src/js_backend/inferred_data.dart
+++ b/pkg/compiler/lib/src/js_backend/inferred_data.dart
@@ -103,8 +103,8 @@
       DataSource source, JClosedWorld closedWorld) {
     source.begin(tag);
     Set<MemberEntity> functionsCalledInLoop = source.readMembers().toSet();
-    Map<FunctionEntity, SideEffects> sideEffects =
-        source.readMemberMap(() => new SideEffects.readFromDataSource(source));
+    Map<FunctionEntity, SideEffects> sideEffects = source.readMemberMap(
+        (MemberEntity member) => new SideEffects.readFromDataSource(source));
     Set<FunctionEntity> sideEffectsFreeElements =
         source.readMembers<FunctionEntity>().toSet();
     Set<FunctionEntity> elementsThatCannotThrow =
@@ -126,8 +126,10 @@
     sink.writeBool(false); // Is _not_ trivial.
     sink.begin(tag);
     sink.writeMembers(_functionsCalledInLoop);
-    sink.writeMemberMap(_sideEffects,
-        (SideEffects sideEffects) => sideEffects.writeToDataSink(sink));
+    sink.writeMemberMap(
+        _sideEffects,
+        (MemberEntity member, SideEffects sideEffects) =>
+            sideEffects.writeToDataSink(sink));
     sink.writeMembers(_sideEffectsFreeElements);
     sink.writeMembers(_elementsThatCannotThrow);
     sink.writeMembers(_functionsThatMightBePassedToApply);
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index f405dc0..dd8c765 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -140,6 +140,8 @@
 
   CompoundName(this._parts);
 
+  CompoundName.from(List<jsAst.Name> parts) : this(<_NamerName>[...parts]);
+
   @override
   String get name {
     if (_cachedName == null) {
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 3342b54..cc517d2 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -348,7 +348,7 @@
         source.readClassMap(source.readString);
     Set<ClassEntity> anonymousJsInteropClasses = source.readClasses().toSet();
     Map<MemberEntity, String> jsInteropMembers =
-        source.readMemberMap(source.readString);
+        source.readMemberMap((MemberEntity member) => source.readString());
     source.end(tag);
     return new NativeBasicDataImpl(
         elementEnvironment,
@@ -369,7 +369,8 @@
     sink.writeLibraryMap(jsInteropLibraries, sink.writeString);
     sink.writeClassMap(jsInteropClasses, sink.writeString);
     sink.writeClasses(anonymousJsInteropClasses);
-    sink.writeMemberMap(jsInteropMembers, sink.writeString);
+    sink.writeMemberMap(jsInteropMembers,
+        (MemberEntity member, String name) => sink.writeString(name));
     sink.end(tag);
   }
 
@@ -576,13 +577,16 @@
     NativeBasicData nativeBasicData =
         new NativeBasicData.readFromDataSource(source, elementEnvironment);
     Map<MemberEntity, String> nativeMemberName =
-        source.readMemberMap(source.readString);
-    Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = source
-        .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
-    Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = source
-        .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
-    Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = source
-        .readMemberMap(() => new NativeBehavior.readFromDataSource(source));
+        source.readMemberMap((MemberEntity member) => source.readString());
+    Map<FunctionEntity, NativeBehavior> nativeMethodBehavior =
+        source.readMemberMap((MemberEntity member) =>
+            new NativeBehavior.readFromDataSource(source));
+    Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior =
+        source.readMemberMap((MemberEntity member) =>
+            new NativeBehavior.readFromDataSource(source));
+    Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior =
+        source.readMemberMap((MemberEntity member) =>
+            new NativeBehavior.readFromDataSource(source));
     source.end(tag);
     return new NativeDataImpl(
         nativeBasicData,
@@ -597,16 +601,20 @@
     sink.begin(tag);
     _nativeBasicData.writeToDataSink(sink);
 
-    sink.writeMemberMap(nativeMemberName, sink.writeString);
+    sink.writeMemberMap(nativeMemberName,
+        (MemberEntity member, String name) => sink.writeString(name));
 
-    sink.writeMemberMap(nativeMethodBehavior, (NativeBehavior behavior) {
+    sink.writeMemberMap(nativeMethodBehavior,
+        (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
 
-    sink.writeMemberMap(nativeFieldLoadBehavior, (NativeBehavior behavior) {
+    sink.writeMemberMap(nativeFieldLoadBehavior,
+        (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
-    sink.writeMemberMap(nativeFieldStoreBehavior, (NativeBehavior behavior) {
+    sink.writeMemberMap(nativeFieldStoreBehavior,
+        (MemberEntity member, NativeBehavior behavior) {
       behavior.writeToDataSink(sink);
     });
 
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
new file mode 100644
index 0000000..4135d60
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -0,0 +1,381 @@
+// Copyright (c) 2019, 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.
+
+library js_backend.runtime_types_new;
+
+import 'package:js_runtime/shared/recipe_syntax.dart';
+
+import '../common_elements.dart' show JCommonElements, JElementEnvironment;
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../js_model/type_recipe.dart';
+import '../js_emitter/js_emitter.dart' show ModularEmitter;
+import '../universe/class_hierarchy.dart';
+import '../world.dart';
+import 'namer.dart';
+import 'native_data.dart';
+
+import 'runtime_types.dart' show RuntimeTypesNeed, RuntimeTypesSubstitutions;
+
+abstract class RecipeEncoder {
+  /// Returns a [jsAst.Expression] representing the given [recipe] to be
+  /// evaluated against a type environment with shape [structure].
+  jsAst.Expression encodeRecipe(ModularEmitter emitter,
+      TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
+
+  jsAst.Expression encodeGroundRecipe(
+      ModularEmitter emitter, TypeRecipe recipe);
+
+  // TODO(sra): Still need a $signature function when the function type is a
+  // function of closed type variables. See if the $signature method can always
+  // be generated through SSA in those cases.
+  jsAst.Expression encodeSignature(ModularNamer namer, ModularEmitter emitter,
+      DartType type, jsAst.Expression this_);
+}
+
+class RecipeEncoderImpl implements RecipeEncoder {
+  final JClosedWorld _closedWorld;
+  final RuntimeTypesSubstitutions _rtiSubstitutions;
+  final NativeBasicData _nativeData;
+  final JElementEnvironment _elementEnvironment;
+  final JCommonElements commonElements;
+  final RuntimeTypesNeed _rtiNeed;
+
+  RecipeEncoderImpl(this._closedWorld, this._rtiSubstitutions, this._nativeData,
+      this._elementEnvironment, this.commonElements, this._rtiNeed);
+
+  @override
+  jsAst.Expression encodeRecipe(ModularEmitter emitter,
+      TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
+    return _RecipeGenerator(this, emitter, environmentStructure, recipe).run();
+  }
+
+  @override
+  jsAst.Expression encodeGroundRecipe(
+      ModularEmitter emitter, TypeRecipe recipe) {
+    return _RecipeGenerator(this, emitter, null, recipe).run();
+  }
+
+  @override
+  jsAst.Expression encodeSignature(ModularNamer namer, ModularEmitter emitter,
+      DartType type, jsAst.Expression this_) {
+    // TODO(sra): These inputs (referenced to quell lints) are used by the old
+    // rti signature generator. Do we need them?
+    _rtiNeed;
+    commonElements;
+    _elementEnvironment;
+    throw UnimplementedError('RecipeEncoderImpl.getSignatureEncoding');
+  }
+}
+
+class _RecipeGenerator implements DartTypeVisitor<void, void> {
+  final RecipeEncoderImpl _encoder;
+  final ModularEmitter _emitter;
+  final TypeEnvironmentStructure _environment;
+  final TypeRecipe _recipe;
+
+  final List<FunctionTypeVariable> functionTypeVariables = [];
+
+  // Accumulated recipe.
+  final List<jsAst.Literal> _fragments = [];
+  final List<int> _codes = [];
+
+  _RecipeGenerator(
+      this._encoder, this._emitter, this._environment, this._recipe);
+
+  JClosedWorld get _closedWorld => _encoder._closedWorld;
+  NativeBasicData get _nativeData => _encoder._nativeData;
+  RuntimeTypesSubstitutions get _rtiSubstitutions => _encoder._rtiSubstitutions;
+
+  jsAst.Expression run() {
+    _start(_recipe);
+    assert(functionTypeVariables.isEmpty);
+    if (_fragments.isEmpty) {
+      return js.string(String.fromCharCodes(_codes));
+    }
+    _flushCodes();
+    jsAst.LiteralString quote = jsAst.LiteralString('"');
+    return jsAst.StringConcatenation([quote, ..._fragments, quote]);
+  }
+
+  void _start(TypeRecipe recipe) {
+    if (recipe is TypeExpressionRecipe) {
+      visit(recipe.type, null);
+    } else if (recipe is SingletonTypeEnvironmentRecipe) {
+      visit(recipe.type, null);
+    } else if (recipe is FullTypeEnvironmentRecipe) {
+      _startFullTypeEnvironmentRecipe(recipe, null);
+    }
+  }
+
+  void _startFullTypeEnvironmentRecipe(FullTypeEnvironmentRecipe recipe, _) {
+    if (recipe.classType == null) {
+      _emitCode(Recipe.pushDynamic);
+      assert(recipe.types.isNotEmpty);
+    } else {
+      visit(recipe.classType, null);
+      // TODO(sra): The separator can be omitted when the parser will have
+      // reduced to the top of stack to an Rti value.
+      _emitCode(Recipe.toType);
+    }
+
+    if (recipe.types.isNotEmpty) {
+      _emitCode(Recipe.startTypeArguments);
+      bool first = true;
+      for (DartType type in recipe.types) {
+        if (!first) {
+          _emitCode(Recipe.separator);
+        }
+        visit(type, _);
+        first = false;
+      }
+      _emitCode(Recipe.endTypeArguments);
+    }
+  }
+
+  void _emitCode(int code) {
+    // TODO(sra): We should permit codes with short escapes (like '\n') for
+    // infrequent operators.
+    assert(code >= 0x20 && code <= 0x7E && code != 0x22);
+    _codes.add(code);
+  }
+
+  void _flushCodes() {
+    if (_codes.isEmpty) return;
+    // TODO(sra): codes need some escaping.
+    _fragments.add(StringBackedName(String.fromCharCodes(_codes)));
+    _codes.clear();
+  }
+
+  void _emitInteger(int value) {
+    if (_codes.isEmpty ? _fragments.isNotEmpty : Recipe.isDigit(_codes.last)) {
+      _emitCode(Recipe.separator);
+    }
+    _emitStringUnescaped('$value');
+  }
+
+  void _emitStringUnescaped(String string) {
+    for (int code in string.codeUnits) {
+      _emitCode(code);
+    }
+  }
+
+  void _emitName(jsAst.Name name) {
+    if (_fragments.isNotEmpty && _codes.isEmpty) {
+      _emitCode(Recipe.separator);
+    }
+    _flushCodes();
+    _fragments.add(name);
+  }
+
+  void _emitExtensionOp(int value) {
+    _emitInteger(value);
+    _emitCode(Recipe.extensionOp);
+  }
+
+  @override
+  void visit(DartType type, _) => type.accept(this, _);
+
+  @override
+  void visitTypeVariableType(TypeVariableType type, _) {
+    TypeEnvironmentStructure environment = _environment;
+    if (environment is SingletonTypeEnvironmentStructure) {
+      if (type == environment.variable) {
+        _emitInteger(0);
+        return;
+      }
+    }
+    if (environment is FullTypeEnvironmentStructure) {
+      int i = environment.bindings.indexOf(type);
+      if (i >= 0) {
+        // Indexes are 1-based since '0' encodes using the entire type for the
+        // singleton structure.
+        _emitInteger(i + 1);
+        return;
+      }
+
+      int index = _indexIntoClassTypeVariables(type);
+      if (index != null) {
+        // Indexed class type variables come after the bound function type
+        // variables.
+        _emitInteger(1 + environment.bindings.length + index);
+        return;
+      }
+      // TODO(sra): Encode type variables names via namer.
+    }
+    // TODO(sra): Handle missing cases. This just emits some readable junk. The
+    // backticks ensure it won't parse at runtime.
+    '`$type`'.codeUnits.forEach(_emitCode);
+  }
+
+  int /*?*/ _indexIntoClassTypeVariables(TypeVariableType variable) {
+    TypeVariableEntity element = variable.element;
+    ClassEntity cls = element.typeDeclaration;
+
+    // TODO(sra): We might be in a context where the class type variable has an
+    // index, even though in the general case it is not at a specific index.
+
+    if (_closedWorld.isUsedAsMixin(cls)) return null;
+
+    ClassHierarchy classHierarchy = _closedWorld.classHierarchy;
+    if (classHierarchy.anyStrictSubclassOf(cls, (ClassEntity subclass) {
+      return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
+    })) {
+      return null;
+    }
+    return element.index;
+  }
+
+  @override
+  void visitFunctionTypeVariable(FunctionTypeVariable type, _) {
+    int position = functionTypeVariables.indexOf(type);
+    assert(position >= 0);
+    // See [visitFunctionType] for explanation.
+    _emitInteger(functionTypeVariables.length - position - 1);
+    _emitCode(Recipe.genericFunctionTypeParameterIndex);
+  }
+
+  @override
+  void visitDynamicType(DynamicType type, _) {
+    _emitCode(Recipe.pushDynamic);
+  }
+
+  @override
+  void visitInterfaceType(InterfaceType type, _) {
+    jsAst.Name name = _emitter.typeAccessNewRti(type.element);
+    if (type.typeArguments.isEmpty) {
+      // Push the name, which is later converted by an implicit toType
+      // operation.
+      _emitName(name);
+    } else {
+      _emitName(name);
+      _emitCode(Recipe.startTypeArguments);
+      bool first = true;
+      for (DartType argumentType in type.typeArguments) {
+        if (!first) {
+          _emitCode(Recipe.separator);
+        }
+        if (_nativeData.isJsInteropClass(type.element)) {
+          // Emit 'any' type.
+          _emitExtensionOp(Recipe.pushAnyExtension);
+        } else {
+          visit(argumentType, _);
+        }
+        first = false;
+      }
+      _emitCode(Recipe.endTypeArguments);
+    }
+  }
+
+  @override
+  void visitFunctionType(FunctionType type, _) {
+    if (type.typeVariables.isNotEmpty) {
+      // Enter generic function scope.
+      //
+      // Function type variables are encoded as a modified de Bruin index. We
+      // count variables from the current scope outwards, counting the variables
+      // in the same scope left-to-right.
+      //
+      // If we push the current scope's variables in reverse, then the index is
+      // the position measured from the end.
+      //
+      //    foo<AA,BB>() => ...
+      //      //^0 ^1
+      //    functionTypeVariables: [BB,AA]
+      //
+      //    foo<AA,BB>() => <UU,VV,WW>() => ...
+      //        ^3 ^4        ^0 ^1 ^2
+      //    functionTypeVariables: [BB,AA,WW,VV,UU]
+      //
+      for (FunctionTypeVariable variable in type.typeVariables.reversed) {
+        functionTypeVariables.add(variable);
+      }
+    }
+
+    visit(type.returnType, _);
+    _emitCode(Recipe.startFunctionArguments);
+
+    bool first = true;
+    for (DartType parameterType in type.parameterTypes) {
+      if (!first) {
+        _emitCode(Recipe.separator);
+      }
+      visit(parameterType, _);
+      first = false;
+    }
+
+    if (type.optionalParameterTypes.isNotEmpty) {
+      first = true;
+      _emitCode(Recipe.startOptionalGroup);
+      for (DartType parameterType in type.optionalParameterTypes) {
+        if (!first) {
+          _emitCode(Recipe.separator);
+        }
+        visit(parameterType, _);
+        first = false;
+      }
+      _emitCode(Recipe.endOptionalGroup);
+    }
+
+    void emitNamedGroup(List<String> names, List<DartType> types) {
+      assert(names.length == types.length);
+      first = true;
+      _emitCode(Recipe.startNamedGroup);
+      for (int i = 0; i < names.length; i++) {
+        if (!first) {
+          _emitCode(Recipe.separator);
+        }
+        _emitStringUnescaped(names[i]);
+        _emitCode(Recipe.nameSeparator);
+        visit(types[i], _);
+        first = false;
+      }
+      _emitCode(Recipe.endNamedGroup);
+    }
+
+    // TODO(sra): These are optional named parameters. Handle required named
+    // parameters the same way when they are implemented.
+    if (type.namedParameterTypes.isNotEmpty) {
+      emitNamedGroup(type.namedParameters, type.namedParameterTypes);
+    }
+
+    _emitCode(Recipe.endFunctionArguments);
+
+    // Emit generic type bounds.
+    if (type.typeVariables.isNotEmpty) {
+      bool first = true;
+      _emitCode(Recipe.startTypeArguments);
+      for (FunctionTypeVariable typeVariable in type.typeVariables) {
+        if (!first) {
+          _emitCode(Recipe.separator);
+        }
+        visit(typeVariable.bound, _);
+      }
+      _emitCode(Recipe.endTypeArguments);
+    }
+
+    if (type.typeVariables.isNotEmpty) {
+      // Exit generic function scope. Remove the type variables pushed at entry.
+      functionTypeVariables.length -= type.typeVariables.length;
+    }
+  }
+
+  @override
+  void visitVoidType(VoidType type, _) {
+    _emitCode(Recipe.pushVoid);
+  }
+
+  @override
+  void visitTypedefType(TypedefType type, _) {
+    visit(type.unaliased, _);
+  }
+
+  @override
+  void visitFutureOrType(FutureOrType type, _) {
+    visit(type.typeArgument, _);
+    _emitCode(Recipe.wrapFutureOr);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index c9b0ec1..62e9ab0 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -90,6 +90,7 @@
           namer,
           closedWorld,
           codegen.rtiEncoder,
+          codegen.rtiRecipeEncoder,
           _backendStrategy.sourceInformationStrategy,
           this,
           _generateSourceMap);
@@ -179,6 +180,9 @@
   /// Returns the JS expression representing the type [e].
   jsAst.Expression typeAccess(Entity e);
 
+  /// Returns the JS name representing the type [e].
+  jsAst.Name typeAccessNewRti(Entity e);
+
   /// Returns the JS code for accessing the embedded [global].
   jsAst.Expression generateEmbeddedGlobalAccess(String global);
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index c664a0f..8752178 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -17,6 +17,7 @@
 import '../../js_backend/constant_emitter.dart';
 import '../../js_backend/namer.dart';
 import '../../js_backend/runtime_types.dart';
+import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
 import '../../options.dart';
 import '../../universe/codegen_world_builder.dart' show CodegenWorld;
 import '../../world.dart' show JClosedWorld;
@@ -86,6 +87,11 @@
   }
 
   @override
+  js.Name typeAccessNewRti(Entity element) {
+    return _namer.globalPropertyNameForType(element);
+  }
+
+  @override
   js.Expression staticClosureAccess(FunctionEntity element) {
     return new js.Call(
         new js.PropertyAccess(_namer.readGlobalObjectForMember(element),
@@ -138,6 +144,7 @@
   final DiagnosticReporter _reporter;
   final JClosedWorld _closedWorld;
   final RuntimeTypesEncoder _rtiEncoder;
+  final RecipeEncoder _rtiRecipeEncoder;
   final CompilerTask _task;
   ModelEmitter _emitter;
 
@@ -152,6 +159,7 @@
       Namer namer,
       this._closedWorld,
       this._rtiEncoder,
+      this._rtiRecipeEncoder,
       SourceInformationStrategy sourceInformationStrategy,
       this._task,
       bool shouldGenerateSourceMap)
@@ -167,6 +175,7 @@
         this,
         sourceInformationStrategy,
         _rtiEncoder,
+        _rtiRecipeEncoder,
         shouldGenerateSourceMap);
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index fd8db9b..e5643a5 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -49,6 +49,7 @@
     show Namer, ConstantEmitter, StringBackedName;
 import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
 import '../../js_backend/runtime_types.dart';
+import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
 import '../../options.dart';
 import '../../universe/codegen_world_builder.dart' show CodegenWorld;
 import '../../world.dart';
@@ -99,6 +100,7 @@
       this._emitter,
       this._sourceInformationStrategy,
       RuntimeTypesEncoder rtiEncoder,
+      RecipeEncoder rtiRecipeEncoder,
       this._shouldGenerateSourceMap)
       : _constantOrdering = new ConstantOrdering(_closedWorld.sorter) {
     this._constantEmitter = new ConstantEmitter(
@@ -107,6 +109,7 @@
         _closedWorld.elementEnvironment,
         _closedWorld.rtiNeed,
         rtiEncoder,
+        rtiRecipeEncoder,
         _closedWorld.fieldAnalysis,
         _emitter,
         this.generateConstantReference,
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 2ee5d5c..32f7f78 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -49,12 +49,13 @@
       JsToElementMap elementMap, DataSource source) {
     source.begin(tag);
     // TODO(johnniwinther): Support shared [ScopeInfo].
-    Map<MemberEntity, ScopeInfo> scopeMap =
-        source.readMemberMap(() => new ScopeInfo.readFromDataSource(source));
+    Map<MemberEntity, ScopeInfo> scopeMap = source.readMemberMap(
+        (MemberEntity member) => new ScopeInfo.readFromDataSource(source));
     Map<ir.TreeNode, CapturedScope> capturedScopesMap = source
         .readTreeNodeMap(() => new CapturedScope.readFromDataSource(source));
-    Map<MemberEntity, CapturedScope> capturedScopeForSignatureMap = source
-        .readMemberMap(() => new CapturedScope.readFromDataSource(source));
+    Map<MemberEntity, CapturedScope> capturedScopeForSignatureMap =
+        source.readMemberMap((MemberEntity member) =>
+            new CapturedScope.readFromDataSource(source));
     Map<ir.LocalFunction, ClosureRepresentationInfo>
         localClosureRepresentationMap = source.readTreeNodeMap(
             () => new ClosureRepresentationInfo.readFromDataSource(source));
@@ -67,13 +68,15 @@
   @override
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
-    sink.writeMemberMap(
-        _scopeMap, (ScopeInfo info) => info.writeToDataSink(sink));
+    sink.writeMemberMap(_scopeMap,
+        (MemberEntity member, ScopeInfo info) => info.writeToDataSink(sink));
     sink.writeTreeNodeMap(_capturedScopesMap, (CapturedScope scope) {
       scope.writeToDataSink(sink);
     });
-    sink.writeMemberMap(_capturedScopeForSignatureMap,
-        (CapturedScope scope) => scope.writeToDataSink(sink));
+    sink.writeMemberMap(
+        _capturedScopeForSignatureMap,
+        (MemberEntity member, CapturedScope scope) =>
+            scope.writeToDataSink(sink));
     sink.writeTreeNodeMap(_localClosureRepresentationMap,
         (ClosureRepresentationInfo info) {
       info.writeToDataSink(sink);
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 3fb71a4..0a88fbe 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -120,11 +120,14 @@
   List<DartType> getDartTypes(List<ir.DartType> types);
 
   /// Returns the definition information for [member].
-  MemberDefinition getMemberDefinition(covariant MemberEntity member);
+  MemberDefinition getMemberDefinition(MemberEntity member);
+
+  /// Returns the [ir.Member] containing the definition of [member], if any.
+  ir.Member getMemberContextNode(MemberEntity member);
 
   /// Returns the type of `this` in [member], or `null` if member is defined in
   /// a static context.
-  InterfaceType getMemberThisType(covariant MemberEntity member);
+  InterfaceType getMemberThisType(MemberEntity member);
 
   /// Returns how [member] has access to type variables of the this type
   /// returned by [getMemberThisType].
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index e24352c..692c95e 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -138,7 +138,8 @@
       AnnotationsData annotations)
       : this.options = _elementMap.options {
     _elementEnvironment = new JsElementEnvironment(this);
-    _commonElements = new CommonElementsImpl(_elementEnvironment);
+    _commonElements =
+        new CommonElementsImpl(_elementEnvironment, _elementMap.options);
     _constantEnvironment = new JsConstantEnvironment(this, environment);
     _typeConverter = new DartTypeConverter(this);
     _types = new KernelDartTypes(this);
@@ -317,7 +318,7 @@
   JsKernelToElementMap.readFromDataSource(this.options, this.reporter,
       Environment environment, ir.Component component, DataSource source) {
     _elementEnvironment = new JsElementEnvironment(this);
-    _commonElements = new CommonElementsImpl(_elementEnvironment);
+    _commonElements = new CommonElementsImpl(_elementEnvironment, options);
     _constantEnvironment = new JsConstantEnvironment(this, environment);
     _typeConverter = new DartTypeConverter(this);
     _types = new KernelDartTypes(this);
@@ -437,8 +438,8 @@
     source.end(typeVariableDataTag);
 
     source.begin(nestedClosuresTag);
-    _nestedClosureMap.addAll(
-        source.readMemberMap(() => source.readMembers<IndexedFunction>()));
+    _nestedClosureMap.addAll(source.readMemberMap(
+        (MemberEntity member) => source.readMembers<IndexedFunction>()));
     source.end(nestedClosuresTag);
 
     source.end(tag);
@@ -548,7 +549,10 @@
     sink.end(typeVariableDataTag);
 
     sink.begin(nestedClosuresTag);
-    sink.writeMemberMap(_nestedClosureMap, sink.writeMembers);
+    sink.writeMemberMap(
+        _nestedClosureMap,
+        (MemberEntity member, List<IndexedFunction> functions) =>
+            sink.writeMembers(functions));
     sink.end(nestedClosuresTag);
 
     sink.end(tag);
@@ -1673,6 +1677,33 @@
   }
 
   @override
+  ir.Member getMemberContextNode(MemberEntity member) {
+    ir.Member getParentMember(ir.TreeNode node) {
+      while (node != null) {
+        if (node is ir.Member) {
+          return node;
+        }
+        node = node.parent;
+      }
+      return null;
+    }
+
+    MemberDefinition definition = getMemberDefinition(member);
+    switch (definition.kind) {
+      case MemberKind.regular:
+      case MemberKind.constructor:
+      case MemberKind.constructorBody:
+        return definition.node;
+      case MemberKind.closureCall:
+      case MemberKind.closureField:
+      case MemberKind.signature:
+      case MemberKind.generatorBody:
+        return getParentMember(definition.node);
+    }
+    throw new UnsupportedError('Unexpected member kind ${definition}');
+  }
+
+  @override
   ClassDefinition getClassDefinition(ClassEntity cls) {
     return getClassDefinitionInternal(cls);
   }
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 9017330..ac096b1 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -678,7 +678,7 @@
     MemberDefinition definition =
         new MemberDefinition.readFromDataSource(source);
     StaticTypeCache staticTypes =
-        new StaticTypeCache.readFromDataSource(source);
+        new StaticTypeCache.readFromDataSource(source, node);
     source.end(tag);
     return new FunctionDataImpl(node, functionNode, definition, staticTypes);
   }
@@ -689,7 +689,7 @@
     sink.begin(tag);
     sink.writeMemberNode(node);
     definition.writeToDataSink(sink);
-    staticTypes.writeToDataSink(sink);
+    staticTypes.writeToDataSink(sink, node);
     sink.end(tag);
   }
 
@@ -877,7 +877,7 @@
     MemberDefinition definition =
         new MemberDefinition.readFromDataSource(source);
     StaticTypeCache staticTypes =
-        new StaticTypeCache.readFromDataSource(source);
+        new StaticTypeCache.readFromDataSource(source, node);
     source.end(tag);
     return new JConstructorDataImpl(
         node, functionNode, definition, staticTypes);
@@ -890,7 +890,7 @@
     sink.writeMemberNode(node);
     definition.writeToDataSink(sink);
     assert(constructorBody == null);
-    staticTypes.writeToDataSink(sink);
+    staticTypes.writeToDataSink(sink, node);
     sink.end(tag);
   }
 
@@ -940,7 +940,7 @@
     MemberDefinition definition =
         new MemberDefinition.readFromDataSource(source);
     StaticTypeCache staticTypes =
-        new StaticTypeCache.readFromDataSource(source);
+        new StaticTypeCache.readFromDataSource(source, node);
     source.end(tag);
     return new ConstructorBodyDataImpl(
         node, functionNode, definition, staticTypes);
@@ -952,7 +952,7 @@
     sink.begin(tag);
     sink.writeMemberNode(node);
     definition.writeToDataSink(sink);
-    staticTypes.writeToDataSink(sink);
+    staticTypes.writeToDataSink(sink, node);
     sink.end(tag);
   }
 
@@ -988,7 +988,7 @@
     MemberDefinition definition =
         new MemberDefinition.readFromDataSource(source);
     StaticTypeCache staticTypes =
-        new StaticTypeCache.readFromDataSource(source);
+        new StaticTypeCache.readFromDataSource(source, node);
     source.end(tag);
     return new JFieldDataImpl(node, definition, staticTypes);
   }
@@ -999,7 +999,7 @@
     sink.begin(tag);
     sink.writeMemberNode(node);
     definition.writeToDataSink(sink);
-    staticTypes.writeToDataSink(sink);
+    staticTypes.writeToDataSink(sink, node);
     sink.end(tag);
   }
 
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 2c0c686..f794857 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -34,6 +34,8 @@
 import '../js_backend/interceptor_data.dart';
 import '../js_backend/namer.dart';
 import '../js_backend/runtime_types.dart';
+import '../js_backend/runtime_types_new.dart'
+    show RecipeEncoder, RecipeEncoderImpl;
 import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
 import '../js/js.dart' as js;
@@ -202,6 +204,7 @@
         closedWorld.elementEnvironment,
         closedWorld.commonElements,
         closedWorld.rtiNeed);
+
     RuntimeTypesSubstitutions rtiSubstitutions;
     if (_compiler.options.disableRtiOptimization) {
       rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(closedWorld);
@@ -213,8 +216,18 @@
       rtiSubstitutions = runtimeTypesImpl;
     }
 
-    CodegenInputs codegen = new CodegenInputsImpl(
-        rtiSubstitutions, rtiEncoder, tracer, rtiTags, fixedNames);
+    RecipeEncoder rtiRecipeEncoder = _compiler.options.experimentNewRti
+        ? new RecipeEncoderImpl(
+            closedWorld,
+            rtiSubstitutions,
+            closedWorld.nativeData,
+            closedWorld.elementEnvironment,
+            closedWorld.commonElements,
+            closedWorld.rtiNeed)
+        : null;
+
+    CodegenInputs codegen = new CodegenInputsImpl(rtiSubstitutions, rtiEncoder,
+        rtiRecipeEncoder, tracer, rtiTags, fixedNames);
 
     functionCompiler.initialize(globalTypeInferenceResults, codegen);
     return codegen;
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 3515770..b1beeb8 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -173,8 +173,8 @@
     elementMap.lateOutputUnitDataBuilder =
         new LateOutputUnitDataBuilder(outputUnitData);
 
-    Map<MemberEntity, MemberAccess> memberAccess =
-        source.readMemberMap(() => new MemberAccess.readFromDataSource(source));
+    Map<MemberEntity, MemberAccess> memberAccess = source.readMemberMap(
+        (MemberEntity member) => new MemberAccess.readFromDataSource(source));
 
     source.end(tag);
 
@@ -228,7 +228,9 @@
     closureDataLookup.writeToDataSink(sink);
     outputUnitData.writeToDataSink(sink);
     sink.writeMemberMap(
-        memberAccess, (MemberAccess access) => access.writeToDataSink(sink));
+        memberAccess,
+        (MemberEntity member, MemberAccess access) =>
+            access.writeToDataSink(sink));
     sink.end(tag);
   }
 
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index ce5aed9..eba6bd9 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -122,7 +122,7 @@
   KernelToElementMapImpl(
       this.reporter, this._environment, this._frontendStrategy, this.options) {
     _elementEnvironment = new KernelElementEnvironment(this);
-    _commonElements = new CommonElementsImpl(_elementEnvironment);
+    _commonElements = new CommonElementsImpl(_elementEnvironment, options);
     _constantEnvironment = new KernelConstantEnvironment(this, _environment);
     _typeConverter = new DartTypeConverter(this);
     _types = new KernelDartTypes(this);
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index fe6d512..1b22344 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -403,6 +403,9 @@
         // `Mixin.method` is inherited by `Class`.
         return;
       }
+      if (member.isForwardingStub && cls.isAnonymousMixin) {
+        return;
+      }
       if (!includeStatic && member.isStatic) return;
       if (member.isNoSuchMethodForwarder) {
         // TODO(sigmund): remove once #33732 is fixed.
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index acce37c..74bf19a 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -120,6 +120,9 @@
   /// Sets a combination of flags for benchmarking 'production' mode.
   bool benchmarkingProduction = false;
 
+  /// Sets a combination of flags for benchmarking 'experiment' mode.
+  bool benchmarkingExperiment = false;
+
   /// ID associated with this sdk build.
   String buildId = _UNDETERMINED_BUILD_ID;
 
@@ -359,6 +362,8 @@
       ..allowMockCompilation = _hasOption(options, Flags.allowMockCompilation)
       ..benchmarkingProduction =
           _hasOption(options, Flags.benchmarkingProduction)
+      ..benchmarkingExperiment =
+          _hasOption(options, Flags.benchmarkingExperiment)
       ..buildId =
           _extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
       ..compileForServer = _hasOption(options, Flags.serverMode)
@@ -462,6 +467,11 @@
       omitImplicitChecks = true;
     }
 
+    if (benchmarkingExperiment) {
+      // TODO(sra): Set flags implied by '--benchmarking-x'. Initially this will
+      // be --experiment-new-rti, and later NNBD.
+    }
+
     if (optimizationLevel != null) {
       if (optimizationLevel == 0) {
         disableInlining = true;
diff --git a/pkg/compiler/lib/src/serialization/abstract_sink.dart b/pkg/compiler/lib/src/serialization/abstract_sink.dart
index a1af8e8..484d24f 100644
--- a/pkg/compiler/lib/src/serialization/abstract_sink.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_sink.dart
@@ -39,6 +39,9 @@
 
   final Map<String, int> tagFrequencyMap;
 
+  ir.Member _currentMemberContext;
+  _MemberData _currentMemberData;
+
   AbstractDataSink({this.useDataKinds: false, this.tagFrequencyMap}) {
     _dartTypeWriter = new DartTypeWriter(this);
     _dartTypeNodeWriter = new DartTypeNodeWriter(this);
@@ -73,6 +76,24 @@
   }
 
   @override
+  void inMemberContext(ir.Member context, void f()) {
+    ir.Member oldMemberContext = _currentMemberContext;
+    _MemberData oldMemberData = _currentMemberData;
+    _currentMemberContext = context;
+    _currentMemberData = null;
+    f();
+    _currentMemberData = oldMemberData;
+    _currentMemberContext = oldMemberContext;
+  }
+
+  _MemberData get currentMemberData {
+    assert(_currentMemberContext != null,
+        "DataSink has no current member context.");
+    return _currentMemberData ??= _memberData[_currentMemberContext] ??=
+        new _MemberData(_currentMemberContext);
+  }
+
+  @override
   void writeCached<E>(E value, void f(E value)) {
     IndexedSink sink = _generalCaches[E] ??= new IndexedSink<E>(this);
     sink.write(value, (v) => f(v));
@@ -221,10 +242,58 @@
   @override
   void writeTreeNode(ir.TreeNode value) {
     _writeDataKind(DataKind.treeNode);
-    _writeTreeNode(value);
+    _writeTreeNode(value, null);
   }
 
-  void _writeTreeNode(ir.TreeNode value) {
+  @override
+  void writeTreeNodeInContext(ir.TreeNode value) {
+    writeTreeNodeInContextInternal(value, currentMemberData);
+  }
+
+  void writeTreeNodeInContextInternal(
+      ir.TreeNode value, _MemberData memberData) {
+    _writeDataKind(DataKind.treeNode);
+    _writeTreeNode(value, memberData);
+  }
+
+  @override
+  void writeTreeNodeOrNullInContext(ir.TreeNode value) {
+    writeBool(value != null);
+    if (value != null) {
+      writeTreeNodeInContextInternal(value, currentMemberData);
+    }
+  }
+
+  @override
+  void writeTreeNodesInContext(Iterable<ir.TreeNode> values,
+      {bool allowNull: false}) {
+    if (values == null) {
+      assert(allowNull);
+      writeInt(0);
+    } else {
+      writeInt(values.length);
+      for (ir.TreeNode value in values) {
+        writeTreeNodeInContextInternal(value, currentMemberData);
+      }
+    }
+  }
+
+  @override
+  void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V> map, void f(V value),
+      {bool allowNull: false}) {
+    if (map == null) {
+      assert(allowNull);
+      writeInt(0);
+    } else {
+      writeInt(map.length);
+      map.forEach((ir.TreeNode key, V value) {
+        writeTreeNodeInContextInternal(key, currentMemberData);
+        f(value);
+      });
+    }
+  }
+
+  void _writeTreeNode(ir.TreeNode value, _MemberData memberData) {
     if (value is ir.Class) {
       _writeEnumInternal(_TreeNodeKind.cls);
       _writeClassNode(value);
@@ -234,39 +303,43 @@
     } else if (value is ir.VariableDeclaration &&
         value.parent is ir.FunctionDeclaration) {
       _writeEnumInternal(_TreeNodeKind.functionDeclarationVariable);
-      _writeTreeNode(value.parent);
+      _writeTreeNode(value.parent, memberData);
     } else if (value is ir.FunctionNode) {
       _writeEnumInternal(_TreeNodeKind.functionNode);
-      _writeFunctionNode(value);
+      _writeFunctionNode(value, memberData);
     } else if (value is ir.TypeParameter) {
       _writeEnumInternal(_TreeNodeKind.typeParameter);
-      _writeTypeParameter(value);
+      _writeTypeParameter(value, memberData);
     } else if (value is ConstantReference) {
       _writeEnumInternal(_TreeNodeKind.constant);
-      _writeTreeNode(value.expression);
+      _writeTreeNode(value.expression, memberData);
       _ConstantNodeIndexerVisitor indexer = new _ConstantNodeIndexerVisitor();
       value.expression.constant.accept(indexer);
       _writeIntInternal(indexer.getIndex(value.constant));
     } else {
       _writeEnumInternal(_TreeNodeKind.node);
-      ir.TreeNode member = value;
-      while (member is! ir.Member) {
-        if (member == null) {
-          throw new UnsupportedError("No enclosing member of TreeNode "
-              "$value (${value.runtimeType})");
+      if (memberData == null) {
+        ir.TreeNode member = value;
+        while (member is! ir.Member) {
+          if (member == null) {
+            throw new UnsupportedError("No enclosing member of TreeNode "
+                "$value (${value.runtimeType})");
+          }
+          member = member.parent;
         }
-        member = member.parent;
+        _writeMemberNode(member);
+        memberData = _memberData[member] ??= new _MemberData(member);
       }
-      _writeMemberNode(member);
-      _MemberData memberData = _memberData[member] ??= new _MemberData(member);
       int index = memberData.getIndexByTreeNode(value);
       assert(
-          index != null, "No TreeNode index found for ${value.runtimeType}.");
+          index != null,
+          "No TreeNode index found for ${value.runtimeType} "
+          "found in ${memberData}.");
       _writeIntInternal(index);
     }
   }
 
-  void _writeFunctionNode(ir.FunctionNode value) {
+  void _writeFunctionNode(ir.FunctionNode value, _MemberData memberData) {
     ir.TreeNode parent = value.parent;
     if (parent is ir.Procedure) {
       _writeEnumInternal(_FunctionNodeKind.procedure);
@@ -276,10 +349,10 @@
       _writeMemberNode(parent);
     } else if (parent is ir.FunctionExpression) {
       _writeEnumInternal(_FunctionNodeKind.functionExpression);
-      _writeTreeNode(parent);
+      _writeTreeNode(parent, memberData);
     } else if (parent is ir.FunctionDeclaration) {
       _writeEnumInternal(_FunctionNodeKind.functionDeclaration);
-      _writeTreeNode(parent);
+      _writeTreeNode(parent, memberData);
     } else {
       throw new UnsupportedError(
           "Unsupported FunctionNode parent ${parent.runtimeType}");
@@ -289,10 +362,10 @@
   @override
   void writeTypeParameterNode(ir.TypeParameter value) {
     _writeDataKind(DataKind.typeParameterNode);
-    _writeTypeParameter(value);
+    _writeTypeParameter(value, null);
   }
 
-  void _writeTypeParameter(ir.TypeParameter value) {
+  void _writeTypeParameter(ir.TypeParameter value, _MemberData memberData) {
     ir.TreeNode parent = value.parent;
     if (parent is ir.Class) {
       _writeEnumInternal(_TypeParameterKind.cls);
@@ -300,7 +373,7 @@
       _writeIntInternal(parent.typeParameters.indexOf(value));
     } else if (parent is ir.FunctionNode) {
       _writeEnumInternal(_TypeParameterKind.functionNode);
-      _writeFunctionNode(parent);
+      _writeFunctionNode(parent, memberData);
       _writeIntInternal(parent.typeParameters.indexOf(value));
     } else {
       throw new UnsupportedError(
@@ -438,7 +511,8 @@
       case ConstantValueKind.CONSTRUCTED:
         ConstructedConstantValue constant = value;
         writeDartType(constant.type);
-        writeMemberMap(constant.fields, writeConstant);
+        writeMemberMap(constant.fields,
+            (MemberEntity member, ConstantValue value) => writeConstant(value));
         break;
       case ConstantValueKind.TYPE:
         TypeConstantValue constant = value;
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index a2fa583..a69e834 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -22,6 +22,9 @@
 
   Map<Type, IndexedSource> _generalCaches = {};
 
+  ir.Member _currentMemberContext;
+  _MemberData _currentMemberData;
+
   AbstractDataSource({this.useDataKinds: false}) {
     _stringIndex = new IndexedSource<String>(this);
     _uriIndex = new IndexedSource<Uri>(this);
@@ -92,6 +95,24 @@
   }
 
   @override
+  T inMemberContext<T>(ir.Member context, T f()) {
+    ir.Member oldMemberContext = _currentMemberContext;
+    _MemberData oldMemberData = _currentMemberData;
+    _currentMemberContext = context;
+    _currentMemberData = null;
+    T result = f();
+    _currentMemberData = oldMemberData;
+    _currentMemberContext = oldMemberContext;
+    return result;
+  }
+
+  _MemberData get currentMemberData {
+    assert(_currentMemberContext != null,
+        "DataSink has no current member context.");
+    return _currentMemberData ??= _getMemberData(_currentMemberContext);
+  }
+
+  @override
   E readCached<E>(E f()) {
     IndexedSource source = _generalCaches[E] ??= new IndexedSource<E>(this);
     return source.read(f);
@@ -322,11 +343,11 @@
       case MemberContextKind.cls:
         _ClassData cls = _readClassData();
         String name = _readString();
-        return cls.lookupMember(name);
+        return cls.lookupMemberDataByName(name);
       case MemberContextKind.library:
         _LibraryData library = _readLibraryData();
         String name = _readString();
-        return library.lookupMember(name);
+        return library.lookupMemberDataByName(name);
     }
     throw new UnsupportedError("Unsupported _MemberKind $kind");
   }
@@ -340,7 +361,7 @@
   _ClassData _readClassData() {
     _LibraryData library = _readLibraryData();
     String name = _readString();
-    return library.lookupClass(name);
+    return library.lookupClassByName(name);
   }
 
   @override
@@ -419,7 +440,64 @@
   @override
   ir.TreeNode readTreeNode() {
     _checkDataKind(DataKind.treeNode);
-    return _readTreeNode();
+    return _readTreeNode(null);
+  }
+
+  _MemberData _getMemberData(ir.Member node) {
+    _LibraryData libraryData =
+        componentLookup.getLibraryDataByUri(node.enclosingLibrary.importUri);
+    if (node.enclosingClass != null) {
+      _ClassData classData = libraryData.lookupClassByNode(node.enclosingClass);
+      return classData.lookupMemberDataByNode(node);
+    } else {
+      return libraryData.lookupMemberDataByNode(node);
+    }
+  }
+
+  @override
+  ir.TreeNode readTreeNodeInContext() {
+    return readTreeNodeInContextInternal(currentMemberData);
+  }
+
+  ir.TreeNode readTreeNodeInContextInternal(_MemberData memberData) {
+    _checkDataKind(DataKind.treeNode);
+    return _readTreeNode(memberData);
+  }
+
+  @override
+  ir.TreeNode readTreeNodeOrNullInContext() {
+    bool hasValue = readBool();
+    if (hasValue) {
+      return readTreeNodeInContextInternal(currentMemberData);
+    }
+    return null;
+  }
+
+  @override
+  List<E> readTreeNodesInContext<E extends ir.TreeNode>(
+      {bool emptyAsNull: false}) {
+    int count = readInt();
+    if (count == 0 && emptyAsNull) return null;
+    List<E> list = new List<E>(count);
+    for (int i = 0; i < count; i++) {
+      ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
+      list[i] = node;
+    }
+    return list;
+  }
+
+  @override
+  Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f(),
+      {bool emptyAsNull: false}) {
+    int count = readInt();
+    if (count == 0 && emptyAsNull) return null;
+    Map<K, V> map = {};
+    for (int i = 0; i < count; i++) {
+      ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
+      V value = f();
+      map[node] = value;
+    }
+    return map;
   }
 
   @override
@@ -493,7 +571,8 @@
       case ConstantValueKind.CONSTRUCTED:
         InterfaceType type = readDartType();
         Map<FieldEntity, ConstantValue> fields =
-            readMemberMap<FieldEntity, ConstantValue>(() => readConstant());
+            readMemberMap<FieldEntity, ConstantValue>(
+                (MemberEntity member) => readConstant());
         return new ConstructedConstantValue(type, fields);
       case ConstantValueKind.TYPE:
         DartType representedType = readDartType();
@@ -524,7 +603,7 @@
     throw new UnsupportedError("Unexpexted constant value kind ${kind}.");
   }
 
-  ir.TreeNode _readTreeNode() {
+  ir.TreeNode _readTreeNode(_MemberData memberData) {
     _TreeNodeKind kind = _readEnumInternal(_TreeNodeKind.values);
     switch (kind) {
       case _TreeNodeKind.cls:
@@ -532,32 +611,34 @@
       case _TreeNodeKind.member:
         return _readMemberData().node;
       case _TreeNodeKind.functionDeclarationVariable:
-        ir.FunctionDeclaration functionDeclaration = _readTreeNode();
+        ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
         return functionDeclaration.variable;
       case _TreeNodeKind.functionNode:
-        return _readFunctionNode();
+        return _readFunctionNode(memberData);
       case _TreeNodeKind.typeParameter:
-        return _readTypeParameter();
+        return _readTypeParameter(memberData);
       case _TreeNodeKind.constant:
         // TODO(johnniwinther): Support serialization within a member context
         // and use this to temporarily cache constant node indices.
-        ir.ConstantExpression expression = _readTreeNode();
+        ir.ConstantExpression expression = _readTreeNode(memberData);
         _ConstantNodeIndexerVisitor indexer = new _ConstantNodeIndexerVisitor();
         expression.constant.accept(indexer);
         ir.Constant constant = indexer.getConstant(_readIntInternal());
         return new ConstantReference(expression, constant);
       case _TreeNodeKind.node:
-        _MemberData data = _readMemberData();
+        if (memberData == null) {
+          memberData = _readMemberData();
+        }
         int index = _readIntInternal();
-        ir.TreeNode treeNode = data.getTreeNodeByIndex(index);
+        ir.TreeNode treeNode = memberData.getTreeNodeByIndex(index);
         assert(treeNode != null,
-            "No TreeNode found for index $index in ${data.node}.$_errorContext");
+            "No TreeNode found for index $index in ${memberData.node}.$_errorContext");
         return treeNode;
     }
     throw new UnsupportedError("Unexpected _TreeNodeKind $kind");
   }
 
-  ir.FunctionNode _readFunctionNode() {
+  ir.FunctionNode _readFunctionNode(_MemberData memberData) {
     _FunctionNodeKind kind = _readEnumInternal(_FunctionNodeKind.values);
     switch (kind) {
       case _FunctionNodeKind.procedure:
@@ -567,10 +648,10 @@
         ir.Constructor constructor = _readMemberData().node;
         return constructor.function;
       case _FunctionNodeKind.functionExpression:
-        ir.FunctionExpression functionExpression = _readTreeNode();
+        ir.FunctionExpression functionExpression = _readTreeNode(memberData);
         return functionExpression.function;
       case _FunctionNodeKind.functionDeclaration:
-        ir.FunctionDeclaration functionDeclaration = _readTreeNode();
+        ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
         return functionDeclaration.function;
     }
     throw new UnsupportedError("Unexpected _FunctionNodeKind $kind");
@@ -579,17 +660,17 @@
   @override
   ir.TypeParameter readTypeParameterNode() {
     _checkDataKind(DataKind.typeParameterNode);
-    return _readTypeParameter();
+    return _readTypeParameter(null);
   }
 
-  ir.TypeParameter _readTypeParameter() {
+  ir.TypeParameter _readTypeParameter(_MemberData memberData) {
     _TypeParameterKind kind = _readEnumInternal(_TypeParameterKind.values);
     switch (kind) {
       case _TypeParameterKind.cls:
         ir.Class cls = _readClassData().node;
         return cls.typeParameters[_readIntInternal()];
       case _TypeParameterKind.functionNode:
-        ir.FunctionNode functionNode = _readFunctionNode();
+        ir.FunctionNode functionNode = _readFunctionNode(memberData);
         return functionNode.typeParameters[_readIntInternal()];
     }
     throw new UnsupportedError("Unexpected _TypeParameterKind kind $kind");
diff --git a/pkg/compiler/lib/src/serialization/member_data.dart b/pkg/compiler/lib/src/serialization/member_data.dart
index f088210..867a271 100644
--- a/pkg/compiler/lib/src/serialization/member_data.dart
+++ b/pkg/compiler/lib/src/serialization/member_data.dart
@@ -55,27 +55,46 @@
   final ir.Library node;
 
   /// Cache of [_ClassData] for classes in this library.
-  Map<String, _ClassData> _classes;
+  Map<String, _ClassData> _classesByName;
+  Map<ir.Class, _ClassData> _classesByNode;
 
   /// Cache of [ir.Typedef] nodes for typedefs in this library.
   Map<String, ir.Typedef> _typedefs;
 
   /// Cache of [_MemberData] for members in this library.
-  Map<String, _MemberData> _members;
+  Map<String, _MemberData> _membersByName;
+  Map<ir.Member, _MemberData> _membersByNode;
 
   _LibraryData(this.node);
 
-  /// Returns the [_ClassData] for the class [name] in this library.
-  _ClassData lookupClass(String name) {
-    if (_classes == null) {
-      _classes = {};
+  void _ensureClasses() {
+    if (_classesByName == null) {
+      _classesByName = {};
+      _classesByNode = {};
       for (ir.Class cls in node.classes) {
-        assert(!_classes.containsKey(cls.name),
-            "Duplicate class '${cls.name}' in $_classes trying to add $cls.");
-        _classes[cls.name] = new _ClassData(cls);
+        assert(
+            !_classesByName.containsKey(cls.name),
+            "Duplicate class '${cls.name}' in $_classesByName "
+            "trying to add $cls.");
+        assert(
+            !_classesByNode.containsKey(cls),
+            "Duplicate class '${cls.name}' in $_classesByNode "
+            "trying to add $cls.");
+        _classesByNode[cls] = _classesByName[cls.name] = new _ClassData(cls);
       }
     }
-    return _classes[name];
+  }
+
+  /// Returns the [_ClassData] for the class [name] in this library.
+  _ClassData lookupClassByName(String name) {
+    _ensureClasses();
+    return _classesByName[name];
+  }
+
+  /// Returns the [_ClassData] for the class [node] in this library.
+  _ClassData lookupClassByNode(ir.Class node) {
+    _ensureClasses();
+    return _classesByNode[node];
   }
 
   ir.Typedef lookupTypedef(String name) {
@@ -92,20 +111,37 @@
     return _typedefs[name];
   }
 
-  /// Returns the [_MemberData] for the member uniquely identified by [name] in
-  /// this library.
-  _MemberData lookupMember(String name) {
-    if (_members == null) {
-      _members = {};
+  void _ensureMembers() {
+    if (_membersByName == null) {
+      _membersByName = {};
+      _membersByNode = {};
       for (ir.Member member in node.members) {
         String name = _computeMemberName(member);
         if (name == null) continue;
-        assert(!_members.containsKey(name),
-            "Duplicate member '$name' in $_members trying to add $member.");
-        _members[name] = new _MemberData(member);
+        assert(
+            !_membersByName.containsKey(name),
+            "Duplicate member '$name' in $_membersByName "
+            "trying to add $member.");
+        assert(
+            !_membersByNode.containsKey(member),
+            "Duplicate member '$name' in $_membersByNode "
+            "trying to add $member.");
+        _membersByNode[member] = _membersByName[name] = new _MemberData(member);
       }
     }
-    return _members[name];
+  }
+
+  /// Returns the [_MemberData] for the member uniquely identified by [name] in
+  /// this library.
+  _MemberData lookupMemberDataByName(String name) {
+    _ensureMembers();
+    return _membersByName[name];
+  }
+
+  /// Returns the [_MemberData] for the member [node] in this library.
+  _MemberData lookupMemberDataByNode(ir.Member node) {
+    _ensureMembers();
+    return _membersByNode[node];
   }
 
   @override
@@ -118,24 +154,42 @@
   final ir.Class node;
 
   /// Cache of [_MemberData] for members in this class.
-  Map<String, _MemberData> _members;
+  Map<String, _MemberData> _membersByName;
+  Map<ir.Member, _MemberData> _membersByNode;
 
   _ClassData(this.node);
 
-  /// Returns the [_MemberData] for the member uniquely identified by [name] in
-  /// this class.
-  _MemberData lookupMember(String name) {
-    if (_members == null) {
-      _members = {};
+  void _ensureMembers() {
+    if (_membersByName == null) {
+      _membersByName = {};
+      _membersByNode = {};
       for (ir.Member member in node.members) {
         String name = _computeMemberName(member);
         if (name == null) continue;
-        assert(!_members.containsKey(name),
-            "Duplicate member '$name' in $_members trying to add $member.");
-        _members[name] = new _MemberData(member);
+        assert(
+            !_membersByName.containsKey(name),
+            "Duplicate member '$name' in $_membersByName "
+            "trying to add $member.");
+        assert(
+            !_membersByNode.containsKey(member),
+            "Duplicate member '$name' in $_membersByNode "
+            "trying to add $member.");
+        _membersByNode[member] = _membersByName[name] = new _MemberData(member);
       }
     }
-    return _members[name];
+  }
+
+  /// Returns the [_MemberData] for the member uniquely identified by [name] in
+  /// this class.
+  _MemberData lookupMemberDataByName(String name) {
+    _ensureMembers();
+    return _membersByName[name];
+  }
+
+  /// Returns the [_MemberData] for the member [node] in this class.
+  _MemberData lookupMemberDataByNode(ir.Member node) {
+    _ensureMembers();
+    return _membersByNode[node];
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 2de3e8a..c65a05c 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -142,14 +142,14 @@
   }
 
   @override
-  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(),
+  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member),
       {bool emptyAsNull: false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
       MemberEntity member = readMember();
-      V value = f();
+      V value = f(member);
       map[member] = value;
     }
     return map;
@@ -516,7 +516,8 @@
   }
 
   @override
-  void writeMemberMap<V>(Map<MemberEntity, V> map, void f(V value),
+  void writeMemberMap<V>(
+      Map<MemberEntity, V> map, void f(MemberEntity member, V value),
       {bool allowNull: false}) {
     if (map == null) {
       assert(allowNull);
@@ -525,7 +526,7 @@
       writeInt(map.length);
       map.forEach((MemberEntity member, V value) {
         writeMember(member);
-        f(value);
+        f(member, value);
       });
     }
   }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 92e6ad0..425f6d2 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -187,6 +187,35 @@
   void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value),
       {bool allowNull: false});
 
+  /// Writes a reference to the kernel tree node [value] in the known [context]
+  /// to this data sink.
+  void writeTreeNodeInContext(ir.TreeNode value);
+
+  /// Writes a reference to the potentially `null` kernel tree node [value] in
+  /// the known [context] to this data sink.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSource.readTreeNodeOrNullInContext].
+  void writeTreeNodeOrNullInContext(ir.TreeNode value);
+
+  /// Writes references to the kernel tree node [values] in the known [context]
+  /// to this data sink. If [allowNull] is `true`, [values] is allowed to be
+  /// `null`.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSource.readTreeNodesInContext].
+  void writeTreeNodesInContext(Iterable<ir.TreeNode> values,
+      {bool allowNull: false});
+
+  /// Writes the [map] from references to kernel tree nodes to [V] values in the
+  /// known [context] to this data sink, calling [f] to write each value to the
+  /// data sink. If [allowNull] is `true`, [map] is allowed to be `null`.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSource.readTreeNodeMapInContext].
+  void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V> map, void f(V value),
+      {bool allowNull: false});
+
   /// Writes a reference to the kernel type parameter node [value] to this data
   /// sink.
   void writeTypeParameterNode(ir.TypeParameter value);
@@ -297,7 +326,8 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSource.readMemberMap].
-  void writeMemberMap<V>(Map<MemberEntity, V> map, void f(V value),
+  void writeMemberMap<V>(
+      Map<MemberEntity, V> map, void f(MemberEntity member, V value),
       {bool allowNull: false});
 
   /// Writes a reference to the local [value] to this data sink.
@@ -406,6 +436,11 @@
   /// Register a [CodegenWriter] with this data sink to support serialization
   /// of codegen only data.
   void registerCodegenWriter(CodegenWriter writer);
+
+  /// Invoke [f] in the context of [member]. This sets up support for
+  /// serialization of `ir.TreeNode`s using the `writeTreeNode*InContext`
+  /// methods.
+  void inMemberContext(ir.Member member, void f());
 }
 
 /// Interface for deserialization.
@@ -446,6 +481,11 @@
   /// for deserialization of codegen only data.
   void deregisterCodegenReader(CodegenReader reader);
 
+  /// Invoke [f] in the context of [member]. This sets up support for
+  /// deserialization of `ir.TreeNode`s using the `readTreeNode*InContext`
+  /// methods.
+  T inMemberContext<T>(ir.Member member, T f());
+
   /// Reads a reference to an [E] value from this data source. If the value has
   /// not yet been deserialized, [f] is called to deserialize the value itself.
   E readCached<E>(E f());
@@ -577,6 +617,33 @@
   Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f(),
       {bool emptyAsNull: false});
 
+  /// Reads a reference to a kernel tree node in the known [context] from this
+  /// data source.
+  ir.TreeNode readTreeNodeInContext();
+
+  /// Reads a reference to a potentially `null` kernel tree node in the known
+  /// [context] from this data source.
+  ir.TreeNode readTreeNodeOrNullInContext();
+
+  /// Reads a list of references to kernel tree nodes in the known [context]
+  /// from this data source. If [emptyAsNull] is `true`, `null` is returned
+  /// instead of an empty list.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSink.writeTreeNodesInContext].
+  List<E> readTreeNodesInContext<E extends ir.TreeNode>(
+      {bool emptyAsNull: false});
+
+  /// Reads a map from kernel tree nodes to [V] values in the known [context]
+  /// from this data source, calling [f] to read each value from the data
+  /// source. If [emptyAsNull] is `true`, `null` is returned instead of an empty
+  /// map.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSink.writeTreeNodeMapInContext].
+  Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f(),
+      {bool emptyAsNull: false});
+
   /// Reads a reference to a kernel type parameter node from this data source.
   ir.TypeParameter readTypeParameterNode();
 
@@ -668,7 +735,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSink.writeMemberMap].
-  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(),
+  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member),
       {bool emptyAsNull: false});
 
   /// Reads a reference to a local from this data source.
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 61771d5..f9affee 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -29,7 +29,7 @@
   InferredData inferredData = results.inferredData;
   closedWorld.writeToDataSink(sink);
   inferredData.writeToDataSink(sink);
-  results.writeToDataSink(sink);
+  results.writeToDataSink(sink, closedWorld.elementMap);
   sink.close();
 }
 
@@ -45,7 +45,7 @@
   InferredData newInferredData =
       new InferredData.readFromDataSource(source, newClosedWorld);
   return new GlobalTypeInferenceResults.readFromDataSource(
-      source, newClosedWorld, newInferredData);
+      source, newClosedWorld.elementMap, newClosedWorld, newInferredData);
 }
 
 class SerializationTask extends CompilerTask {
@@ -134,7 +134,9 @@
       sink.registerEntityWriter(entityWriter);
       sink.registerCodegenWriter(new CodegenWriterImpl(closedWorld));
       sink.writeMemberMap(
-          results, (CodegenResult result) => result.writeToDataSink(sink));
+          results,
+          (MemberEntity member, CodegenResult result) =>
+              result.writeToDataSink(sink));
       sink.close();
     });
   }
@@ -155,7 +157,7 @@
         DataSource source = new BinarySourceImpl(dataInput.data);
         backendStrategy.prepareCodegenReader(source);
         Map<MemberEntity, CodegenResult> codegenResults =
-            source.readMemberMap(() {
+            source.readMemberMap((MemberEntity member) {
           List<ModularName> modularNames = [];
           List<ModularExpression> modularExpressions = [];
           CodegenReader reader = new CodegenReaderImpl(
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 257c019..2fa3bac 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -789,25 +789,31 @@
       bool needsTypeArguments =
           closedWorld.rtiNeed.classNeedsTypeArguments(cls);
       if (needsTypeArguments) {
-        // Read the values of the type arguments and create a
-        // HTypeInfoExpression to set on the newly created object.
-        List<HInstruction> typeArguments = <HInstruction>[];
-        InterfaceType thisType = _elementEnvironment.getThisType(cls);
-        for (DartType typeVariable in thisType.typeArguments) {
-          HInstruction argument = localsHandler
-              .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
-          typeArguments.add(argument);
+        if (options.experimentNewRti) {
+          InterfaceType thisType = _elementEnvironment.getThisType(cls);
+          HInstruction typeArgument =
+              _typeBuilder.analyzeTypeArgumentNewRti(thisType, sourceElement);
+          constructorArguments.add(typeArgument);
+        } else {
+          // Read the values of the type arguments and create a
+          // HTypeInfoExpression to set on the newly created object.
+          List<HInstruction> typeArguments = <HInstruction>[];
+          InterfaceType thisType = _elementEnvironment.getThisType(cls);
+          for (DartType typeVariable in thisType.typeArguments) {
+            HInstruction argument = localsHandler
+                .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
+            typeArguments.add(argument);
+          }
+
+          HInstruction typeInfo = new HTypeInfoExpression(
+              TypeInfoExpressionKind.INSTANCE,
+              thisType,
+              typeArguments,
+              _abstractValueDomain.dynamicType);
+          add(typeInfo);
+          constructorArguments.add(typeInfo);
         }
-
-        HInstruction typeInfo = new HTypeInfoExpression(
-            TypeInfoExpressionKind.INSTANCE,
-            thisType,
-            typeArguments,
-            _abstractValueDomain.dynamicType);
-        add(typeInfo);
-        constructorArguments.add(typeInfo);
       }
-
       newObject = new HCreate(cls, constructorArguments,
           _abstractValueDomain.createNonNullExact(cls), sourceInformation,
           instantiatedTypes: instantiatedTypes,
@@ -1454,12 +1460,16 @@
         if (!bound.isDynamic &&
             !bound.isVoid &&
             bound != _commonElements.objectType) {
-          _assertIsType(
-              newParameter,
-              bound,
-              "The type argument '",
-              "' is not a subtype of the type variable bound '",
-              "' of type variable '${local.name}' in '${method.name}'.");
+          if (options.experimentNewRti) {
+            _checkTypeBound(newParameter, bound, local.name);
+          } else {
+            _assertIsType(
+                newParameter,
+                bound,
+                "The type argument '",
+                "' is not a subtype of the type variable bound '",
+                "' of type variable '${local.name}' in '${method.name}'.");
+          }
         }
       }
     }
@@ -3048,6 +3058,17 @@
     if (!_rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
       return object;
     }
+    if (options.experimentNewRti) {
+      // [type] could be `List<T>`, so ensure it is `JSArray<T>`.
+      InterfaceType arrayType =
+          InterfaceType(_commonElements.jsArrayClass, type.typeArguments);
+      HInstruction rti =
+          _typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
+
+      // TODO(15489): Register at codegen.
+      registry?.registerInstantiation(type);
+      return _callSetRuntimeTypeInfo(rti, object, sourceInformation);
+    }
     List<HInstruction> arguments = <HInstruction>[];
     for (DartType argument in type.typeArguments) {
       arguments.add(_typeBuilder.analyzeTypeArgument(argument, sourceElement));
@@ -4030,6 +4051,8 @@
       _handleJsInterceptorConstant(invocation);
     } else if (name == 'getInterceptor') {
       _handleForeignGetInterceptor(invocation);
+    } else if (name == 'getJSArrayInteropRti') {
+      _handleForeignGetJSArrayInteropRti(invocation);
     } else if (name == 'JS_STRING_CONCAT') {
       _handleJsStringConcat(invocation);
     } else if (name == '_createInvocationMirror') {
@@ -4592,6 +4615,24 @@
     stack.add(instruction);
   }
 
+  void _handleForeignGetJSArrayInteropRti(ir.StaticInvocation invocation) {
+    if (_unexpectedForeignArguments(invocation,
+            minPositional: 0, maxPositional: 0) ||
+        !options.experimentNewRti) {
+      // Result expected on stack.
+      stack.add(graph.addConstantNull(closedWorld));
+      return;
+    }
+    // TODO(sra): Introduce 'any' type.
+    InterfaceType interopType =
+        InterfaceType(_commonElements.jsArrayClass, [DynamicType()]);
+    SourceInformation sourceInformation =
+        _sourceInformationBuilder.buildCall(invocation, invocation);
+    HInstruction rti = HLoadType(interopType, _abstractValueDomain.dynamicType)
+      ..sourceInformation = sourceInformation;
+    push(rti);
+  }
+
   void _handleForeignJs(ir.StaticInvocation invocation) {
     if (_unexpectedForeignArguments(invocation,
         minPositional: 2, maxPositional: null, typeArgumentCount: 1)) {
@@ -5212,6 +5253,24 @@
     add(assertIsSubtype);
   }
 
+  void _checkTypeBound(
+      HInstruction typeInstruction, DartType bound, String variableName) {
+    HInstruction boundInstruction = _typeBuilder.analyzeTypeArgumentNewRti(
+        localsHandler.substInContext(bound), sourceElement);
+
+    HInstruction variableNameInstruction =
+        graph.addConstantString(variableName, closedWorld);
+    FunctionEntity element = _commonElements.checkTypeBound;
+    var inputs = <HInstruction>[
+      typeInstruction,
+      boundInstruction,
+      variableNameInstruction
+    ];
+    HInstruction checkBound = new HInvokeStatic(
+        element, inputs, typeInstruction.instructionType, const <DartType>[]);
+    add(checkBound);
+  }
+
   @override
   void visitConstructorInvocation(ir.ConstructorInvocation node) {
     SourceInformation sourceInformation =
@@ -5290,6 +5349,13 @@
       return;
     }
 
+    if (options.experimentNewRti) {
+      HInstruction rti =
+          _typeBuilder.analyzeTypeArgumentNewRti(typeValue, sourceElement);
+      push(HIsTest(typeValue, expression, rti, _abstractValueDomain.boolType));
+      return;
+    }
+
     if (typeValue is FunctionType) {
       HInstruction representation =
           _typeBuilder.analyzeTypeArgument(typeValue, sourceElement);
@@ -6876,6 +6942,12 @@
   }
 
   @override
+  visitConstantExpression(ir.ConstantExpression node) {
+    registerRegularNode();
+    registerReductiveNode();
+  }
+
+  @override
   visitReturnStatement(ir.ReturnStatement node) {
     registerRegularNode();
     node.visitChildren(this);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index a80a7a6..6c5154c 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -26,8 +26,10 @@
 import '../js_backend/native_data.dart';
 import '../js_backend/namer.dart' show ModularNamer;
 import '../js_backend/runtime_types.dart';
+import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
 import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
 import '../js_model/elements.dart' show JGeneratorBody;
+import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
 import '../native/behavior.dart';
 import '../options.dart';
 import '../tracer.dart';
@@ -114,6 +116,7 @@
           codegen.checkedModeHelpers,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
+          codegen.rtiRecipeEncoder,
           namer,
           codegen.tracer,
           closedWorld,
@@ -143,6 +146,7 @@
           codegen.checkedModeHelpers,
           codegen.rtiSubstitutions,
           codegen.rtiEncoder,
+          codegen.rtiRecipeEncoder,
           namer,
           codegen.tracer,
           closedWorld,
@@ -180,6 +184,7 @@
   final CheckedModeHelpers _checkedModeHelpers;
   final RuntimeTypesSubstitutions _rtiSubstitutions;
   final RuntimeTypesEncoder _rtiEncoder;
+  final RecipeEncoder _rtiRecipeEncoder;
   final ModularNamer _namer;
   final Tracer _tracer;
   final JClosedWorld _closedWorld;
@@ -234,6 +239,7 @@
       this._checkedModeHelpers,
       this._rtiSubstitutions,
       this._rtiEncoder,
+      this._rtiRecipeEncoder,
       this._namer,
       this._tracer,
       this._closedWorld,
@@ -3334,6 +3340,8 @@
 
   @override
   visitIsTest(HIsTest node) {
+    _registry.registerTypeUse(new TypeUse.isCheck(node.dartType));
+
     use(node.typeInput);
     js.Expression first = pop();
     use(node.checkedInput);
@@ -3372,20 +3380,36 @@
     FunctionEntity helperElement = _commonElements.findType;
     _registry.registerStaticUse(
         new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
-    // TODO(sra): Encode recipe.
-    js.Expression recipe = js.string('${node.typeExpression}');
+    js.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
+        _emitter, TypeExpressionRecipe(node.typeExpression));
     js.Expression helper = _emitter.staticFunctionAccess(helperElement);
     push(js.js(r'#(#)', [helper, recipe]).withSourceInformation(
         node.sourceInformation));
   }
 
   @override
+  visitInstanceEnvironment(HInstanceEnvironment node) {
+    use(node.inputs.single);
+    js.Expression receiver = pop();
+    // TODO(sra): Optimize to direct field access where possible.
+    //
+    //    push(js.js(r'#.#', [receiver, _namer.rtiFieldJsName]));
+
+    FunctionEntity helperElement = _commonElements.instanceType;
+    _registry.registerStaticUse(
+        new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
+    js.Expression helper = _emitter.staticFunctionAccess(helperElement);
+    push(js.js(r'#(#)', [helper, receiver]).withSourceInformation(
+        node.sourceInformation));
+  }
+
+  @override
   visitTypeEval(HTypeEval node) {
     // Call `env._eval("recipe")`.
     use(node.inputs[0]);
     js.Expression environment = pop();
-    // TODO(sra): Encode recipe.
-    js.Expression recipe = js.string('${node.typeExpression}');
+    js.Expression recipe = _rtiRecipeEncoder.encodeRecipe(
+        _emitter, node.envStructure, node.typeExpression);
 
     MemberEntity method = _commonElements.rtiEvalMethod;
     Selector selector = Selector.fromElement(method);
@@ -3409,7 +3433,7 @@
     use(node.inputs[1]);
     js.Expression extensions = pop();
 
-    MemberEntity method = _commonElements.rtiEvalMethod;
+    MemberEntity method = _commonElements.rtiBindMethod;
     Selector selector = Selector.fromElement(method);
     js.Name methodLiteral = _namer.invocationName(selector);
     push(js.js('#.#(#)', [
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index ac8f779..a7d0316 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -110,6 +110,7 @@
   R visitAsCheck(HAsCheck node);
   R visitSubtypeCheck(HSubtypeCheck node);
   R visitLoadType(HLoadType node);
+  R visitInstanceEnvironment(HInstanceEnvironment node);
   R visitTypeEval(HTypeEval node);
   R visitTypeBind(HTypeBind node);
 }
@@ -606,6 +607,8 @@
   @override
   visitLoadType(HLoadType node) => visitInstruction(node);
   @override
+  visitInstanceEnvironment(HInstanceEnvironment node) => visitInstruction(node);
+  @override
   visitTypeEval(HTypeEval node) => visitInstruction(node);
   @override
   visitTypeBind(HTypeBind node) => visitInstruction(node);
@@ -1091,8 +1094,9 @@
   static const int AS_CHECK_TYPECODE = 48;
   static const int SUBTYPE_CHECK_TYPECODE = 49;
   static const int LOAD_TYPE_TYPECODE = 50;
-  static const int TYPE_EVAL_TYPECODE = 51;
-  static const int TYPE_BIND_TYPECODE = 52;
+  static const int INSTANCE_ENVIRONMENT_TYPECODE = 51;
+  static const int TYPE_EVAL_TYPECODE = 52;
+  static const int TYPE_BIND_TYPECODE = 53;
 
   HInstruction(this.inputs, this.instructionType)
       : id = idCounter++,
@@ -2903,6 +2907,7 @@
 
   @override
   ThisLocal get sourceElement => super.sourceElement;
+
   @override
   void set sourceElement(covariant ThisLocal local) {
     super.sourceElement = local;
@@ -4343,7 +4348,10 @@
 /// lowered to other instructions, so this instruction remains for types that
 /// depend on type variables and complex types.
 class HIsTest extends HInstruction {
-  HIsTest(HInstruction checked, HInstruction rti, AbstractValue type)
+  final DartType dartType;
+
+  HIsTest(
+      this.dartType, HInstruction checked, HInstruction rti, AbstractValue type)
       : super([rti, checked], type) {
     setUseGvn();
   }
@@ -4464,6 +4472,33 @@
   String toString() => 'HLoadType($typeExpression)';
 }
 
+/// The reified Rti environment stored on a class instance.
+///
+/// Classes with reified type arguments have the type environment stored on the
+/// instance. The reified environment is typically stored as the instance type,
+/// e.g. "UnmodifiableListView<int>".
+class HInstanceEnvironment extends HRtiInstruction {
+  HInstanceEnvironment(HInstruction instance, AbstractValue type)
+      : super([instance], type) {
+    setUseGvn();
+  }
+
+  @override
+  accept(HVisitor visitor) => visitor.visitInstanceEnvironment(this);
+
+  @override
+  int typeCode() => HInstruction.INSTANCE_ENVIRONMENT_TYPECODE;
+
+  @override
+  bool typeEquals(HInstruction other) => other is HInstanceEnvironment;
+
+  @override
+  bool dataEquals(HInstanceEnvironment other) => true;
+
+  @override
+  String toString() => 'HInstanceEnvironment()';
+}
+
 /// Evaluates an Rti type recipe in an Rti environment.
 class HTypeEval extends HRtiInstruction {
   TypeEnvironmentStructure envStructure;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 1a27e5b..865c0ff 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -636,6 +636,8 @@
       return splitInstruction;
     }
 
+    // TODO(sra): Implement tagging with `JSArray<String>` for new rti.
+
     node.block.addBefore(node, splitInstruction);
 
     HInstruction stringTypeInfo = new HTypeInfoExpression(
@@ -1639,20 +1641,50 @@
 
       for (HInstruction argument in node.inputs) {
         if (argument is HTypeInfoReadVariable) {
+          ClassEntity context = DartTypes.getClassContext(argument.variable);
           HInstruction nextSource = argument.object;
+          if (nextSource is HRef) {
+            HRef ref = nextSource;
+            nextSource = ref.value;
+          }
           if (nextSource is HThis) {
             if (source == null) {
               source = nextSource;
-              ClassEntity contextClass =
-                  nextSource.sourceElement.enclosingClass;
-              if (node.inputs.length !=
-                  _closedWorld.elementEnvironment
-                      .getThisType(contextClass)
-                      .typeArguments
-                      .length) {
+              ClassEntity thisClass = nextSource.sourceElement.enclosingClass;
+              InterfaceType thisType =
+                  _closedWorld.elementEnvironment.getThisType(thisClass);
+              if (node.inputs.length != thisType.typeArguments.length) {
                 return null;
               }
-              if (needsSubstitutionForTypeVariableAccess(contextClass)) {
+              if (needsSubstitutionForTypeVariableAccess(thisClass)) {
+                return null;
+              }
+              if (context != null &&
+                  !_rtiSubstitutions.isTrivialSubstitution(
+                      thisClass, context)) {
+                // If inlining, the [context] is not the same as [thisClass].
+                // If this is the case, then the substitution must be trivial.
+                // Consider this:
+                //
+                //    class A {
+                //      final Object value;
+                //      A(this.value);
+                //    }
+                //    class B<T> extends A {
+                //      B(T value) : super(value);
+                //      T get value => super.value as T;
+                //    }
+                //    class C<S> extends B<List<S>> {
+                //      C(List<S> value) : super(value);
+                //      S get first => value.first;
+                //    }
+                //
+                // If `B.value` is inlined into `C.first` the type info
+                // expression is the list `[B.T]` on a `this` of type `C<S>`.
+                // Since the substitution from C to B is not trivial
+                // (S -> List<S>) this type info expression cannot be replaced
+                // with the type arguments `C<S>` (it would yield [S] instead of
+                // [List<S>]).
                 return null;
               }
             }
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 539261d..7ca5ee2 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -675,38 +675,44 @@
   }
 
   @override
-  visitIsTest(HIsTest node) {
+  String visitIsTest(HIsTest node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     return "IsTest: $inputs";
   }
 
   @override
-  visitAsCheck(HAsCheck node) {
+  String visitAsCheck(HAsCheck node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     String error = node.isTypeError ? 'TypeError' : 'CastError';
     return "AsCheck: $error $inputs";
   }
 
   @override
-  visitSubtypeCheck(HSubtypeCheck node) {
+  String visitSubtypeCheck(HSubtypeCheck node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     return "SubtypeCheck: $inputs";
   }
 
   @override
-  visitLoadType(HLoadType node) {
+  String visitLoadType(HLoadType node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     return "LoadType: ${node.typeExpression}  $inputs";
   }
 
   @override
-  visitTypeEval(HTypeEval node) {
+  String visitInstanceEnvironment(HInstanceEnvironment node) {
+    var inputs = node.inputs.map(temporaryId).join(', ');
+    return "InstanceEnvironment: $inputs";
+  }
+
+  @override
+  String visitTypeEval(HTypeEval node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     return "TypeEval: ${node.typeExpression}  $inputs";
   }
 
   @override
-  visitTypeBind(HTypeBind node) {
+  String visitTypeBind(HTypeBind node) {
     var inputs = node.inputs.map(temporaryId).join(', ');
     return "TypeBind: $inputs";
   }
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 11c31ec..03ad305 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -247,6 +247,10 @@
   HInstruction analyzeTypeArgument(
       DartType argument, MemberEntity sourceElement,
       {SourceInformation sourceInformation}) {
+    if (builder.options.experimentNewRti) {
+      return analyzeTypeArgumentNewRti(argument, sourceElement,
+          sourceInformation: sourceInformation);
+    }
     argument = argument.unaliased;
     if (argument.treatAsDynamic) {
       // Represent [dynamic] as [null].
@@ -279,25 +283,136 @@
       {SourceInformation sourceInformation}) {
     argument = argument.unaliased;
 
-    if (argument.containsFreeTypeVariables) {
-      // TODO(sra): Locate type environment.
-      HInstruction environment =
-          builder.graph.addConstantString("env", _closedWorld);
-      // TODO(sra): Determine environment structure from context.
-      TypeEnvironmentStructure structure = null;
-      HInstruction rti = HTypeEval(environment, structure,
-          TypeExpressionRecipe(argument), _abstractValueDomain.dynamicType)
+    if (!argument.containsTypeVariables) {
+      HInstruction rti = HLoadType(argument, _abstractValueDomain.dynamicType)
         ..sourceInformation = sourceInformation;
       builder.add(rti);
       return rti;
     }
+    // TODO(sra): Locate type environment.
+    _EnvironmentExpressionAndStructure environmentAccess =
+        _buildEnvironmentForType(argument, sourceElement,
+            sourceInformation: sourceInformation);
 
-    HInstruction rti = HLoadType(argument, _abstractValueDomain.dynamicType)
+    HInstruction rti = HTypeEval(
+        environmentAccess.expression,
+        environmentAccess.structure,
+        TypeExpressionRecipe(argument),
+        _abstractValueDomain.dynamicType)
       ..sourceInformation = sourceInformation;
     builder.add(rti);
     return rti;
   }
 
+  _EnvironmentExpressionAndStructure _buildEnvironmentForType(
+      DartType type, MemberEntity member,
+      {SourceInformation sourceInformation}) {
+    assert(type.containsTypeVariables);
+    // Build the environment for each access, and hope GVN reduces the larger
+    // number of expressions. Another option is to precompute the environment at
+    // procedure entry and optimize early-exits by sinking the precomputed
+    // environment.
+
+    // Split the type variables into class-scope and function-scope(s).
+    bool usesInstanceParameters = false;
+    InterfaceType interfaceType;
+    Set<TypeVariableType> parameters = Set();
+
+    void processTypeVariable(TypeVariableType type) {
+      ClassTypeVariableAccess typeVariableAccess;
+      if (type.element.typeDeclaration is ClassEntity) {
+        typeVariableAccess = computeTypeVariableAccess(member);
+        interfaceType = _closedWorld.elementEnvironment
+            .getThisType(type.element.typeDeclaration);
+      } else {
+        typeVariableAccess = ClassTypeVariableAccess.parameter;
+      }
+      switch (typeVariableAccess) {
+        case ClassTypeVariableAccess.parameter:
+          parameters.add(type);
+          return;
+        case ClassTypeVariableAccess.instanceField:
+          if (member != builder.targetElement) {
+            // When [member] is a field, we can either be generating a checked
+            // setter or inlining its initializer in a constructor. An
+            // initializer is never built standalone, so in that case [target]
+            // is not the [member] itself.
+            parameters.add(type);
+            return;
+          }
+          usesInstanceParameters = true;
+          return;
+        case ClassTypeVariableAccess.property:
+          usesInstanceParameters = true;
+          return;
+        default:
+          builder.reporter.internalError(
+              type.element, 'Unexpected type variable in static context.');
+      }
+    }
+
+    type.forEachTypeVariable(processTypeVariable);
+
+    HInstruction environment;
+    TypeEnvironmentStructure structure;
+
+    if (usesInstanceParameters) {
+      HInstruction target =
+          builder.localsHandler.readThis(sourceInformation: sourceInformation);
+      // TODO(sra): HInstanceEnvironment should probably take an interceptor to
+      // allow the getInterceptor call to be reused.
+      environment =
+          HInstanceEnvironment(target, _abstractValueDomain.dynamicType)
+            ..sourceInformation = sourceInformation;
+      builder.add(environment);
+      structure = FullTypeEnvironmentStructure(classType: interfaceType);
+    }
+
+    // TODO(sra): Visit parameters in source-order.
+    for (TypeVariableType parameter in parameters) {
+      Local typeVariableLocal =
+          builder.localsHandler.getTypeVariableAsLocal(parameter);
+      HInstruction access = builder.localsHandler
+          .readLocal(typeVariableLocal, sourceInformation: sourceInformation);
+
+      if (environment == null) {
+        environment = access;
+        structure = SingletonTypeEnvironmentStructure(parameter);
+      } else if (structure is SingletonTypeEnvironmentStructure) {
+        SingletonTypeEnvironmentStructure singletonStructure = structure;
+        // Convert a singleton environment into a singleton tuple and extend it
+        // via 'bind'. i.e. generate `env1._eval("@<0>")._bind(env2)` TODO(sra):
+        // Have a bind1 instruction.
+        // TODO(sra): Add a 'Rti._bind1' method to shorten and accelerate this
+        // common case.
+        HInstruction singletonTuple = HTypeEval(
+            environment,
+            structure,
+            FullTypeEnvironmentRecipe(types: [singletonStructure.variable]),
+            _abstractValueDomain.dynamicType)
+          ..sourceInformation = sourceInformation;
+        builder.add(singletonTuple);
+        environment =
+            HTypeBind(singletonTuple, access, _abstractValueDomain.dynamicType);
+        builder.add(environment);
+        structure = FullTypeEnvironmentStructure(
+            bindings: [singletonStructure.variable, parameter]);
+      } else if (structure is FullTypeEnvironmentStructure) {
+        FullTypeEnvironmentStructure fullStructure = structure;
+        environment =
+            HTypeBind(environment, access, _abstractValueDomain.dynamicType);
+        builder.add(environment);
+        structure = FullTypeEnvironmentStructure(
+            classType: fullStructure.classType,
+            bindings: [...fullStructure.bindings, parameter]);
+      } else {
+        builder.reporter.internalError(parameter.element, 'Unexpected');
+      }
+    }
+
+    return _EnvironmentExpressionAndStructure(environment, structure);
+  }
+
   /// Build a [HTypeConversion] for converting [original] to type [type].
   ///
   /// Invariant: [type] must be valid in the context.
@@ -357,8 +472,9 @@
     if (type.isVoid) return original;
     if (type == _closedWorld.commonElements.objectType) return original;
 
-    HInstruction reifiedType =
-        analyzeTypeArgumentNewRti(type, builder.sourceElement);
+    HInstruction reifiedType = analyzeTypeArgumentNewRti(
+        type, builder.sourceElement,
+        sourceInformation: sourceInformation);
     if (type is InterfaceType) {
       // TODO(sra): Under NNDB opt-in, this will be NonNullable.
       AbstractValue subtype =
@@ -374,3 +490,9 @@
     }
   }
 }
+
+class _EnvironmentExpressionAndStructure {
+  final HInstruction expression;
+  final TypeEnvironmentStructure structure;
+  _EnvironmentExpressionAndStructure(this.expression, this.structure);
+}
diff --git a/pkg/dart_internal/pubspec.yaml b/pkg/dart_internal/pubspec.yaml
index 9a15238..89bb3d6 100644
--- a/pkg/dart_internal/pubspec.yaml
+++ b/pkg/dart_internal/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart_internal
-version: 0.1.4
+version: 0.1.5
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
@@ -16,4 +16,4 @@
 environment:
   # Restrict the upper bound so that we can remove support for this in a later
   # version of the SDK without it being a breaking change.
-  sdk: ">=2.0.0-dev.12.0 <2.4.0"
+  sdk: ">=2.0.0-dev.12.0 <2.5.0"
diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 249dc5d..efc01ff 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -1,3 +1,5 @@
+include: package:pedantic/analysis_options.1.8.0.yaml
+
 analyzer:
   strong-mode:
     implicit-casts: false
@@ -14,27 +16,3 @@
 linter:
   rules:
     - annotate_overrides
-    - avoid_empty_else
-    - avoid_init_to_null
-    - avoid_relative_lib_imports
-    - avoid_return_types_on_setters
-    - avoid_shadowing_type_parameters
-    - avoid_types_as_parameter_names
-    - curly_braces_in_flow_control_structures
-    - empty_catches
-    - empty_constructor_bodies
-    - library_names
-    - library_prefixes
-    - no_duplicate_case_values
-    - null_closures
-    - prefer_contains
-    - prefer_equal_for_default_values
-    - prefer_is_empty
-    - prefer_is_not_empty
-    - recursive_getters
-    - type_init_formals
-    - unawaited_futures
-    - unnecessary_null_in_if_null_operators
-    - unrelated_type_equality_checks
-    - use_rethrow_when_possible
-    - valid_regexps
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index db2f7b8..4d4ac46 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -23,8 +23,8 @@
 
   if (parsedArgs.isWorker) {
     var workerConnection = sendPort == null
-        ? new StdAsyncWorkerConnection()
-        : new SendPortAsyncWorkerConnection(sendPort);
+        ? StdAsyncWorkerConnection()
+        : SendPortAsyncWorkerConnection(sendPort);
     await _CompilerWorker(parsedArgs, workerConnection).run();
   } else if (parsedArgs.isBatch) {
     await runBatch(parsedArgs);
@@ -52,7 +52,16 @@
     var args = _startupArgs.merge(request.arguments);
     var output = StringBuffer();
     var context = args.reuseResult ? lastResult : null;
-    lastResult = await runZoned(() => compile(args, previousResult: context),
+
+    /// Build a map of uris to digests.
+    final inputDigests = <Uri, List<int>>{};
+    for (var input in request.inputs) {
+      inputDigests[Uri.base.resolve(input.path)] = input.digest;
+    }
+
+    lastResult = await runZoned(
+        () =>
+            compile(args, previousResult: context, inputDigests: inputDigests),
         zoneSpecification:
             ZoneSpecification(print: (self, parent, zone, message) {
       output.writeln(message.toString());
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 3d4d114..519cd8b 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart' show StringToken;
-import 'package:analyzer/src/dart/ast/utilities.dart' show UIAsCodeVisitorMixin;
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -68,7 +67,6 @@
 // (which result in (JS.Statement).
 class CodeGenerator extends Object
     with
-        UIAsCodeVisitorMixin<js_ast.Node>,
         NullableTypeInference,
         SharedCompiler<LibraryElement, ClassElement, InterfaceType,
             FunctionBody>
@@ -5500,7 +5498,7 @@
       variable = forParts.loopVariable.identifier;
       init = js.call('let # = #.current', [_emitVariableDef(variable), iter]);
     } else {
-      throw new StateError('Unrecognized for loop parts');
+      throw StateError('Unrecognized for loop parts');
     }
     return js.statement(
         '{'
@@ -6518,7 +6516,7 @@
     } else if (forParts is ForPartsWithDeclarations) {
       init = visitVariableDeclarationList(forParts.variables);
     } else {
-      throw new StateError('Unrecognized for loop parts');
+      throw StateError('Unrecognized for loop parts');
     }
     js_ast.Expression update;
     if (forParts.updaters != null && forParts.updaters.isNotEmpty) {
@@ -6550,7 +6548,7 @@
         ]);
       }
     } else {
-      throw new StateError('Unrecognized for loop parts');
+      throw StateError('Unrecognized for loop parts');
     }
     return js_ast.ForOf(jsLeftExpression, jsIterable, jsBody);
   }
@@ -6620,7 +6618,7 @@
       } else if (forParts is ForEachPartsWithDeclaration) {
         variable = forParts.loopVariable.identifier;
       } else {
-        throw new StateError('Unrecognized for loop parts');
+        throw StateError('Unrecognized for loop parts');
       }
       var castType = getImplicitCast(variable);
       if (castType != null) {
@@ -6748,6 +6746,9 @@
 
   @override
   visitExtensionDeclaration(ExtensionDeclaration node) => _unreachable(node);
+
+  @override
+  visitExtensionOverride(ExtensionOverride node) => _unreachable(node);
 }
 
 // TODO(jacobr): we would like to do something like the following
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 02e108e..b3f4d3f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -14,7 +14,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart' hide CustomUriResolver;
 import 'package:analyzer/src/summary/package_bundle_reader.dart'
-    show InSummaryUriResolver, SummaryDataStore;
+    show InSummarySource, InSummaryUriResolver, SummaryDataStore;
 import 'package:args/args.dart' show ArgParser, ArgResults;
 import 'package:cli_util/cli_util.dart' show getSdkPath;
 import 'package:path/path.dart' as path;
@@ -40,10 +40,14 @@
   /// The default analysis root.
   String analysisRoot = path.current;
 
+  // May be null.
+  final DependencyTracker dependencyTracker;
+
   AnalyzerOptions._(
       {this.contextBuilderOptions,
       String dartSdkPath,
-      this.customUrlMappings = const {}})
+      this.customUrlMappings = const {},
+      this.dependencyTracker})
       : dartSdkPath = dartSdkPath ?? getSdkPath() {
     contextBuilderOptions.declaredVariables ??= const {};
   }
@@ -69,12 +73,16 @@
     // For building the SDK, we explicitly set the path to none.
     if (dartSdkSummaryPath == 'build') dartSdkSummaryPath = null;
     contextOpts.dartSdkSummaryPath = dartSdkSummaryPath;
+    var summaryDepsOutput = args['summary-deps-output'] as String;
+    var dependencyTracker =
+        summaryDepsOutput != null ? DependencyTracker(summaryDepsOutput) : null;
 
     return AnalyzerOptions._(
         contextBuilderOptions: contextOpts,
         dartSdkPath: dartSdkPath,
         customUrlMappings:
-            _parseUrlMappings(args['url-mapping'] as List<String>));
+            _parseUrlMappings(args['url-mapping'] as List<String>),
+        dependencyTracker: dependencyTracker);
   }
 
   static void addArguments(ArgParser parser, {bool hide = true}) {
@@ -126,7 +134,14 @@
         .add(CustomUriResolver(resourceProvider, options.customUrlMappings));
   }
   if (summaryData != null) {
-    resolvers.add(InSummaryUriResolver(resourceProvider, summaryData));
+    UriResolver summaryResolver =
+        InSummaryUriResolver(resourceProvider, summaryData);
+    if (options.dependencyTracker != null) {
+      // Wrap summaryResolver.
+      summaryResolver = TrackingInSummaryUriResolver(
+          summaryResolver, options.dependencyTracker);
+    }
+    resolvers.add(summaryResolver);
   }
 
   var fileResolvers = options.fileResolvers ?? createFileResolvers(options);
@@ -160,3 +175,34 @@
   }
   return mappings;
 }
+
+/// A set of path strings read during the build.
+class DependencyTracker {
+  final _dependencies = Set<String>();
+
+  /// The path to the file to create once tracking is done.
+  final String outputPath;
+
+  DependencyTracker(this.outputPath);
+
+  Iterable<String> get dependencies => _dependencies;
+
+  void record(String path) => _dependencies.add(path);
+}
+
+/// Wrapper for [UriResolver] that tracks accesses to summaries.
+class TrackingInSummaryUriResolver extends UriResolver {
+  final UriResolver _summaryResolver;
+  final DependencyTracker _dependencyTracker;
+
+  TrackingInSummaryUriResolver(this._summaryResolver, this._dependencyTracker);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    var source = _summaryResolver.resolveAbsolute(uri, actualUri);
+    if (source != null && source is InSummarySource) {
+      _dependencyTracker.record(source.summaryPath);
+    }
+    return source;
+  }
+}
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index 70bdc0a..0ce3e60 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -117,6 +117,12 @@
     }
   }
 
+  if (analyzerOptions.dependencyTracker != null) {
+    var file = File(analyzerOptions.dependencyTracker.outputPath);
+    file.writeAsStringSync(
+        (analyzerOptions.dependencyTracker.dependencies.toList()..sort()).join('\n'));
+  }
+
   var jsModule = JSModuleFile(
       errors.formattedErrors.toList(), options, jsProgram, driver.summaryBytes);
   return jsModule;
@@ -205,6 +211,9 @@
           hide: hide)
       ..addOption('summary-out',
           help: 'location to write the summary file', hide: hide)
+      ..addOption('summary-deps-output',
+          help: 'Path to a file to dump summary dependency info to.',
+          hide: hide)
       ..addOption('module-root',
           help: '(deprecated) used to determine the default module name and\n'
               'summary import name if those are not provided.',
diff --git a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
index 885172f..ecb118f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
@@ -369,7 +369,7 @@
           _nullableLocals.add(element);
         }
       } else {
-        throw new StateError('Unrecognized for loop parts');
+        throw StateError('Unrecognized for loop parts');
       }
     }
     super.visitForStatement(node);
diff --git a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
index 94f1c2edb..dd81f22 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_metalet.dart
@@ -292,9 +292,8 @@
     T tree, Map<MetaLetVariable, Expression> substitutions) {
   var generator = InstantiatorGeneratorVisitor(/*forceCopy:*/ false);
   var instantiator = generator.compile(tree);
-  var nodes = List<MetaLetVariable>.from(generator
-      .analysis.containsInterpolatedNode
-      .where((n) => n is MetaLetVariable));
+  var nodes = List<MetaLetVariable>.from(
+      generator.analysis.containsInterpolatedNode.whereType<MetaLetVariable>());
   if (nodes.isEmpty) return tree;
 
   return instantiator(Map.fromIterable(nodes,
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_command.dart b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
index 0388456..fbbf31d 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_command.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_command.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:collection';
 import 'dart:io';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:args/args.dart';
@@ -263,8 +262,8 @@
 List<String> filterUnknownArguments(List<String> args, ArgParser parser) {
   if (!args.contains('--ignore-unrecognized-flags')) return args;
 
-  var knownOptions = new HashSet<String>();
-  var knownAbbreviations = new HashSet<String>();
+  var knownOptions = <String>{};
+  var knownAbbreviations = <String>{};
   parser.options.forEach((String name, Option option) {
     knownOptions.add(name);
     var abbreviation = option.abbr;
@@ -400,7 +399,7 @@
 /// The result may also contain a [previousResult], which can be passed back in
 /// for batch/worker executions to attempt to existing state.
 Future<CompilerResult> compile(ParsedArguments args,
-    {CompilerResult previousResult}) {
+    {CompilerResult previousResult, Map<Uri, List<int>> inputDigests}) {
   if (previousResult != null && !args.isBatchOrWorker) {
     throw ArgumentError(
         'previousResult requires --batch or --bazel_worker mode/');
@@ -408,7 +407,8 @@
   if (args.isKernel) {
     return kernel_compiler.compile(args.rest,
         compilerState: previousResult?.kernelState,
-        useIncrementalCompiler: args.useIncrementalCompiler);
+        useIncrementalCompiler: args.useIncrementalCompiler,
+        inputDigests: inputDigests);
   } else {
     var result = analyzer_compiler.compile(args.rest,
         compilerState: previousResult?.analyzerState);
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index 2d0dd51..a03424d 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -2,6 +2,8 @@
 // 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.
 
+// ignore_for_file: slash_for_doc_comments, unnecessary_new
+
 // Utilities for building JS ASTs at runtime.  Contains a builder class
 // and a parser that parses part of the language.
 
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 36d2368..219e99a 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -2,6 +2,8 @@
 // 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.
 
+// ignore_for_file: slash_for_doc_comments
+
 part of js_ast;
 
 abstract class NodeVisitor<T> {
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index f4a9717..0349ce9 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -2,6 +2,8 @@
 // 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.
 
+// ignore_for_file: slash_for_doc_comments, unnecessary_const
+
 part of js_ast;
 
 class JavaScriptPrintingOptions {
@@ -1018,7 +1020,7 @@
       spaceOut();
       // Object initializers require parenthesis to disambiguate
       // AssignmentExpression from FunctionBody. See:
-      // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-function-definitions
+      // https://tc39.github.io/ecma262/#sec-arrow-function-definitions
       var needsParen = fun.body is ObjectInitializer;
       if (needsParen) out("(");
       visitNestedExpression(body, ASSIGNMENT,
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index 6363cd6..4fe7042 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -2,6 +2,8 @@
 // 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.
 
+// ignore_for_file: slash_for_doc_comments
+
 part of js_ast;
 
 class TemplateManager {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index ca85c12..22da1ec 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -37,11 +37,13 @@
 /// Returns `true` if the program compiled without any fatal errors.
 Future<CompilerResult> compile(List<String> args,
     {fe.InitializedCompilerState compilerState,
-    bool useIncrementalCompiler = false}) async {
+    bool useIncrementalCompiler = false,
+    Map<Uri, List<int>> inputDigests}) async {
   try {
     return await _compile(args,
         compilerState: compilerState,
-        useIncrementalCompiler: useIncrementalCompiler);
+        useIncrementalCompiler: useIncrementalCompiler,
+        inputDigests: inputDigests);
   } catch (error, stackTrace) {
     print('''
 We're sorry, you've found a bug in our compiler.
@@ -68,7 +70,8 @@
 
 Future<CompilerResult> _compile(List<String> args,
     {fe.InitializedCompilerState compilerState,
-    bool useIncrementalCompiler = false}) async {
+    bool useIncrementalCompiler = false,
+    Map<Uri, List<int>> inputDigests}) async {
   // TODO(jmesserly): refactor options to share code with dartdevc CLI.
   var argParser = ArgParser(allowTrailingOptions: true)
     ..addFlag('help',
@@ -214,7 +217,9 @@
   var experiments = <fe.ExperimentalFlag, bool>{};
   for (var name in options.experiments.keys) {
     var flag = fe.parseExperimentalFlag(name);
-    if (flag != null) {
+    if (flag == fe.ExperimentalFlag.expiredFlag) {
+      stderr.writeln("Flag '$name' is no longer required.");
+    } else if (flag != null) {
       experiments[flag] = options.experiments[name];
     } else {
       stderr.writeln("Unknown experiment flag '$name'.");
@@ -243,7 +248,7 @@
         fileSystem: fileSystem,
         experiments: experiments);
   } else {
-    doneInputSummaries = new List<Component>(summaryModules.length);
+    doneInputSummaries = List<Component>(summaryModules.length);
     compilerState = await fe.initializeIncrementalCompiler(
         oldCompilerState,
         doneInputSummaries,
@@ -253,6 +258,7 @@
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
         summaryModules.keys.toList(),
+        inputDigests,
         DevCompilerTarget(
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
@@ -286,7 +292,7 @@
     Component incrementalComponent = await incrementalCompiler.computeDelta(
         entryPoints: inputs, fullComponent: true);
     hierarchy = incrementalCompiler.userCode.loader.hierarchy;
-    result = new fe.DdcResult(incrementalComponent, doneInputSummaries);
+    result = fe.DdcResult(incrementalComponent, doneInputSummaries);
 
     // Workaround for DDC relying on isExternal being set to true.
     for (var lib in cachedSdkInput.component.libraries) {
@@ -329,7 +335,7 @@
     outFiles.add(sink.flush().then((_) => sink.close()));
   }
   if (argResults['summarize-text'] as bool) {
-    StringBuffer sb = new StringBuffer();
+    StringBuffer sb = StringBuffer();
     kernel.Printer(sb, showExternal: false).writeComponentFile(component);
     outFiles.add(File(output + '.txt').writeAsString(sb.toString()));
   }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 9971f7c..76c8c53 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -39,7 +39,7 @@
         ExpressionVisitor<js_ast.Expression>,
         DartTypeVisitor<js_ast.Expression>,
         ConstantVisitor<js_ast.Expression> {
-  final SharedCompilerOptions options;
+  final SharedCompilerOptions _options;
 
   /// Maps a library URI import, that is not in [_libraries], to the
   /// corresponding Kernel summary module we imported it with.
@@ -98,11 +98,11 @@
   // TODO(jmesserly): rename to `_nativeTypes`
   final NativeTypeSet _extensionTypes;
 
-  final CoreTypes coreTypes;
+  final CoreTypes _coreTypes;
 
-  final TypeEnvironment types;
+  final TypeEnvironment _types;
 
-  final ClassHierarchy hierarchy;
+  final ClassHierarchy _hierarchy;
 
   /// Information about virtual and overridden fields/getters/setters in the
   /// class we're currently compiling, or `null` if we aren't compiling a class.
@@ -110,7 +110,7 @@
 
   /// Information about virtual fields for all libraries in the current build
   /// unit.
-  final virtualFields = VirtualFieldModel();
+  final _virtualFields = VirtualFieldModel();
 
   final JSTypeRep _typeRep;
 
@@ -183,17 +183,17 @@
   /// continue statements and are used to simulate "jumping" to case statements.
   /// State variables hold the next constant case expression, while labels act
   /// as targets for continue and break.
-  final _switchLabelStates = HashMap<Statement, SwitchLabelState>();
+  final _switchLabelStates = HashMap<Statement, _SwitchLabelState>();
 
   final Class _jsArrayClass;
-  final Class privateSymbolClass;
-  final Class linkedHashMapImplClass;
-  final Class identityHashMapImplClass;
-  final Class linkedHashSetClass;
-  final Class linkedHashSetImplClass;
-  final Class identityHashSetImplClass;
-  final Class syncIterableClass;
-  final Class asyncStarImplClass;
+  final Class _privateSymbolClass;
+  final Class _linkedHashMapImplClass;
+  final Class _identityHashMapImplClass;
+  final Class _linkedHashSetClass;
+  final Class _linkedHashSetImplClass;
+  final Class _identityHashSetImplClass;
+  final Class _syncIterableClass;
+  final Class _asyncStarImplClass;
 
   /// The dart:async `StreamIterator<T>` type.
   final Class _asyncStreamIteratorClass;
@@ -214,28 +214,28 @@
   }
 
   ProgramCompiler._(
-      this.coreTypes,
+      this._coreTypes,
       LibraryIndex sdk,
       this._extensionTypes,
       this._constants,
-      this.types,
-      this.hierarchy,
+      this._types,
+      this._hierarchy,
       this._typeRep,
       this._nullableInference,
-      this.options)
+      this._options)
       : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
         _asyncStreamIteratorClass =
             sdk.getClass('dart:async', 'StreamIterator'),
-        privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
-        linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
-        identityHashMapImplClass =
+        _privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
+        _linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
+        _identityHashMapImplClass =
             sdk.getClass('dart:_js_helper', 'IdentityMap'),
-        linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'),
-        linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
-        identityHashSetImplClass =
+        _linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'),
+        _linkedHashSetImplClass = sdk.getClass('dart:collection', '_HashSet'),
+        _identityHashSetImplClass =
             sdk.getClass('dart:collection', '_IdentityHashSet'),
-        syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable'),
-        asyncStarImplClass = sdk.getClass('dart:async', '_AsyncStarImpl');
+        _syncIterableClass = sdk.getClass('dart:_js_helper', 'SyncIterable'),
+        _asyncStarImplClass = sdk.getClass('dart:async', '_AsyncStarImpl');
 
   @override
   Uri get currentLibraryUri => _currentLibrary.importUri;
@@ -244,18 +244,17 @@
   Library get currentLibrary => _currentLibrary;
 
   @override
-  Library get coreLibrary => coreTypes.coreLibrary;
+  Library get coreLibrary => _coreTypes.coreLibrary;
 
   @override
   FunctionNode get currentFunction => _currentFunction;
 
   @override
-  InterfaceType get privateSymbolType => privateSymbolClass.rawType;
+  InterfaceType get privateSymbolType => _privateSymbolClass.rawType;
 
   @override
-  InterfaceType get internalSymbolType => coreTypes.internalSymbolClass.rawType;
-
-  bool get emitMetadata => options.emitMetadata;
+  InterfaceType get internalSymbolType =>
+      _coreTypes.internalSymbolClass.rawType;
 
   js_ast.Program emitModule(Component component, List<Component> summaries,
       List<Uri> summaryUris, Map<Uri, String> moduleImportForSummary) {
@@ -289,7 +288,7 @@
     }
 
     // Add implicit dart:core dependency so it is first.
-    emitLibraryName(coreTypes.coreLibrary);
+    emitLibraryName(_coreTypes.coreLibrary);
 
     // Visit each library and emit its code.
     //
@@ -311,7 +310,7 @@
     // hoisted definitions.
     items.addAll(_typeTable.discharge());
 
-    return finishModule(items, options.moduleName);
+    return finishModule(items, _options.moduleName);
   }
 
   @override
@@ -440,14 +439,14 @@
     var savedLibrary = _currentLibrary;
     var savedUri = _currentUri;
     _currentClass = c;
-    types.thisType = c.thisType;
+    _types.thisType = c.thisType;
     _currentLibrary = c.enclosingLibrary;
     _currentUri = c.fileUri;
 
     moduleItems.add(_emitClassDeclaration(c));
 
     _currentClass = savedClass;
-    types.thisType = savedClass?.thisType;
+    _types.thisType = savedClass?.thisType;
     _currentLibrary = savedLibrary;
     _currentUri = savedUri;
   }
@@ -487,7 +486,7 @@
 
     var savedClassProperties = _classProperties;
     _classProperties =
-        ClassPropertyModel.build(types, _extensionTypes, virtualFields, c);
+        ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, c);
 
     var jsCtors = _defineConstructors(c, className);
     var jsMethods = _emitClassMethods(c);
@@ -644,7 +643,7 @@
       List<js_ast.Method> methods,
       List<js_ast.Statement> body,
       List<js_ast.Statement> deferredSupertypes) {
-    if (c == coreTypes.objectClass) {
+    if (c == _coreTypes.objectClass) {
       body.add(_emitClassStatement(c, className, null, methods));
       return;
     }
@@ -663,7 +662,7 @@
         if (t is InterfaceType) {
           var tc = t.classNode;
           if (c == tc) return true;
-          if (tc == coreTypes.objectClass || !visited.add(t)) return false;
+          if (tc == _coreTypes.objectClass || !visited.add(t)) return false;
           if (t.typeArguments.any(defer)) return true;
           var mixin = tc.mixedInType;
           return mixin != null && defer(mixin.asInterfaceType) ||
@@ -706,10 +705,10 @@
     var superclass = getSuperclassAndMixins(c, mixinClasses);
     var supertype = identical(c.superclass, superclass)
         ? c.supertype.asInterfaceType
-        : hierarchy.getClassAsInstanceOf(c, superclass).asInterfaceType;
+        : _hierarchy.getClassAsInstanceOf(c, superclass).asInterfaceType;
     mixinClasses = mixinClasses.reversed.toList();
     var mixins = mixinClasses
-        .map((m) => hierarchy.getClassAsInstanceOf(c, m).asInterfaceType)
+        .map((m) => _hierarchy.getClassAsInstanceOf(c, m).asInterfaceType)
         .toList();
 
     var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass);
@@ -872,8 +871,8 @@
       Class c, js_ast.Expression className, List<js_ast.Statement> body) {
     js_ast.Expression getInterfaceSymbol(Class interface) {
       var library = interface.enclosingLibrary;
-      if (library == coreTypes.coreLibrary ||
-          library == coreTypes.asyncLibrary) {
+      if (library == _coreTypes.coreLibrary ||
+          library == _coreTypes.asyncLibrary) {
         switch (interface.name) {
           case 'List':
           case 'Map':
@@ -899,8 +898,8 @@
     // TODO(jmesserly): share these hand coded type checks with the old back
     // end, perhaps by factoring them into a common file, or move them to be
     // static methdos in the SDK. (Or wait until we delete the old back end.)
-    if (c.enclosingLibrary == coreTypes.coreLibrary) {
-      if (c == coreTypes.objectClass) {
+    if (c.enclosingLibrary == _coreTypes.coreLibrary) {
+      if (c == _coreTypes.objectClass) {
         // Everything is an Object.
         body.add(js.statement(
             '#.is = function is_Object(o) { return true; }', [className]));
@@ -910,7 +909,7 @@
             '#._check = function check_Object(o) { return o; }', [className]));
         return null;
       }
-      if (c == coreTypes.stringClass) {
+      if (c == _coreTypes.stringClass) {
         body.add(js.statement(
             '#.is = function is_String(o) { return typeof o == "string"; }',
             className));
@@ -928,7 +927,7 @@
             [className, runtimeModule, className]));
         return null;
       }
-      if (c == coreTypes.functionClass) {
+      if (c == _coreTypes.functionClass) {
         body.add(js.statement(
             '#.is = function is_Function(o) { return typeof o == "function"; }',
             className));
@@ -946,7 +945,7 @@
             [className, runtimeModule, className]));
         return null;
       }
-      if (c == coreTypes.intClass) {
+      if (c == _coreTypes.intClass) {
         body.add(js.statement(
             '#.is = function is_int(o) {'
             '  return typeof o == "number" && Math.floor(o) == o;'
@@ -968,7 +967,7 @@
             [className, runtimeModule, className]));
         return null;
       }
-      if (c == coreTypes.nullClass) {
+      if (c == _coreTypes.nullClass) {
         body.add(js.statement(
             '#.is = function is_Null(o) { return o == null; }', className));
         body.add(js.statement(
@@ -985,7 +984,7 @@
             [className, runtimeModule, className]));
         return null;
       }
-      if (c == coreTypes.numClass || c == coreTypes.doubleClass) {
+      if (c == _coreTypes.numClass || c == _coreTypes.doubleClass) {
         body.add(js.statement(
             '#.is = function is_num(o) { return typeof o == "number"; }',
             className));
@@ -1003,7 +1002,7 @@
             [className, runtimeModule, className]));
         return null;
       }
-      if (c == coreTypes.boolClass) {
+      if (c == _coreTypes.boolClass) {
         body.add(js.statement(
             '#.is = function is_bool(o) { return o === true || o === false; }',
             className));
@@ -1022,12 +1021,12 @@
         return null;
       }
     }
-    if (c.enclosingLibrary == coreTypes.asyncLibrary) {
-      if (c == coreTypes.futureOrClass) {
+    if (c.enclosingLibrary == _coreTypes.asyncLibrary) {
+      if (c == _coreTypes.futureOrClass) {
         var typeParam = TypeParameterType(c.typeParameters[0]);
         var typeT = visitTypeParameterType(typeParam);
         var futureOfT = visitInterfaceType(
-            InterfaceType(coreTypes.futureClass, [typeParam]));
+            InterfaceType(_coreTypes.futureClass, [typeParam]));
         body.add(js.statement('''
             #.is = function is_FutureOr(o) {
               return #.is(o) || #.is(o);
@@ -1123,7 +1122,7 @@
   void _emitClassMetadata(List<Expression> metadata,
       js_ast.Expression className, List<js_ast.Statement> body) {
     // Metadata
-    if (emitMetadata && metadata.isNotEmpty) {
+    if (_options.emitMetadata && metadata.isNotEmpty) {
       body.add(js.statement('#[#.metadata] = #;', [
         className,
         runtimeModule,
@@ -1135,7 +1134,7 @@
 
   /// Ensure `dartx.` symbols we will use are present.
   void _initExtensionSymbols(Class c) {
-    if (_extensionTypes.hasNativeSubtype(c) || c == coreTypes.objectClass) {
+    if (_extensionTypes.hasNativeSubtype(c) || c == _coreTypes.objectClass) {
       for (var m in c.procedures) {
         if (!m.isAbstract && !m.isStatic && !m.name.isPrivate) {
           _declareMemberName(m, useExtension: true);
@@ -1187,7 +1186,7 @@
       if (elements.isEmpty) return;
 
       if (!name.startsWith('Static')) {
-        var proto = c == coreTypes.objectClass
+        var proto = c == _coreTypes.objectClass
             ? js.call('Object.create(null)')
             : runtimeCall('get${name}s(#.__proto__)', [className]);
         elements.insert(0, js_ast.Property(propertyName('__proto__'), proto));
@@ -1230,7 +1229,7 @@
     for (var member in classProcedures) {
       // Static getters/setters/methods cannot be called with dynamic dispatch,
       // nor can they be torn off.
-      if (!emitMetadata && member.isStatic) continue;
+      if (!_options.emitMetadata && member.isStatic) continue;
 
       var name = member.name.name;
       var reifiedType = _getMemberRuntimeType(member, c) as FunctionType;
@@ -1241,7 +1240,7 @@
       // emit a signature on this class.  Otherwise we will inherit the
       // signature from the superclass.
       var memberOverride = c.superclass != null
-          ? hierarchy.getDispatchTarget(c.superclass, member.name,
+          ? _hierarchy.getDispatchTarget(c.superclass, member.name,
               setter: member.isSetter)
           : null;
 
@@ -1289,7 +1288,7 @@
     for (var field in classFields) {
       // Only instance fields need to be saved for dynamic dispatch.
       var isStatic = field.isStatic;
-      if (!emitMetadata && isStatic) continue;
+      if (!_options.emitMetadata && isStatic) continue;
 
       var memberName = _declareMemberName(field);
       var fieldSig = _emitFieldSignature(field, c);
@@ -1299,7 +1298,7 @@
     emitSignature('Field', instanceFields);
     emitSignature('StaticField', staticFields);
 
-    if (emitMetadata) {
+    if (_options.emitMetadata) {
       var constructors = <js_ast.Property>[];
       var allConstructors = [
         ...c.constructors,
@@ -1316,9 +1315,9 @@
 
     // Add static property dart._runtimeType to Object.
     // All other Dart classes will (statically) inherit this property.
-    if (c == coreTypes.objectClass) {
+    if (c == _coreTypes.objectClass) {
       body.add(runtimeStatement('lazyFn(#, () => #.#)',
-          [className, emitLibraryName(coreTypes.coreLibrary), 'Type']));
+          [className, emitLibraryName(_coreTypes.coreLibrary), 'Type']));
     }
 
     _classEmittingSignatures = savedClass;
@@ -1328,7 +1327,9 @@
     var type = _getTypeFromClass(field.type, field.enclosingClass, fromClass);
     var args = [_emitType(type)];
     var annotations = field.annotations;
-    if (emitMetadata && annotations != null && annotations.isNotEmpty) {
+    if (_options.emitMetadata &&
+        annotations != null &&
+        annotations.isNotEmpty) {
       var savedUri = _currentUri;
       _currentUri = field.enclosingClass.fileUri;
       args.add(js_ast.ArrayInitializer(
@@ -1350,7 +1351,7 @@
       result = f.functionType;
     } else {
       reifyParameter(VariableDeclaration p) =>
-          isCovariantParameter(p) ? coreTypes.objectClass.thisType : p.type;
+          isCovariantParameter(p) ? _coreTypes.objectClass.thisType : p.type;
       reifyNamedParameter(VariableDeclaration p) =>
           NamedType(p.name, reifyParameter(p));
 
@@ -1370,7 +1371,7 @@
   DartType _getTypeFromClass(DartType type, Class superclass, Class subclass) {
     if (identical(superclass, subclass)) return type;
     return Substitution.fromSupertype(
-            hierarchy.getClassAsInstanceOf(subclass, superclass))
+            _hierarchy.getClassAsInstanceOf(subclass, superclass))
         .substituteType(type);
   }
 
@@ -1457,7 +1458,7 @@
   js_ast.Statement _emitSuperConstructorCallIfNeeded(
       Class c, js_ast.Expression className,
       [SuperInitializer superInit]) {
-    if (c == coreTypes.objectClass) return null;
+    if (c == _coreTypes.objectClass) return null;
 
     Constructor ctor;
     List<js_ast.Expression> args;
@@ -1494,7 +1495,7 @@
   }
 
   bool _hasUnnamedConstructor(Class c) {
-    if (c == null || c == coreTypes.objectClass) return false;
+    if (c == null || c == _coreTypes.objectClass) return false;
     var ctor = unnamedConstructor(c);
     if (ctor != null && !ctor.isSynthetic) return true;
     return c.fields.any((f) => !f.isStatic);
@@ -1611,7 +1612,7 @@
     bool hasJsPeer = _extensionTypes.isNativeClass(c);
     bool hasIterator = false;
 
-    if (c == coreTypes.objectClass) {
+    if (c == _coreTypes.objectClass) {
       // Dart does not use ES6 constructors.
       // Add an error to catch any invalid usage.
       jsMethods.add(
@@ -1746,7 +1747,7 @@
   }
 
   js_ast.Fun _emitNativeFunctionBody(Procedure node) {
-    String name = getAnnotationName(node, isJSAnnotation) ?? node.name.name;
+    String name = _annotationName(node, isJSAnnotation) ?? node.name.name;
     if (node.isGetter) {
       return js_ast.Fun([], js.block('{ return this.#; }', [name]));
     } else if (node.isSetter) {
@@ -1787,7 +1788,7 @@
         return const [];
       }
       var setterType = substituteType(superMember.setterType);
-      if (types.isTop(setterType)) return const [];
+      if (_types.isTop(setterType)) return const [];
       return [
         js_ast.Method(
             name,
@@ -1922,7 +1923,7 @@
     var jsMethods = <js_ast.Method>[];
     assert(!field.isStatic);
 
-    var name = getAnnotationName(field, isJSName) ?? field.name.name;
+    var name = _annotationName(field, isJSName) ?? field.name.name;
     // Generate getter
     var fn = js_ast.Fun([], js.block('{ return this.#; }', [name]));
     var method = js_ast.Method(_declareMemberName(field), fn, isGetter: true);
@@ -1979,21 +1980,21 @@
   /// otherwise it returns the adapter code.
   // TODO(jmesserly): should we adapt `Iterator` too?
   js_ast.Method _emitIterable(Class c) {
-    var iterable = hierarchy.getClassAsInstanceOf(c, coreTypes.iterableClass);
+    var iterable = _hierarchy.getClassAsInstanceOf(c, _coreTypes.iterableClass);
     if (iterable == null) return null;
 
     // If a parent had an `iterator` (concrete or abstract) or implements
     // Iterable, we know the adapter is already there, so we can skip it as a
     // simple code size optimization.
-    var parent = hierarchy.getDispatchTarget(c.superclass, Name('iterator'));
+    var parent = _hierarchy.getDispatchTarget(c.superclass, Name('iterator'));
     if (parent != null) return null;
 
     var parentIterable =
-        hierarchy.getClassAsInstanceOf(c.superclass, coreTypes.iterableClass);
+        _hierarchy.getClassAsInstanceOf(c.superclass, _coreTypes.iterableClass);
     if (parentIterable != null) return null;
 
     if (c.enclosingLibrary.importUri.scheme == 'dart' &&
-        c.procedures.any((m) => getJSExportName(m) == 'Symbol.iterator')) {
+        c.procedures.any((m) => _jsExportName(m) == 'Symbol.iterator')) {
       return null;
     }
 
@@ -2003,7 +2004,7 @@
         js.call('Symbol.iterator'),
         js.call('function() { return new #.JsIterator(this.#); }', [
           runtimeModule,
-          _emitMemberName('iterator', memberClass: coreTypes.iterableClass)
+          _emitMemberName('iterator', memberClass: _coreTypes.iterableClass)
         ]) as js_ast.Fun);
   }
 
@@ -2184,7 +2185,7 @@
     // SDK code. These renames need to be included at every declaration,
     // including overrides in subclasses.
     if (member != null) {
-      var runtimeName = getJSExportName(member);
+      var runtimeName = _jsExportName(member);
       if (runtimeName != null) {
         var parts = runtimeName.split('.');
         if (parts.length < 2) return propertyName(runtimeName);
@@ -2224,7 +2225,7 @@
   /// one without renaming.
   bool _isSymbolizedMember(Class c, String name) {
     if (c == null) {
-      return isObjectMember(name);
+      return _isObjectMember(name);
     }
     c = _typeRep.getImplementationClass(c.rawType) ?? c;
     if (_extensionTypes.isNativeClass(c)) {
@@ -2233,7 +2234,7 @@
       // Fields on a native class are implicitly native.
       // Methods/getters/setters are marked external/native.
       if (member is Field || member is Procedure && member.isExternal) {
-        var jsName = getAnnotationName(member, isJSName);
+        var jsName = _annotationName(member, isJSName);
         return jsName != null && jsName != name;
       } else {
         // Non-external members must be symbolized.
@@ -2258,8 +2259,8 @@
     return map.putIfAbsent(
         name,
         () =>
-            hierarchy.getDispatchTarget(c, Name(name)) ??
-            hierarchy.getDispatchTarget(c, Name(name), setter: true));
+            _hierarchy.getDispatchTarget(c, Name(name)) ??
+            _hierarchy.getDispatchTarget(c, Name(name), setter: true));
   }
 
   js_ast.Expression _emitStaticMemberName(String name, [NamedNode member]) {
@@ -2296,7 +2297,7 @@
 
   js_ast.Expression _emitJSInteropStaticMemberName(NamedNode n) {
     if (!usesJSInterop(n)) return null;
-    var name = getAnnotationName(n, isPublicJSAnnotation);
+    var name = _annotationName(n, isPublicJSAnnotation);
     if (name != null) {
       if (name.contains('.')) {
         throw UnsupportedError(
@@ -2320,15 +2321,14 @@
   /// NOTE: usually you should use [_emitTopLevelName] instead of this. This
   /// function does not handle JS interop.
   js_ast.Expression _emitTopLevelMemberName(NamedNode n, {String suffix = ''}) {
-    var name = getJSExportName(n) ?? getTopLevelName(n);
+    var name = _jsExportName(n) ?? getTopLevelName(n);
     return propertyName(name + suffix);
   }
 
   String _getJSNameWithoutGlobal(NamedNode n) {
     if (!usesJSInterop(n)) return null;
-    var libraryJSName = getAnnotationName(getLibrary(n), isPublicJSAnnotation);
-    var jsName =
-        getAnnotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
+    var libraryJSName = _annotationName(getLibrary(n), isPublicJSAnnotation);
+    var jsName = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
     return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
   }
 
@@ -2402,7 +2402,7 @@
     // dart:mirrors is enabled.
     // TODO(jmesserly): do we even need this for mirrors, since statics are not
     // commonly reflected on?
-    if (emitMetadata && _reifyFunctionType(p.function)) {
+    if (_options.emitMetadata && _reifyFunctionType(p.function)) {
       body.add(
           _emitFunctionTagged(nameExpr, p.function.functionType, topLevel: true)
               .toStatement());
@@ -2593,7 +2593,7 @@
       /// Kernel represents `<T>` as `<T extends Object = dynamic>`. We can find
       /// explicit bounds by looking for anything *except* that.
       typeParameterHasExplicitBound(TypeParameter t) =>
-          t.bound != types.objectType || t.defaultType != const DynamicType();
+          t.bound != _types.objectType || t.defaultType != const DynamicType();
 
       // If any explicit bounds were passed, emit them.
       if (typeFormals.any(typeParameterHasExplicitBound)) {
@@ -2629,7 +2629,7 @@
     var result = visitFunctionType(type, member: member);
 
     var annotations = member.annotations;
-    if (emitMetadata && annotations.isNotEmpty) {
+    if (_options.emitMetadata && annotations.isNotEmpty) {
       // TODO(jmesserly): should we disable source info for annotations?
       var savedUri = _currentUri;
       _currentUri = member.enclosingClass.fileUri;
@@ -2661,7 +2661,7 @@
   // responsible for unpacking this.
   js_ast.Expression _emitAnnotatedResult(
       js_ast.Expression result, List<Expression> metadata, Member member) {
-    if (emitMetadata && metadata.isNotEmpty) {
+    if (_options.emitMetadata && metadata.isNotEmpty) {
       // TODO(jmesserly): should we disable source info for annotations?
       var savedUri = _currentUri;
       _currentUri = member.enclosingClass.fileUri;
@@ -2824,9 +2824,9 @@
       }
 
       var returnType =
-          _getExpectedReturnType(function, coreTypes.iterableClass);
+          _getExpectedReturnType(function, _coreTypes.iterableClass);
       var syncIterable =
-          _emitType(InterfaceType(syncIterableClass, [returnType]));
+          _emitType(InterfaceType(_syncIterableClass, [returnType]));
       return js.call('new #.new(#)', [syncIterable, gen]);
     }
 
@@ -2840,8 +2840,8 @@
       // _AsyncStarImpl has an example of the generated code.
       var gen = emitGeneratorFn((_) => [_asyncStarController]);
 
-      var returnType = _getExpectedReturnType(function, coreTypes.streamClass);
-      var asyncStarImpl = InterfaceType(asyncStarImplClass, [returnType]);
+      var returnType = _getExpectedReturnType(function, _coreTypes.streamClass);
+      var asyncStarImpl = InterfaceType(_asyncStarImplClass, [returnType]);
       return js.call('new #.new(#).stream', [_emitType(asyncStarImpl), gen]);
     }
 
@@ -2859,16 +2859,16 @@
     var gen = emitGeneratorFn((_) => []);
     // Return type of an async body is `Future<flatten(T)>`, where T is the
     // declared return type.
-    var returnType = types.unfutureType(function.functionType.returnType);
+    var returnType = _types.unfutureType(function.functionType.returnType);
     return js.call('#.async(#, #)',
-        [emitLibraryName(coreTypes.asyncLibrary), _emitType(returnType), gen]);
+        [emitLibraryName(_coreTypes.asyncLibrary), _emitType(returnType), gen]);
   }
 
   /// Gets the expected return type of a `sync*` or `async*` body.
   DartType _getExpectedReturnType(FunctionNode f, Class expected) {
     var type = f.functionType.returnType;
     if (type is InterfaceType) {
-      var match = hierarchy.getTypeAsInstanceOf(type, expected);
+      var match = _hierarchy.getTypeAsInstanceOf(type, expected);
       if (match != null) return match.typeArguments[0];
     }
     return const DynamicType();
@@ -3021,7 +3021,7 @@
   void _emitCovarianceBoundsCheck(
       List<TypeParameter> typeFormals, List<js_ast.Statement> body) {
     for (var t in typeFormals) {
-      if (t.isGenericCovariantImpl && !types.isTop(t.bound)) {
+      if (t.isGenericCovariantImpl && !_types.isTop(t.bound)) {
         body.add(runtimeStatement('checkTypeBound(#, #, #)', [
           _emitType(TypeParameterType(t)),
           _emitType(t.bound),
@@ -3090,7 +3090,7 @@
     }
 
     if (node is AsExpression && node.isTypeError) {
-      assert(node.getStaticType(types) == types.boolType);
+      assert(node.getStaticType(_types) == _types.boolType);
       return runtimeCall('dtest(#)', [_visitExpression(node.operand)]);
     }
 
@@ -3211,12 +3211,12 @@
 
   @override
   js_ast.Statement visitAssertStatement(AssertStatement node) {
-    if (!options.enableAsserts) return js_ast.EmptyStatement();
+    if (!_options.enableAsserts) return js_ast.EmptyStatement();
     var condition = node.condition;
-    var conditionType = condition.getStaticType(types);
+    var conditionType = condition.getStaticType(_types);
     var jsCondition = _visitExpression(condition);
 
-    var boolType = coreTypes.boolClass.rawType;
+    var boolType = _coreTypes.boolClass.rawType;
     if (conditionType is FunctionType &&
         conditionType.requiredParameterCount == 0 &&
         conditionType.returnType == boolType) {
@@ -3337,7 +3337,7 @@
   // (targeting the loop).  Find the outermost non-labeled statement starting
   // from body and record all the intermediate labeled statements as continue
   // targets.
-  Statement effectiveBodyOf(Statement loop, Statement body) {
+  Statement _effectiveBodyOf(Statement loop, Statement body) {
     // In a loop whose body is not labeled, this list should be empty because
     // it is not possible to continue to an outer loop without a label.
     _currentContinueTargets = <LabeledStatement>[];
@@ -3350,7 +3350,7 @@
     return body;
   }
 
-  T translateLoop<T extends js_ast.Statement>(Statement node, T action()) {
+  T _translateLoop<T extends js_ast.Statement>(Statement node, T action()) {
     List<LabeledStatement> savedBreakTargets;
     if (_currentBreakTargets.isNotEmpty &&
         _effectiveTargets[_currentBreakTargets.first] != node) {
@@ -3371,17 +3371,17 @@
 
   @override
   js_ast.While visitWhileStatement(WhileStatement node) {
-    return translateLoop(node, () {
+    return _translateLoop(node, () {
       var condition = _visitTest(node.condition);
-      var body = _visitScope(effectiveBodyOf(node, node.body));
+      var body = _visitScope(_effectiveBodyOf(node, node.body));
       return js_ast.While(condition, body);
     });
   }
 
   @override
   js_ast.Do visitDoStatement(DoStatement node) {
-    return translateLoop(node, () {
-      var body = _visitScope(effectiveBodyOf(node, node.body));
+    return _translateLoop(node, () {
+      var body = _visitScope(_effectiveBodyOf(node, node.body));
       var condition = _visitTest(node.condition);
       return js_ast.Do(body, condition);
     });
@@ -3389,7 +3389,7 @@
 
   @override
   js_ast.For visitForStatement(ForStatement node) {
-    return translateLoop(node, () {
+    return _translateLoop(node, () {
       emitForInitializer(VariableDeclaration v) =>
           js_ast.VariableInitialization(_emitVariableDef(v),
               _visitInitializer(v.initializer, v.annotations));
@@ -3405,7 +3405,7 @@
             .toVoidExpression();
       }
       var condition = _visitTest(node.condition);
-      var body = _visitScope(effectiveBodyOf(node, node.body));
+      var body = _visitScope(_effectiveBodyOf(node, node.body));
 
       return js_ast.For(initList, condition, update, body);
     });
@@ -3413,13 +3413,13 @@
 
   @override
   js_ast.Statement visitForInStatement(ForInStatement node) {
-    return translateLoop(node, () {
+    return _translateLoop(node, () {
       if (node.isAsync) {
         return _emitAwaitFor(node);
       }
 
       var iterable = _visitExpression(node.iterable);
-      var body = _visitScope(effectiveBodyOf(node, node.body));
+      var body = _visitScope(_effectiveBodyOf(node, node.body));
 
       var init = js.call('let #', _emitVariableDef(node.variable));
       if (_annotatedNullCheck(node.variable.annotations)) {
@@ -3500,7 +3500,7 @@
       var labelState = js_ast.TemporaryId("labelState");
       // TODO(markzipan): Retrieve the real label name with source offsets
       var labelName = 'SL${_switchLabelStates.length}';
-      _switchLabelStates[node] = SwitchLabelState(labelName, labelState);
+      _switchLabelStates[node] = _SwitchLabelState(labelName, labelState);
 
       for (var c in node.cases) {
         var subcases =
@@ -3689,7 +3689,7 @@
     var then = js_ast.Block(body);
 
     // Discard following clauses, if any, as they are unreachable.
-    if (types.isTop(node.guard)) return then;
+    if (_types.isTop(node.guard)) return then;
 
     var condition =
         _emitIsExpression(VariableGet(exceptionParameter), node.guard);
@@ -3856,7 +3856,7 @@
     // encoded as a different node, or possibly eliminated?
     // (Regardless, we'll still need to handle the callable JS interop classes.)
     if (memberName == 'call' &&
-        _isDirectCallable(receiver.getStaticType(types))) {
+        _isDirectCallable(receiver.getStaticType(_types))) {
       // Tearoff of `call` on a function type is a no-op;
       return _visitExpression(receiver);
     }
@@ -3866,7 +3866,7 @@
     // TODO(jmesserly): we need to mark an end span for property accessors so
     // they can be hovered. Unfortunately this is not possible as Kernel does
     // not store this data.
-    if (isObjectMember(memberName)) {
+    if (_isObjectMember(memberName)) {
       if (isNullable(receiver)) {
         // If the receiver is nullable, use a helper so calls like
         // `null.hashCode` and `null.runtimeType` will work.
@@ -3891,7 +3891,7 @@
   // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
   // _emitMemberName would be a nice place to handle it, but we don't have
   // access to the target expression there (needed for `dart.replNameLookup`).
-  String get _replSuffix => options.replCompile ? 'Repl' : '';
+  String get _replSuffix => _options.replCompile ? 'Repl' : '';
 
   js_ast.Expression _emitPropertySet(
       Expression receiver, Member member, Expression value,
@@ -3981,7 +3981,7 @@
         target.hasGetter &&
         _isDynamicOrFunction(target.getterType);
     if (name == 'call') {
-      var receiverType = receiver.getStaticType(types);
+      var receiverType = receiver.getStaticType(_types);
       if (isCallingDynamicField || _isDynamicOrFunction(receiverType)) {
         return _emitDynamicInvoke(jsReceiver, null, args, arguments);
       } else if (_isDirectCallable(receiverType)) {
@@ -4060,7 +4060,7 @@
 
   js_ast.Expression _getImplicitCallTarget(InterfaceType from) {
     var c = from.classNode;
-    var member = hierarchy.getInterfaceMember(c, Name("call"));
+    var member = _hierarchy.getInterfaceMember(c, Name("call"));
     if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
       return _emitMemberName('call', member: member);
     }
@@ -4068,7 +4068,7 @@
   }
 
   bool _isDynamicOrFunction(DartType t) =>
-      t == coreTypes.functionClass.rawType || t == const DynamicType();
+      t == _coreTypes.functionClass.rawType || t == const DynamicType();
 
   js_ast.Expression _emitUnaryOperator(
       Expression expr, Member target, InvocationExpression node) {
@@ -4245,10 +4245,10 @@
     if (target != null) {
       var targetClass = target.enclosingClass;
       var leftType = targetClass.rawType;
-      var rightType = right.getStaticType(types);
+      var rightType = right.getStaticType(_types);
 
       if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
-          leftType == types.stringType && op == '+') {
+          leftType == _types.stringType && op == '+') {
         // Inline operations on primitive types where possible.
         // TODO(jmesserly): inline these from dart:core instead of hardcoding
         // the implementation details here.
@@ -4343,7 +4343,7 @@
       Expression left, Member target, Expression right,
       {bool negated = false}) {
     var targetClass = target?.enclosingClass;
-    var leftType = targetClass?.rawType ?? left.getStaticType(types);
+    var leftType = targetClass?.rawType ?? left.getStaticType(_types);
 
     // Conceptually `x == y` in Dart is defined as:
     //
@@ -4433,7 +4433,7 @@
   /// [jsTarget].[jsName], replacing `super` if it is not allowed in scope.
   js_ast.PropertyAccess _emitSuperTarget(Member member, {bool setter = false}) {
     var jsName = _emitMemberName(member.name.name, member: member);
-    if (member is Field && !virtualFields.isVirtual(member)) {
+    if (member is Field && !_virtualFields.isVirtual(member)) {
       return js_ast.PropertyAccess(js_ast.This(), jsName);
     }
     if (_superAllowed) return js_ast.PropertyAccess(js_ast.Super(), jsName);
@@ -4497,7 +4497,7 @@
         return getExtensionSymbolInternal(firstArg.value);
       }
     }
-    if (target == coreTypes.identicalProcedure) {
+    if (target == _coreTypes.identicalProcedure) {
       return _emitCoreIdenticalCall(node.arguments.positional);
     }
     if (_isDebuggerCall(target)) {
@@ -4561,7 +4561,7 @@
       if (target is Procedure && target.isStatic && target.isExternal) {
         var nativeName = _extensionTypes.getNativePeers(c);
         if (nativeName.isNotEmpty) {
-          var memberName = getAnnotationName(target, isJSName) ??
+          var memberName = _annotationName(target, isJSName) ??
               _emitStaticMemberName(target.name.name, target);
           return runtimeCall('global.#.#', [nativeName[0], memberName]);
         }
@@ -4643,7 +4643,7 @@
 
   bool _isNull(Expression expr) =>
       expr is NullLiteral ||
-      expr.getStaticType(types) == coreTypes.nullClass.rawType;
+      expr.getStaticType(_types) == _coreTypes.nullClass.rawType;
 
   bool _doubleEqIsIdentity(Expression left, Expression right) {
     // If we statically know LHS or RHS is null we can use ==.
@@ -4651,7 +4651,7 @@
     // If the representation of the  two types will not induce conversion in
     // JS then we can use == .
     return !_typeRep.equalityMayConvert(
-        left.getStaticType(types), right.getStaticType(types));
+        left.getStaticType(_types), right.getStaticType(_types));
   }
 
   bool _tripleEqIsIdentity(Expression left, Expression right) {
@@ -4697,7 +4697,7 @@
     }
     var code = negated ? '!#' : '#';
     return js.call(code,
-        js_ast.Call(_emitTopLevelName(coreTypes.identicalProcedure), jsArgs));
+        js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs));
   }
 
   @override
@@ -4722,7 +4722,7 @@
         ? ctorClass.rawType
         : InterfaceType(ctorClass, args.types);
 
-    if (isFromEnvironmentInvocation(coreTypes, node)) {
+    if (isFromEnvironmentInvocation(_coreTypes, node)) {
       var value = _constants.evaluate(node);
       if (value is PrimitiveConstant) {
         return value.accept(this) as js_ast.Expression;
@@ -4779,7 +4779,7 @@
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= _typeRep.isPrimitive(typeArgs[0]);
-    var c = identity ? identityHashMapImplClass : linkedHashMapImplClass;
+    var c = identity ? _identityHashMapImplClass : _linkedHashMapImplClass;
     return _emitType(InterfaceType(c, typeArgs));
   }
 
@@ -4787,7 +4787,7 @@
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= _typeRep.isPrimitive(typeArgs[0]);
-    var c = identity ? identityHashSetImplClass : linkedHashSetImplClass;
+    var c = identity ? _identityHashSetImplClass : _linkedHashSetImplClass;
     return _emitType(InterfaceType(c, typeArgs));
   }
 
@@ -4810,7 +4810,7 @@
           operand.receiver, operand.target, operand.arguments.positional[0],
           negated: true);
     } else if (operand is StaticInvocation &&
-        operand.target == coreTypes.identicalProcedure) {
+        operand.target == _coreTypes.identicalProcedure) {
       return _emitCoreIdenticalCall(operand.arguments.positional,
           negated: true);
     }
@@ -4845,7 +4845,7 @@
       if (jsExpr is js_ast.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
         continue;
       }
-      parts.add(e.getStaticType(types) == types.stringType && !isNullable(e)
+      parts.add(e.getStaticType(_types) == _types.stringType && !isNullable(e)
           ? jsExpr
           : runtimeCall('str(#)', [jsExpr]));
     }
@@ -4864,7 +4864,7 @@
         node.accept(this);
         if (node is ConstantExpression) {
           var list = node.constant as ListConstant;
-          entries.addAll(list.entries.map(visitConstant));
+          entries.addAll(list.entries.map(_visitConstant));
         } else if (node is ListLiteral) {
           entries.addAll(node.expressions.map(_visitExpression));
         }
@@ -4886,7 +4886,7 @@
         node.accept(this);
         if (node is ConstantExpression) {
           var set = node.constant as SetConstant;
-          entries.addAll(set.entries.map(visitConstant));
+          entries.addAll(set.entries.map(_visitConstant));
         } else if (node is SetLiteral) {
           entries.addAll(node.expressions.map(_visitExpression));
         }
@@ -4909,8 +4909,8 @@
         if (node is ConstantExpression) {
           var map = node.constant as MapConstant;
           for (var entry in map.entries) {
-            entries.add(visitConstant(entry.key));
-            entries.add(visitConstant(entry.value));
+            entries.add(_visitConstant(entry.key));
+            entries.add(_visitConstant(entry.value));
           }
         } else if (node is MapLiteral) {
           for (var entry in node.entries) {
@@ -4928,7 +4928,7 @@
   @override
   js_ast.Expression visitInstanceCreation(InstanceCreation node) {
     // Only occurs inside unevaluated constants.
-    throw new UnsupportedError("Instance creation");
+    throw UnsupportedError("Instance creation");
   }
 
   @override
@@ -4941,7 +4941,7 @@
     var lhs = _visitExpression(operand);
     var typeofName = _typeRep.typeFor(type).primitiveTypeOf;
     // Inline primitives other than int (which requires a Math.floor check).
-    if (typeofName != null && type != types.intType) {
+    if (typeofName != null && type != _types.intType) {
       return js.call('typeof # == #', [lhs, js.string(typeofName, "'")]);
     } else {
       return js.call('#.is(#)', [_emitType(type), lhs]);
@@ -4953,7 +4953,7 @@
     Expression fromExpr = node.operand;
     var to = node.type;
     var jsFrom = _visitExpression(fromExpr);
-    var from = fromExpr.getStaticType(types);
+    var from = fromExpr.getStaticType(_types);
 
     // If the check was put here by static analysis to ensure soundness, we
     // can't skip it. For example, one could implement covariant generic caller
@@ -4973,13 +4973,13 @@
     //      }
     //
     var isTypeError = node.isTypeError;
-    if (!isTypeError && types.isSubtypeOf(from, to)) return jsFrom;
+    if (!isTypeError && _types.isSubtypeOf(from, to)) return jsFrom;
 
     // All Dart number types map to a JS double.
     if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
       // Make sure to check when converting to int.
-      if (from != coreTypes.intClass.rawType &&
-          to == coreTypes.intClass.rawType) {
+      if (from != _coreTypes.intClass.rawType &&
+          to == _coreTypes.intClass.rawType) {
         // TODO(jmesserly): fuse this with notNull check.
         // TODO(jmesserly): this does not correctly distinguish user casts from
         // required-for-soundness casts.
@@ -4995,7 +4995,7 @@
 
   js_ast.Expression _emitCast(js_ast.Expression expr, DartType type,
       {bool implicit = true}) {
-    if (types.isTop(type)) return expr;
+    if (_types.isTop(type)) return expr;
 
     var code = implicit ? '#._check(#)' : '#.as(#)';
     return js.call(code, [_emitType(type), expr]);
@@ -5066,7 +5066,7 @@
     // TODO(markzipan): remove const check when we use front-end const eval
     if (!node.isConst) {
       var setType = visitInterfaceType(
-          InterfaceType(linkedHashSetClass, [node.typeArgument]));
+          InterfaceType(_linkedHashSetClass, [node.typeArgument]));
       if (node.expressions.isEmpty) {
         return js.call('#.new()', [setType]);
       }
@@ -5095,7 +5095,7 @@
     // TODO(markzipan): remove const check when we use front-end const eval
     if (!node.isConst) {
       var mapType =
-          _emitMapImplType(node.getStaticType(types) as InterfaceType);
+          _emitMapImplType(node.getStaticType(_types) as InterfaceType);
       if (node.entries.isEmpty) {
         return js.call('new #.new()', [mapType]);
       }
@@ -5118,7 +5118,7 @@
   js_ast.Expression visitFunctionExpression(FunctionExpression node) {
     var fn = _emitArrowFunction(node);
     if (!_reifyFunctionType(node.function)) return fn;
-    return _emitFunctionTagged(fn, node.getStaticType(types) as FunctionType);
+    return _emitFunctionTagged(fn, node.getStaticType(_types) as FunctionType);
   }
 
   js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) {
@@ -5197,8 +5197,8 @@
     jsBlock.accept(finder);
     if (finder.hasYield) {
       var genFn = js_ast.Fun([], jsBlock, isGenerator: true);
-      var asyncLibrary = emitLibraryName(coreTypes.asyncLibrary);
-      var returnType = _emitType(node.getStaticType(types));
+      var asyncLibrary = emitLibraryName(_coreTypes.asyncLibrary);
+      var returnType = _emitType(node.getStaticType(_types));
       var asyncCall =
           js.call('#.async(#, #)', [asyncLibrary, returnType, genFn]);
       return js_ast.Yield(asyncCall);
@@ -5254,23 +5254,23 @@
   /// Returns the name value of the `JSExportName` annotation (when compiling
   /// the SDK), or `null` if there's none. This is used to control the name
   /// under which functions are compiled and exported.
-  String getJSExportName(NamedNode n) {
+  String _jsExportName(NamedNode n) {
     var library = getLibrary(n);
     if (library == null || library.importUri.scheme != 'dart') return null;
 
-    return getAnnotationName(n, isJSExportNameAnnotation);
+    return _annotationName(n, isJSExportNameAnnotation);
   }
 
   /// If [node] has annotation matching [test] and the first argument is a
   /// string, this returns the string value.
   ///
   /// Calls [findAnnotation] followed by [getNameFromAnnotation].
-  String getAnnotationName(NamedNode node, bool test(Expression value)) {
+  String _annotationName(NamedNode node, bool test(Expression value)) {
     return _constants.getFieldValueFromAnnotation(
         findAnnotation(node, test), 'name') as String;
   }
 
-  js_ast.Expression visitConstant(Constant node) =>
+  js_ast.Expression _visitConstant(Constant node) =>
       node.accept(this) as js_ast.Expression;
   @override
   js_ast.Expression visitNullConstant(NullConstant node) =>
@@ -5315,8 +5315,8 @@
   js_ast.Expression visitMapConstant(MapConstant node) {
     var entries = [
       for (var e in node.entries) ...[
-        visitConstant(e.key),
-        visitConstant(e.value),
+        _visitConstant(e.key),
+        _visitConstant(e.value),
       ],
     ];
     return _emitConstMap(node.keyType, node.valueType, entries);
@@ -5324,11 +5324,11 @@
 
   @override
   js_ast.Expression visitListConstant(ListConstant node) => _emitConstList(
-      node.typeArgument, node.entries.map(visitConstant).toList());
+      node.typeArgument, node.entries.map(_visitConstant).toList());
 
   @override
   js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet(
-      node.typeArgument, node.entries.map(visitConstant).toList());
+      node.typeArgument, node.entries.map(_visitConstant).toList());
 
   @override
   js_ast.Expression visitInstanceConstant(InstanceConstant node) {
@@ -5339,7 +5339,7 @@
           _emitMemberName(member.name.name, member: member), constant);
     }
 
-    var type = visitInterfaceType(node.getType(types) as InterfaceType);
+    var type = visitInterfaceType(node.getType(_types) as InterfaceType);
     var prototype = js.call("#.prototype", [type]);
     var properties = [
       js_ast.Property(propertyName("__proto__"), prototype),
@@ -5361,7 +5361,7 @@
   js_ast.Expression visitPartialInstantiationConstant(
           PartialInstantiationConstant node) =>
       runtimeCall('gbind(#, #)', [
-        visitConstant(node.tearOffConstant),
+        _visitConstant(node.tearOffConstant),
         node.types.map(_emitType).toList()
       ]);
 
@@ -5389,7 +5389,7 @@
 ///
 /// Operator == is excluded, as it is handled as part of the equality binary
 /// operator.
-bool isObjectMember(String name) {
+bool _isObjectMember(String name) {
   // We could look these up on Object, but we have hard coded runtime helpers
   // so it's not really providing any benefit.
   switch (name) {
@@ -5417,9 +5417,9 @@
   return false;
 }
 
-class SwitchLabelState {
+class _SwitchLabelState {
   String label;
   js_ast.Identifier variable;
 
-  SwitchLabelState(this.label, this.variable);
+  _SwitchLabelState(this.label, this.variable);
 }
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 7ca09fb..4dc3d73 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -15,6 +15,7 @@
 dev_dependencies:
   sourcemap_testing:
     path: ../sourcemap_testing
+  pedantic: ^1.8.0
   test: any
   testing:
     path: ../testing
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 62fb349..2442d93 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -23,16 +23,16 @@
       sdkRoot.resolve('tests/modular/'),
       'tests/modular',
       _options,
-      new IOPipeline([
+      IOPipeline([
         SourceToSummaryDillStep(),
         DDKStep(),
         RunD8(),
       ], cacheSharedModules: true));
 }
 
-const dillId = const DataId("dill");
-const jsId = const DataId("js");
-const txtId = const DataId("txt");
+const dillId = DataId("dill");
+const jsId = DataId("js");
+const txtId = DataId("txt");
 
 class SourceToSummaryDillStep implements IOModularStep {
   @override
@@ -270,7 +270,7 @@
   } else if (Platform.isMacOS) {
     return 'third_party/d8/macos/d8';
   }
-  throw new UnsupportedError('Unsupported platform.');
+  throw UnsupportedError('Unsupported platform.');
 }
 
 Future<void> _createPackagesFile(
@@ -287,7 +287,7 @@
   // TODO(sigmund): follow up with the CFE to see if we can remove the need
   // for the .packages entry altogether if they won't need to read the
   // sources.
-  var packagesContents = new StringBuffer();
+  var packagesContents = StringBuffer();
   if (module.isPackage) {
     packagesContents.write('${module.name}:${module.packageBase}\n');
   }
diff --git a/pkg/dev_compiler/test/sourcemap/common.dart b/pkg/dev_compiler/test/sourcemap/common.dart
index 86f1e30..f3e041e 100644
--- a/pkg/dev_compiler/test/sourcemap/common.dart
+++ b/pkg/dev_compiler/test/sourcemap/common.dart
@@ -7,7 +7,7 @@
 import 'dart:io';
 
 import 'package:path/path.dart' as path;
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 import 'package:sourcemap_testing/src/stepping_helper.dart';
 import 'package:testing/testing.dart';
 
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
index 33f0a99..653b25e 100644
--- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart
+++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -8,8 +8,8 @@
 import 'dart:mirrors' show currentMirrorSystem;
 
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 import 'package:path/path.dart' as path;
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
 import 'package:sourcemap_testing/src/stacktrace_helper.dart';
 import 'package:sourcemap_testing/src/stepping_helper.dart';
 import 'package:testing/testing.dart';
diff --git a/pkg/dev_compiler/tool/patch_sdk.dart b/pkg/dev_compiler/tool/patch_sdk.dart
index c890b2e..f6b6a8c 100755
--- a/pkg/dev_compiler/tool/patch_sdk.dart
+++ b/pkg/dev_compiler/tool/patch_sdk.dart
@@ -9,9 +9,7 @@
 import 'dart:io';
 import 'dart:math' as math;
 
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart'
-    show parseCompilationUnit, parseDirectives;
+import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -90,7 +88,7 @@
       int inputModifyTime = math.max(selfModifyTime,
           libraryFile.lastModifiedSync().millisecondsSinceEpoch);
       var partFiles = <File>[];
-      for (var part in parseDirectives(libraryContents).directives) {
+      for (var part in parseString(content: libraryContents).unit.directives) {
         if (part is PartDirective) {
           var partPath = part.uri.stringValue;
           outPaths.add(path.join(path.dirname(libraryOut), partPath));
@@ -188,7 +186,7 @@
   bool failed = false;
   for (var partContent in partsContents) {
     var partEdits = StringEditBuffer(partContent);
-    var partUnit = parseCompilationUnit(partContent);
+    var partUnit = parseString(content: partContent).unit;
     var patcher = PatchApplier(partEdits, patchFinder);
     partUnit.accept(patcher);
     if (!failed) failed = patcher.patchWasMissing;
@@ -229,12 +227,12 @@
     int importPos = unit.directives
         .lastWhere((d) => d is ImportDirective, orElse: () => libDir)
         .end;
-    for (var d in patch.unit.directives.where((d) => d is ImportDirective)) {
+    for (var d in patch.unit.directives.whereType<ImportDirective>()) {
       _merge(d, importPos);
     }
 
     int partPos = unit.directives.last.end;
-    for (var d in patch.unit.directives.where((d) => d is PartDirective)) {
+    for (var d in patch.unit.directives.whereType<PartDirective>()) {
       _merge(d, partPos);
     }
 
@@ -315,7 +313,7 @@
 
   PatchFinder.parseAndVisit(String contents)
       : contents = contents,
-        unit = parseCompilationUnit(contents) {
+        unit = parseString(content: contents).unit {
     visitCompilationUnit(unit);
   }
 
@@ -482,6 +480,6 @@
   // It doesn't understand optional new/const in Dart 2. For now, we keep
   // redundant `const` in tool/input_sdk/libraries.dart as a workaround.
   var libraryBuilder = SdkLibrariesReader_LibraryBuilder(true);
-  parseCompilationUnit(contents).accept(libraryBuilder);
+  parseString(content: contents).unit.accept(libraryBuilder);
   return libraryBuilder.librariesMap.sdkLibraries;
 }
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 1d75bc5..14a2a0c 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -233,6 +233,8 @@
       ExperimentalFlag flag = parseExperimentalFlag(experiment);
       if (flag == null) {
         onError("Unknown experiment: " + experiment);
+      } else if (flag == ExperimentalFlag.expiredFlag) {
+        print("Experiment flag no longer required: " + experiment);
       } else if (flags.containsKey(flag)) {
         if (flags[flag] != value) {
           onError(
@@ -244,6 +246,7 @@
     }
   }
   for (ExperimentalFlag flag in ExperimentalFlag.values) {
+    if (flag == ExperimentalFlag.expiredFlag) continue;
     assert(defaultExperimentalFlags.containsKey(flag),
         "No default value for $flag.");
     flags[flag] ??= defaultExperimentalFlags[flag];
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 6428f9b..5c2f97e 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -12,9 +12,13 @@
   controlFlowCollections,
   extensionMethods,
   nonNullable,
-  setLiterals,
   spreadCollections,
   tripleShift,
+
+  // A placeholder representing an "expired" flag which has been removed
+  // from the codebase but still needs to be gracefully ignored
+  // when specified on the command line.
+  expiredFlag,
 }
 
 ExperimentalFlag parseExperimentalFlag(String flag) {
@@ -27,12 +31,14 @@
       return ExperimentalFlag.extensionMethods;
     case "non-nullable":
       return ExperimentalFlag.nonNullable;
-    case "set-literals":
-      return ExperimentalFlag.setLiterals;
     case "spread-collections":
       return ExperimentalFlag.spreadCollections;
     case "triple-shift":
       return ExperimentalFlag.tripleShift;
+
+    // Expired flags
+    case "set-literals":
+      return ExperimentalFlag.expiredFlag;
   }
   return null;
 }
@@ -42,7 +48,6 @@
   ExperimentalFlag.controlFlowCollections: true,
   ExperimentalFlag.extensionMethods: false,
   ExperimentalFlag.nonNullable: false,
-  ExperimentalFlag.setLiterals: true,
   ExperimentalFlag.spreadCollections: true,
   ExperimentalFlag.tripleShift: false,
 };
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index c9969c5..2cd528c 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -105,7 +105,8 @@
       ..target = target
       ..fileSystem = fileSystem
       ..omitPlatform = true
-      ..environmentDefines = const {};
+      ..environmentDefines = const {}
+      ..experimentalFlags = experimentalFlags;
 
     processedOpts = new ProcessedOptions(options: options);
     cachedSdkInput = WorkerInputComponent(
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 4c2076b..d761b49 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -131,6 +131,7 @@
     Uri packagesFile,
     Uri librariesSpecificationUri,
     List<Uri> inputSummaries,
+    Map<Uri, List<int>> workerInputDigests,
     Target target,
     {FileSystem fileSystem,
     Map<ExperimentalFlag, bool> experiments}) async {
@@ -143,12 +144,19 @@
 
   Map<Uri, WorkerInputComponent> workerInputCache =
       oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+  var sdkDigest = workerInputDigests[sdkSummary];
+  if (sdkDigest == null) {
+    throw new StateError("Expected to get sdk digest at $cachedSdkInput");
+  }
+
   cachedSdkInput = workerInputCache[sdkSummary];
 
   if (oldState == null ||
       oldState.incrementalCompiler == null ||
       oldState.options.compileSdk != compileSdk ||
-      cachedSdkInput == null) {
+      cachedSdkInput == null ||
+      !digestsEqual(cachedSdkInput.digest, sdkDigest) ||
+      !equalMaps(oldState.options.experimentalFlags, experiments)) {
     // No previous state.
     options = new CompilerOptions()
       ..compileSdk = compileSdk
@@ -166,8 +174,8 @@
 
     processedOpts = new ProcessedOptions(options: options);
 
-    cachedSdkInput = new WorkerInputComponent(null /* not compared anyway */,
-        await processedOpts.loadSdkSummary(null));
+    cachedSdkInput = new WorkerInputComponent(
+        sdkDigest, await processedOpts.loadSdkSummary(null));
     workerInputCache[sdkSummary] = cachedSdkInput;
     incrementalCompiler = new IncrementalCompiler.fromComponent(
         new CompilerContext(processedOpts), cachedSdkInput.component);
@@ -207,10 +215,13 @@
   for (int i = 0; i < inputSummaries.length; i++) {
     Uri inputSummary = inputSummaries[i];
     WorkerInputComponent cachedInput = workerInputCache[inputSummary];
+    var digest = workerInputDigests[inputSummary];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $inputSummary");
+    }
     if (cachedInput == null ||
         cachedInput.component.root != nameRoot ||
-        !digestsEqual(await fileSystem.entityForUri(inputSummary).readAsBytes(),
-            cachedInput.digest)) {
+        !digestsEqual(digest, cachedInput.digest)) {
       loadFromDillIndexes.add(i);
     } else {
       // Need to reset cached components so they are usable again.
@@ -226,11 +237,15 @@
   for (int i = 0; i < loadFromDillIndexes.length; i++) {
     int index = loadFromDillIndexes[i];
     Uri summary = inputSummaries[index];
-    List<int> data = await fileSystem.entityForUri(summary).readAsBytes();
+    List<int> digest = workerInputDigests[summary];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $summary");
+    }
+    var bytes = await fileSystem.entityForUri(summary).readAsBytes();
     WorkerInputComponent cachedInput = WorkerInputComponent(
-        data,
+        digest,
         await compilerState.processedOpts
-            .loadComponent(data, nameRoot, alwaysCreateNewNamedNodes: true));
+            .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
     workerInputCache[summary] = cachedInput;
     doneInputSummaries[index] = cachedInput.component;
   }
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 77ea7b9..5d814c2 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -34,14 +34,19 @@
 export '../fasta/fasta_codes.dart'
     show
         LocatedMessage,
+        messageBytecodeLimitExceededTooManyArguments,
+        noLength,
         templateFfiFieldAnnotation,
-        templateFfiStructAnnotation,
         templateFfiNotStatic,
         templateFfiTypeInvalid,
         templateFfiTypeMismatch,
         templateFfiTypeUnsized,
         templateFfiFieldInitializer,
-        templateIllegalRecursiveType;
+        templateIllegalRecursiveType,
+        templateFfiDartTypeMismatch,
+        templateFfiExtendsOrImplementsSealedClass,
+        templateFfiStructGeneric,
+        templateFfiWrongStructInheritance;
 
 export '../fasta/hybrid_file_system.dart' show HybridFileSystem;
 
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 51e0852..a818b67 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -27,6 +27,7 @@
     show
         ClassBuilder,
         Declaration,
+        FieldBuilder,
         ModifierBuilder,
         NameIterator,
         PrefixBuilder,
@@ -237,6 +238,8 @@
   void recordAccess(int charOffset, int length, Uri fileUri) {}
 
   void buildOutlineExpressions() {}
+
+  List<FieldBuilder> takeImplicitlyTypedFields() => null;
 }
 
 class LibraryLocalDeclarationIterator implements Iterator<Declaration> {
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 0b99bf5..e714210 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -4,6 +4,8 @@
 
 library fasta.member_builder;
 
+import '../problems.dart' show unsupported;
+
 import 'builder.dart'
     show ClassBuilder, Declaration, LibraryBuilder, ModifierBuilder;
 
@@ -41,4 +43,10 @@
 
   @override
   String get fullNameForErrors => name;
+
+  void inferType() => unsupported("inferType", charOffset, fileUri);
+
+  void inferCopiedType(covariant Object other) {
+    unsupported("inferType", charOffset, fileUri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index b25813b..2055984 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -461,6 +461,15 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeBytecodeLimitExceededTooManyArguments =
+    messageBytecodeLimitExceededTooManyArguments;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageBytecodeLimitExceededTooManyArguments =
+    const MessageCode("BytecodeLimitExceededTooManyArguments",
+        message: r"""Dart bytecode limit exceeded: too many arguments.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCandidateFound = messageCandidateFound;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -581,6 +590,36 @@
     tip: r"""Try specifying the file explicitly with the --packages option.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateCantInferReturnTypeDueToInconsistentOverrides =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Can't infer a return type for '#name' as some of the inherited members have different types.""",
+        tipTemplate: r"""Try adding an explicit type.""",
+        withArguments:
+            _withArgumentsCantInferReturnTypeDueToInconsistentOverrides);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeCantInferReturnTypeDueToInconsistentOverrides =
+    const Code<Message Function(String name)>(
+        "CantInferReturnTypeDueToInconsistentOverrides",
+        templateCantInferReturnTypeDueToInconsistentOverrides,
+        analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantInferReturnTypeDueToInconsistentOverrides(
+    String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeCantInferReturnTypeDueToInconsistentOverrides,
+      message:
+          """Can't infer a return type for '${name}' as some of the inherited members have different types.""",
+      tip: """Try adding an explicit type.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         String
@@ -777,6 +816,38 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        String name,
+        String
+            name2)> templateCombinedMemberSignatureFailed = const Template<
+        Message Function(String name, String name2)>(
+    messageTemplate:
+        r"""Class '#name' inherits multiple members named '#name2' with incompatible signatures.""",
+    tipTemplate: r"""Try adding a declaration of '#name2' to '#name'.""",
+    withArguments: _withArgumentsCombinedMemberSignatureFailed);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String name2)>
+    codeCombinedMemberSignatureFailed =
+    const Code<Message Function(String name, String name2)>(
+        "CombinedMemberSignatureFailed", templateCombinedMemberSignatureFailed,
+        analyzerCodes: <String>["INCONSISTENT_INHERITANCE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCombinedMemberSignatureFailed(String name, String name2) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  return new Message(codeCombinedMemberSignatureFailed,
+      message:
+          """Class '${name}' inherits multiple members named '${name2}' with incompatible signatures.""",
+      tip: """Try adding a declaration of '${name2}' to '${name}'.""",
+      arguments: {'name': name, 'name2': name2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
         String string,
         String
             string2)> templateConflictingModifiers = const Template<
@@ -3571,11 +3642,64 @@
   -h        Display this message (add -v for information about all options).""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(DartType _type, DartType _type2)>
+    templateFfiDartTypeMismatch =
+    const Template<Message Function(DartType _type, DartType _type2)>(
+        messageTemplate: r"""Expected '#type' to be a subtype of '#type2'.""",
+        withArguments: _withArgumentsFfiDartTypeMismatch);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, DartType _type2)>
+    codeFfiDartTypeMismatch =
+    const Code<Message Function(DartType _type, DartType _type2)>(
+  "FfiDartTypeMismatch",
+  templateFfiDartTypeMismatch,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiDartTypeMismatch(DartType _type, DartType _type2) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  return new Message(codeFfiDartTypeMismatch,
+      message: """Expected '${type}' to be a subtype of '${type2}'.""" +
+          labeler.originMessages,
+      arguments: {'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateFfiExtendsOrImplementsSealedClass =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Class '#name' cannot be extended or implemented.""",
+        withArguments: _withArgumentsFfiExtendsOrImplementsSealedClass);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeFfiExtendsOrImplementsSealedClass =
+    const Code<Message Function(String name)>(
+  "FfiExtendsOrImplementsSealedClass",
+  templateFfiExtendsOrImplementsSealedClass,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiExtendsOrImplementsSealedClass(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiExtendsOrImplementsSealedClass,
+      message: """Class '${name}' cannot be extended or implemented.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(String name)> templateFfiFieldAnnotation = const Template<
         Message Function(String name)>(
     messageTemplate:
-        r"""Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+        r"""Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields.""",
     withArguments: _withArgumentsFfiFieldAnnotation);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3591,7 +3715,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeFfiFieldAnnotation,
       message:
-          """Field '${name}' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+          """Field '${name}' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields.""",
       arguments: {'name': name});
 }
 
@@ -3646,27 +3770,24 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
-    Message Function(String name)> templateFfiStructAnnotation = const Template<
-        Message Function(String name)>(
-    messageTemplate:
-        r"""Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
-    withArguments: _withArgumentsFfiStructAnnotation);
+const Template<Message Function(String name)> templateFfiStructGeneric =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Struct '#name' should not be generic.""",
+        withArguments: _withArgumentsFfiStructGeneric);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeFfiStructAnnotation =
+const Code<Message Function(String name)> codeFfiStructGeneric =
     const Code<Message Function(String name)>(
-  "FfiStructAnnotation",
-  templateFfiStructAnnotation,
+  "FfiStructGeneric",
+  templateFfiStructGeneric,
 );
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFfiStructAnnotation(String name) {
+Message _withArgumentsFfiStructGeneric(String name) {
   if (name.isEmpty) throw 'No name provided';
   name = demangleMixinApplicationName(name);
-  return new Message(codeFfiStructAnnotation,
-      message:
-          """Class '${name}' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
+  return new Message(codeFfiStructGeneric,
+      message: """Struct '${name}' should not be generic.""",
       arguments: {'name': name});
 }
 
@@ -3767,6 +3888,30 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateFfiWrongStructInheritance =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Struct '#name' must inherit from 'Struct<#name>'.""",
+        withArguments: _withArgumentsFfiWrongStructInheritance);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiWrongStructInheritance =
+    const Code<Message Function(String name)>(
+  "FfiWrongStructInheritance",
+  templateFfiWrongStructInheritance,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiWrongStructInheritance(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiWrongStructInheritance,
+      message: """Struct '${name}' must inherit from 'Struct<${name}>'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeFieldInitializedOutsideDeclaringClass =
     messageFieldInitializedOutsideDeclaringClass;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 71c58dc..691cdc7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2412,6 +2412,14 @@
   }
 
   @override
+  void endInvalidAwaitExpression(
+      Token keyword, Token endToken, fasta.MessageCode errorCode) {
+    debugEvent("AwaitExpression");
+    popForValue();
+    push(buildProblem(errorCode, keyword.offset, keyword.length));
+  }
+
+  @override
   void handleAsyncModifier(Token asyncToken, Token starToken) {
     debugEvent("AsyncModifier");
     push(asyncMarkerFromTokens(asyncToken, starToken));
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 2593336..0960fca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -8,14 +8,19 @@
     show
         Class,
         DartType,
+        Field,
+        FunctionNode,
         InterfaceType,
-        TypeParameter,
+        InvalidType,
         Library,
         Member,
         Name,
         Procedure,
         ProcedureKind,
-        Supertype;
+        Supertype,
+        TypeParameter,
+        TypeParameterType,
+        VariableDeclaration;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -23,6 +28,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import '../dill/dill_member_builder.dart' show DillMemberBuilder;
+
 import '../loader.dart' show Loader;
 
 import '../messages.dart'
@@ -36,15 +43,23 @@
         messageInheritedMembersConflictCause2,
         messageStaticAndInstanceConflict,
         messageStaticAndInstanceConflictCause,
+        templateCantInferReturnTypeDueToInconsistentOverrides,
+        templateCantInferTypeDueToInconsistentOverrides,
+        templateCombinedMemberSignatureFailed,
         templateDuplicatedDeclaration,
         templateDuplicatedDeclarationCause,
+        templateDuplicatedDeclarationUse,
         templateMissingImplementationCause,
         templateMissingImplementationNotAbstract;
 
 import '../names.dart' show noSuchMethodName;
 
+import '../problems.dart' show unhandled;
+
 import '../scope.dart' show Scope;
 
+import '../source/source_loader.dart' show SourceLoader;
+
 import '../type_inference/standard_bounds.dart' show StandardBounds;
 
 import '../type_inference/type_constraint_gatherer.dart'
@@ -56,18 +71,35 @@
 
 import '../type_inference/type_schema_environment.dart' show TypeConstraint;
 
+import 'forwarding_node.dart' show ForwardingNode;
+
 import 'kernel_builder.dart'
     show
         Declaration,
+        FormalParameterBuilder,
+        ImplicitFieldType,
         KernelClassBuilder,
+        KernelFieldBuilder,
+        KernelLibraryBuilder,
         KernelNamedTypeBuilder,
+        KernelProcedureBuilder,
         KernelTypeBuilder,
+        KernelTypeVariableBuilder,
         LibraryBuilder,
+        MemberBuilder,
         TypeBuilder,
         TypeVariableBuilder;
 
 import 'types.dart' show Types;
 
+const DebugLogger debug =
+    const bool.fromEnvironment("debug.hierarchy") ? const DebugLogger() : null;
+
+class DebugLogger {
+  const DebugLogger();
+  void log(Object message) => print(message);
+}
+
 int compareDeclarations(Declaration a, Declaration b) {
   return ClassHierarchy.compareMembers(a.target, b.target);
 }
@@ -94,6 +126,7 @@
   if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
   if (a.isSetter) return !(b.isGetter || b.isSetter);
   if (b.isSetter) return !(a.isGetter || a.isSetter);
+  if (a is InterfaceConflict || b is InterfaceConflict) return false;
   return true;
 }
 
@@ -101,6 +134,68 @@
   return declaration.isField && !(declaration.isFinal || declaration.isConst);
 }
 
+bool hasSameSignature(FunctionNode a, FunctionNode b) {
+  List<TypeParameter> aTypeParameters = a.typeParameters;
+  List<TypeParameter> bTypeParameters = b.typeParameters;
+  int typeParameterCount = aTypeParameters.length;
+  if (typeParameterCount != bTypeParameters.length) return false;
+  Substitution substitution;
+  if (typeParameterCount != 0) {
+    List<DartType> types = new List<DartType>(typeParameterCount);
+    for (int i = 0; i < typeParameterCount; i++) {
+      types[i] = new TypeParameterType(aTypeParameters[i]);
+    }
+    substitution = Substitution.fromPairs(bTypeParameters, types);
+    for (int i = 0; i < typeParameterCount; i++) {
+      DartType aBound = aTypeParameters[i].bound;
+      DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+      if (aBound != bBound) return false;
+    }
+  }
+
+  if (a.requiredParameterCount != b.requiredParameterCount) return false;
+  List<VariableDeclaration> aPositionalParameters = a.positionalParameters;
+  List<VariableDeclaration> bPositionalParameters = b.positionalParameters;
+  if (aPositionalParameters.length != bPositionalParameters.length) {
+    return false;
+  }
+  for (int i = 0; i < aPositionalParameters.length; i++) {
+    VariableDeclaration aParameter = aPositionalParameters[i];
+    VariableDeclaration bParameter = bPositionalParameters[i];
+    if (aParameter.isCovariant != bParameter.isCovariant) return false;
+    DartType aType = aParameter.type;
+    DartType bType = bParameter.type;
+    if (substitution != null) {
+      bType = substitution.substituteType(bType);
+    }
+    if (aType != bType) return false;
+  }
+
+  List<VariableDeclaration> aNamedParameters = a.namedParameters;
+  List<VariableDeclaration> bNamedParameters = b.namedParameters;
+  if (aNamedParameters.length != bNamedParameters.length) return false;
+  for (int i = 0; i < aNamedParameters.length; i++) {
+    VariableDeclaration aParameter = aNamedParameters[i];
+    VariableDeclaration bParameter = bNamedParameters[i];
+    if (aParameter.isCovariant != bParameter.isCovariant) return false;
+    if (aParameter.name != bParameter.name) return false;
+    DartType aType = aParameter.type;
+    DartType bType = bParameter.type;
+    if (substitution != null) {
+      bType = substitution.substituteType(bType);
+    }
+    if (aType != bType) return false;
+  }
+
+  DartType aReturnType = a.returnType;
+  DartType bReturnType = b.returnType;
+  if (substitution != null) {
+    bReturnType = substitution.substituteType(bReturnType);
+  }
+
+  return aReturnType == bReturnType;
+}
+
 class ClassHierarchyBuilder {
   final Map<Class, ClassHierarchyNode> nodes = <Class, ClassHierarchyNode>{};
 
@@ -118,6 +213,10 @@
 
   final Class nullKernelClass;
 
+  final List<DelayedOverrideCheck> overrideChecks = <DelayedOverrideCheck>[];
+
+  final List<DelayedMember> delayedMemberChecks = <DelayedMember>[];
+
   // TODO(ahe): Remove this.
   final CoreTypes coreTypes;
 
@@ -138,10 +237,8 @@
   }
 
   ClassHierarchyNode getNodeFromType(KernelTypeBuilder type) {
-    Declaration declaration = type.declaration;
-    return declaration is KernelClassBuilder
-        ? getNodeFromClass(declaration)
-        : null;
+    KernelClassBuilder cls = getClass(type);
+    return cls == null ? null : getNodeFromClass(cls);
   }
 
   ClassHierarchyNode getNodeFromKernelClass(Class cls) {
@@ -190,7 +287,9 @@
     }
     KernelNamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass);
     if (supertype == null) return null;
-    if (supertype.arguments == null) return superclass.rawType;
+    if (supertype.arguments == null && superclass.typeParameters.isEmpty) {
+      return superclass.rawType;
+    }
     return Substitution.fromInterfaceType(type)
         .substituteType(supertype.build(null));
   }
@@ -232,17 +331,54 @@
     return objectKernelClass.rawType;
   }
 
+  Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) {
+    return getNodeFromKernelClass(cls)
+        .getInterfaceMember(name, isSetter)
+        ?.target;
+  }
+
+  Member getDispatchTargetKernel(Class cls, Name name, bool isSetter) {
+    return getNodeFromKernelClass(cls)
+        .getDispatchTarget(name, isSetter)
+        ?.target;
+  }
+
+  Member getCombinedMemberSignatureKernel(Class cls, Name name, bool isSetter,
+      int charOffset, KernelLibraryBuilder library) {
+    Declaration declaration =
+        getNodeFromKernelClass(cls).getInterfaceMember(name, isSetter);
+    if (declaration?.isStatic ?? true) return null;
+    if (declaration.next != null) {
+      library?.addProblem(
+          templateDuplicatedDeclarationUse.withArguments(name.name),
+          charOffset,
+          name.name.length,
+          library.fileUri);
+      return null;
+    }
+    if (declaration is DelayedMember) {
+      return declaration.check(this);
+    } else {
+      return declaration.target;
+    }
+  }
+
   static ClassHierarchyBuilder build(
       KernelClassBuilder objectClass,
       List<KernelClassBuilder> classes,
-      Loader<Object> loader,
+      SourceLoader loader,
       CoreTypes coreTypes) {
     ClassHierarchyBuilder hierarchy =
         new ClassHierarchyBuilder(objectClass, loader, coreTypes);
     for (int i = 0; i < classes.length; i++) {
       KernelClassBuilder cls = classes[i];
-      hierarchy.nodes[cls.target] =
-          new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+      if (!cls.isPatch) {
+        hierarchy.nodes[cls.target] =
+            new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+      } else {
+        // TODO(ahe): Merge the injected members of patch into the hierarchy
+        // node of `cls.origin`.
+      }
     }
     return hierarchy;
   }
@@ -261,6 +397,8 @@
 
   KernelClassBuilder get objectClass => hierarchy.objectClass;
 
+  final Map<Class, Substitution> substitutions = <Class, Substitution>{};
+
   /// When merging `aList` and `bList`, [a] (from `aList`) and [b] (from
   /// `bList`) each have the same name.
   ///
@@ -271,44 +409,606 @@
   ///
   /// If [mergeKind] is `MergeKind.supertypes`, [a] should implement [b], and
   /// [b] is implicitly abstract.
-  Declaration handleMergeConflict(KernelClassBuilder cls, Declaration a,
-      Declaration b, MergeKind mergeKind) {
+  Declaration handleMergeConflict(
+      Declaration a, Declaration b, MergeKind mergeKind) {
+    debug?.log(
+        "handleMergeConflict: ${fullName(a)} ${fullName(b)} ${mergeKind}");
+    // TODO(ahe): Enable this optimization, but be careful about abstract
+    // methods overriding concrete methods.
+    // if (cls is DillClassBuilder) return a;
     if (a == b) return a;
     if (a.next != null || b.next != null) {
       // Don't check overrides involving duplicated members.
       return a;
     }
-    if (isInheritanceConflict(a, b)) {
-      reportInheritanceConflict(cls, a, b);
-    }
-    Declaration result = a;
-    if (mergeKind == MergeKind.accessors) {
-    } else if (mergeKind == MergeKind.interfaces) {
-      // TODO(ahe): Combine the signatures of a and b.  See the section named
-      // "Combined Member Signatures" in [Dart Programming Language
-      // Specification](
-      // ../../../../../../docs/language/dartLangSpec.tex#combinedMemberSignatures).
-    } else if (a.target.isAbstract) {
-      if (mergeKind == MergeKind.superclass && !b.target.isAbstract) {
-        // An abstract method doesn't override an implemention inherited from a
-        // superclass.
-        result = b;
-      } else {
-        (abstractMembers ??= <Declaration>[]).add(a);
-      }
-    }
+    Declaration result = checkInheritanceConflict(a, b);
+    if (result != null) return result;
+    result = a;
+    switch (mergeKind) {
+      case MergeKind.superclassMembers:
+      case MergeKind.superclassSetters:
+        // [a] is a method declared in [cls]. This means it defines the
+        // interface of this class regardless if its abstract.
+        debug?.log(
+            "superclass: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+        checkValidOverride(
+            a, AbstractMemberOverridingImplementation.selectAbstract(b));
 
-    if (mergeKind == MergeKind.superclass &&
-        result.fullNameForErrors == noSuchMethodName.name &&
-        result.parent != objectClass) {
-      hasNoSuchMethod = true;
+        if (isAbstract(a)) {
+          if (isAbstract(b)) {
+            recordAbstractMember(a);
+          } else {
+            if (!cls.isAbstract) {
+              // The interface of this class is [a]. But the implementation is
+              // [b]. So [b] must implement [a], unless [cls] is abstract.
+              checkValidOverride(b, a);
+            }
+            result = new AbstractMemberOverridingImplementation(
+                cls,
+                a,
+                AbstractMemberOverridingImplementation.selectConcrete(b),
+                mergeKind == MergeKind.superclassSetters,
+                cls.library.loader == hierarchy.loader);
+            hierarchy.delayedMemberChecks.add(result);
+          }
+        } else if (cls.isMixinApplication && a.parent != cls) {
+          result = InheritedImplementationInterfaceConflict.combined(
+              cls,
+              a,
+              b,
+              mergeKind == MergeKind.superclassSetters,
+              cls.library.loader == hierarchy.loader,
+              isInheritableConflict: false);
+          if (result is DelayedMember) {
+            hierarchy.delayedMemberChecks.add(result);
+          }
+        }
+
+        Member target = result.target;
+        if (target.enclosingClass != objectClass.cls &&
+            target.name == noSuchMethodName) {
+          hasNoSuchMethod = true;
+        }
+        break;
+
+      case MergeKind.membersWithSetters:
+      case MergeKind.settersWithMembers:
+        if (a.parent == cls && b.parent != cls) {
+          if (a is KernelFieldBuilder) {
+            if (a.isFinal && b.isSetter) {
+              hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+            } else {
+              if (!inferFieldTypes(a, b)) {
+                hierarchy.overrideChecks
+                    .add(new DelayedOverrideCheck(cls, a, b));
+              }
+            }
+          } else if (a is KernelProcedureBuilder) {
+            if (!inferMethodTypes(a, b)) {
+              hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+            }
+          }
+        }
+        break;
+
+      case MergeKind.interfacesMembers:
+        result = InterfaceConflict.combined(
+            cls, a, b, false, cls.library.loader == hierarchy.loader);
+        break;
+
+      case MergeKind.interfacesSetters:
+        result = InterfaceConflict.combined(
+            cls, a, b, true, cls.library.loader == hierarchy.loader);
+        break;
+
+      case MergeKind.supertypesMembers:
+      case MergeKind.supertypesSetters:
+        // [b] is inherited from an interface so it is implicitly abstract.
+
+        a = AbstractMemberOverridingImplementation.selectAbstract(a);
+        b = AbstractMemberOverridingImplementation.selectAbstract(b);
+
+        // If [a] is declared in this class, it defines the interface.
+        if (a.parent == cls) {
+          debug?.log(
+              "supertypes: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+          checkValidOverride(a, b);
+          if (a is DelayedMember && !a.isInheritableConflict) {
+            if (b is DelayedMember) {
+              b.addAllDeclarationsTo(a.declarations);
+            } else {
+              addDeclarationIfDifferent(b, a.declarations);
+            }
+          }
+        } else {
+          if (isAbstract(a)) {
+            result = InterfaceConflict.combined(
+                cls,
+                a,
+                b,
+                mergeKind == MergeKind.supertypesSetters,
+                cls.library.loader == hierarchy.loader);
+          } else {
+            result = InheritedImplementationInterfaceConflict.combined(
+                cls,
+                a,
+                b,
+                mergeKind == MergeKind.supertypesSetters,
+                cls.library.loader == hierarchy.loader);
+          }
+          debug?.log("supertypes: ${result}");
+          if (result is DelayedMember) {
+            hierarchy.delayedMemberChecks.add(result);
+          }
+        }
+        break;
     }
 
     return result;
   }
 
-  void reportInheritanceConflict(
-      KernelClassBuilder cls, Declaration a, Declaration b) {
+  Declaration checkInheritanceConflict(Declaration a, Declaration b) {
+    if (a is DelayedMember) {
+      Declaration result;
+      for (int i = 0; i < a.declarations.length; i++) {
+        Declaration d = checkInheritanceConflict(a.declarations[i], b);
+        result ??= d;
+      }
+      return result;
+    }
+    if (b is DelayedMember) {
+      Declaration result;
+      for (int i = 0; i < b.declarations.length; i++) {
+        Declaration d = checkInheritanceConflict(a, b.declarations[i]);
+        result ??= d;
+      }
+      return result;
+    }
+    if (isInheritanceConflict(a, b)) {
+      reportInheritanceConflict(a, b);
+      return a;
+    }
+    return null;
+  }
+
+  bool inferMethodTypes(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Trying to infer types for ${fullName(a)} based on ${fullName(b)}");
+    if (b is DelayedMember) {
+      bool hasSameSignature = true;
+      List<Declaration> declarations = b.declarations;
+      for (int i = 0; i < declarations.length; i++) {
+        if (!inferMethodTypes(a, declarations[i])) {
+          hasSameSignature = false;
+        }
+      }
+      return hasSameSignature;
+    }
+    if (a.isGetter) {
+      return inferGetterType(a, b);
+    } else if (a.isSetter) {
+      return inferSetterType(a, b);
+    }
+    bool hadTypesInferred = a.hadTypesInferred;
+    KernelClassBuilder aCls = a.parent;
+    Substitution aSubstitution;
+    if (cls != aCls) {
+      assert(substitutions.containsKey(aCls.target),
+          "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+      aSubstitution = substitutions[aCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+    }
+    KernelClassBuilder bCls = b.parent;
+    Substitution bSubstitution;
+    if (cls != bCls) {
+      assert(substitutions.containsKey(bCls.target),
+          "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+      bSubstitution = substitutions[bCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+    }
+    Procedure aProcedure = a.target;
+    if (b.target is! Procedure) {
+      debug?.log("Giving up 1");
+      return false;
+    }
+    Procedure bProcedure = b.target;
+    FunctionNode aFunction = aProcedure.function;
+    FunctionNode bFunction = bProcedure.function;
+
+    List<TypeParameter> aTypeParameters = aFunction.typeParameters;
+    List<TypeParameter> bTypeParameters = bFunction.typeParameters;
+    int typeParameterCount = aTypeParameters.length;
+    if (typeParameterCount != bTypeParameters.length) {
+      debug?.log("Giving up 2");
+      return false;
+    }
+    Substitution substitution;
+    if (typeParameterCount != 0) {
+      for (int i = 0; i < typeParameterCount; i++) {
+        copyTypeParameterCovariance(
+            a.parent, aTypeParameters[i], bTypeParameters[i]);
+      }
+      List<DartType> types = new List<DartType>(typeParameterCount);
+      for (int i = 0; i < typeParameterCount; i++) {
+        types[i] = new TypeParameterType(aTypeParameters[i]);
+      }
+      substitution = Substitution.fromPairs(bTypeParameters, types);
+      for (int i = 0; i < typeParameterCount; i++) {
+        DartType aBound = aTypeParameters[i].bound;
+        DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+        if (aBound != bBound) {
+          debug?.log("Giving up 3");
+          return false;
+        }
+      }
+    }
+
+    DartType aReturnType = aFunction.returnType;
+    if (aSubstitution != null) {
+      aReturnType = aSubstitution.substituteType(aReturnType);
+    }
+    DartType bReturnType = bFunction.returnType;
+    if (bSubstitution != null) {
+      bReturnType = bSubstitution.substituteType(bReturnType);
+    }
+    if (substitution != null) {
+      bReturnType = substitution.substituteType(bReturnType);
+    }
+    bool result = true;
+    if (aFunction.requiredParameterCount > bFunction.requiredParameterCount) {
+      debug?.log("Giving up 4");
+      return false;
+    }
+    List<VariableDeclaration> aPositional = aFunction.positionalParameters;
+    List<VariableDeclaration> bPositional = bFunction.positionalParameters;
+    if (aPositional.length < bPositional.length) {
+      debug?.log("Giving up 5");
+      return false;
+    }
+
+    if (aReturnType != bReturnType) {
+      if (a.parent == cls && a.returnType == null) {
+        result =
+            inferReturnType(cls, a, bReturnType, hadTypesInferred, hierarchy);
+      } else {
+        debug?.log("Giving up 6");
+        result = false;
+      }
+    }
+
+    for (int i = 0; i < bPositional.length; i++) {
+      VariableDeclaration aParameter = aPositional[i];
+      VariableDeclaration bParameter = bPositional[i];
+      copyParameterCovariance(a.parent, aParameter, bParameter);
+      DartType aType = aParameter.type;
+      if (aSubstitution != null) {
+        aType = aSubstitution.substituteType(aType);
+      }
+      DartType bType = bParameter.type;
+      if (bSubstitution != null) {
+        bType = bSubstitution.substituteType(bType);
+      }
+      if (substitution != null) {
+        bType = substitution.substituteType(bType);
+      }
+      if (aType != bType) {
+        if (a.parent == cls && a.formals[i].type == null) {
+          result = inferParameterType(
+              cls, a, a.formals[i], bType, hadTypesInferred, hierarchy);
+        } else {
+          debug?.log("Giving up 8");
+          result = false;
+        }
+      }
+    }
+
+    List<VariableDeclaration> aNamed = aFunction.namedParameters;
+    List<VariableDeclaration> bNamed = bFunction.namedParameters;
+    named:
+    if (aNamed.isNotEmpty || bNamed.isNotEmpty) {
+      if (aPositional.length != bPositional.length) {
+        debug?.log("Giving up 9");
+        result = false;
+        break named;
+      }
+      if (aFunction.requiredParameterCount !=
+          bFunction.requiredParameterCount) {
+        debug?.log("Giving up 10");
+        result = false;
+        break named;
+      }
+
+      aNamed = aNamed.toList()..sort(compareNamedParameters);
+      bNamed = bNamed.toList()..sort(compareNamedParameters);
+      int aCount = 0;
+      for (int bCount = 0; bCount < bNamed.length; bCount++) {
+        String name = bNamed[bCount].name;
+        for (; aCount < aNamed.length; aCount++) {
+          if (aNamed[aCount].name == name) break;
+        }
+        if (aCount == aNamed.length) {
+          debug?.log("Giving up 11");
+          result = false;
+          break named;
+        }
+        VariableDeclaration aParameter = aNamed[aCount];
+        VariableDeclaration bParameter = bNamed[bCount];
+        copyParameterCovariance(a.parent, aParameter, bParameter);
+        DartType aType = aParameter.type;
+        if (aSubstitution != null) {
+          aType = aSubstitution.substituteType(aType);
+        }
+        DartType bType = bParameter.type;
+        if (bSubstitution != null) {
+          bType = bSubstitution.substituteType(bType);
+        }
+        if (substitution != null) {
+          bType = substitution.substituteType(bType);
+        }
+        if (aType != bType) {
+          FormalParameterBuilder<KernelTypeBuilder> parameter;
+          for (int i = aPositional.length; i < a.formals.length; ++i) {
+            if (a.formals[i].name == name) {
+              parameter = a.formals[i];
+              break;
+            }
+          }
+          if (a.parent == cls && parameter.type == null) {
+            result = inferParameterType(
+                cls, a, parameter, bType, hadTypesInferred, hierarchy);
+          } else {
+            debug?.log("Giving up 12");
+            result = false;
+          }
+        }
+      }
+    }
+    debug?.log("Inferring types for ${fullName(a)} based on ${fullName(b)} " +
+        (result ? "succeeded." : "failed."));
+    return result;
+  }
+
+  bool inferGetterType(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Inferring getter types for ${fullName(a)} based on ${fullName(b)}");
+    Member bTarget = b.target;
+    DartType bType;
+    if (bTarget is Field) {
+      bType = bTarget.type;
+    } else if (bTarget is Procedure) {
+      if (b.isSetter) {
+        VariableDeclaration bParameter =
+            bTarget.function.positionalParameters.single;
+        bType = bParameter.type;
+        if (!hasExplicitlyTypedFormalParameter(b, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (b.isGetter) {
+        bType = bTarget.function.returnType;
+        if (!hasExplicitReturnType(b)) {
+          debug?.log("Giving up (return type may be inferred)");
+          return false;
+        }
+      } else {
+        debug?.log("Giving up (not accessor: ${bTarget.kind})");
+        return false;
+      }
+    } else {
+      debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+      return false;
+    }
+    return a.target.function.returnType == bType;
+  }
+
+  bool inferSetterType(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Inferring setter types for ${fullName(a)} based on ${fullName(b)}");
+    Member bTarget = b.target;
+    Procedure aProcedure = a.target;
+    VariableDeclaration aParameter =
+        aProcedure.function.positionalParameters.single;
+    DartType bType;
+    if (bTarget is Field) {
+      bType = bTarget.type;
+      copyParameterCovarianceFromField(a.parent, aParameter, bTarget);
+    }
+    if (bTarget is Procedure) {
+      if (b.isSetter) {
+        VariableDeclaration bParameter =
+            bTarget.function.positionalParameters.single;
+        bType = bParameter.type;
+        copyParameterCovariance(a.parent, aParameter, bParameter);
+        if (!hasExplicitlyTypedFormalParameter(b, 0) ||
+            !hasExplicitlyTypedFormalParameter(a, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (b.isGetter) {
+        bType = bTarget.function.returnType;
+        if (!hasExplicitReturnType(b)) {
+          debug?.log("Giving up (return type may be inferred)");
+          return false;
+        }
+      } else {
+        debug?.log("Giving up (not accessor: ${bTarget.kind})");
+        return false;
+      }
+    } else {
+      debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+      return false;
+    }
+    return aParameter.type == bType;
+  }
+
+  void checkValidOverride(Declaration a, Declaration b) {
+    debug?.log(
+        "checkValidOverride(${fullName(a)}, ${fullName(b)}) ${a.runtimeType}");
+    if (a is KernelProcedureBuilder) {
+      if (inferMethodTypes(a, b)) return;
+    } else if (a.isField) {
+      if (inferFieldTypes(a, b)) return;
+    }
+    Member aTarget = a.target;
+    Member bTarget = b.target;
+    if (aTarget is Procedure && !aTarget.isAccessor && bTarget is Procedure) {
+      if (hasSameSignature(aTarget.function, bTarget.function)) return;
+    }
+
+    if (b is DelayedMember) {
+      for (int i = 0; i < b.declarations.length; i++) {
+        hierarchy.overrideChecks
+            .add(new DelayedOverrideCheck(cls, a, b.declarations[i]));
+      }
+    } else {
+      hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+    }
+  }
+
+  bool inferFieldTypes(MemberBuilder a, Declaration b) {
+    debug?.log(
+        "Trying to infer field types for ${fullName(a)} based on ${fullName(b)}");
+    if (b is DelayedMember) {
+      bool hasSameSignature = true;
+      List<Declaration> declarations = b.declarations;
+      for (int i = 0; i < declarations.length; i++) {
+        if (!inferFieldTypes(a, declarations[i])) {
+          hasSameSignature = false;
+        }
+      }
+      return hasSameSignature;
+    }
+    Member bTarget = b.target;
+    DartType inheritedType;
+    if (bTarget is Procedure) {
+      if (bTarget.isSetter) {
+        VariableDeclaration parameter =
+            bTarget.function.positionalParameters.single;
+        // inheritedType = parameter.type;
+        copyFieldCovarianceFromParameter(a.parent, a.target, parameter);
+        if (!hasExplicitlyTypedFormalParameter(b, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (bTarget.isGetter) {
+        if (!hasExplicitReturnType(b)) return false;
+        inheritedType = bTarget.function.returnType;
+      }
+    } else if (bTarget is Field) {
+      copyFieldCovariance(a.parent, a.target, bTarget);
+      inheritedType = bTarget.type;
+    }
+    if (inheritedType == null) {
+      debug?.log("Giving up (inheritedType == null)\n${StackTrace.current}");
+      return false;
+    }
+    KernelClassBuilder aCls = a.parent;
+    Substitution aSubstitution;
+    if (cls != aCls) {
+      assert(substitutions.containsKey(aCls.target),
+          "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+      aSubstitution = substitutions[aCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+    }
+    KernelClassBuilder bCls = b.parent;
+    Substitution bSubstitution;
+    if (cls != bCls) {
+      assert(substitutions.containsKey(bCls.target),
+          "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+      bSubstitution = substitutions[bCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+    }
+    if (bSubstitution != null && inheritedType is! ImplicitFieldType) {
+      inheritedType = bSubstitution.substituteType(inheritedType);
+    }
+
+    DartType declaredType = a.target.type;
+    if (aSubstitution != null) {
+      declaredType = aSubstitution.substituteType(declaredType);
+    }
+    if (declaredType == inheritedType) return true;
+
+    bool result = false;
+    if (a is KernelFieldBuilder) {
+      if (a.parent == cls && a.type == null) {
+        if (a.hadTypesInferred) {
+          reportCantInferFieldType(cls, a);
+          inheritedType = const InvalidType();
+        } else {
+          result = true;
+          a.hadTypesInferred = true;
+        }
+        if (inheritedType is ImplicitFieldType) {
+          KernelLibraryBuilder library = cls.library;
+          (library.implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(a);
+        }
+        a.target.type = inheritedType;
+      }
+    }
+    return result;
+  }
+
+  void copyParameterCovariance(Declaration parent,
+      VariableDeclaration aParameter, VariableDeclaration bParameter) {
+    if (parent == cls) {
+      if (bParameter.isCovariant) {
+        aParameter.isCovariant = true;
+      }
+      if (bParameter.isGenericCovariantImpl) {
+        aParameter.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyParameterCovarianceFromField(
+      Declaration parent, VariableDeclaration aParameter, Field bField) {
+    if (parent == cls) {
+      if (bField.isCovariant) {
+        aParameter.isCovariant = true;
+      }
+      if (bField.isGenericCovariantImpl) {
+        aParameter.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyFieldCovariance(Declaration parent, Field aField, Field bField) {
+    if (parent == cls) {
+      if (bField.isCovariant) {
+        aField.isCovariant = true;
+      }
+      if (bField.isGenericCovariantImpl) {
+        aField.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyFieldCovarianceFromParameter(
+      Declaration parent, Field aField, VariableDeclaration bParameter) {
+    if (parent == cls) {
+      if (bParameter.isCovariant) {
+        aField.isCovariant = true;
+      }
+      if (bParameter.isGenericCovariantImpl) {
+        aField.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyTypeParameterCovariance(
+      Declaration parent, TypeParameter aParameter, TypeParameter bParameter) {
+    if (parent == cls) {
+      if (bParameter.isGenericCovariantImpl) {
+        aParameter.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void reportInheritanceConflict(Declaration a, Declaration b) {
     String name = a.fullNameForErrors;
     if (a.parent != b.parent) {
       if (a.parent == cls) {
@@ -374,8 +1074,17 @@
   /// If [mergeKind] is `MergeKind.supertypes`, [member] isn't
   /// implementing/overriding anything.
   void handleOnlyA(Declaration member, MergeKind mergeKind) {
-    if (mergeKind == MergeKind.superclass && member.target.isAbstract) {
-      (abstractMembers ??= <Declaration>[]).add(member);
+    if (mergeKind == MergeKind.interfacesMembers ||
+        mergeKind == MergeKind.interfacesSetters) {
+      return;
+    }
+    // TODO(ahe): Enable this optimization:
+    // if (cls is DillClassBuilder) return;
+    // assert(mergeKind == MergeKind.interfaces || member is! InterfaceConflict);
+    if ((mergeKind == MergeKind.superclassMembers ||
+            mergeKind == MergeKind.superclassSetters) &&
+        isAbstract(member)) {
+      recordAbstractMember(member);
     }
   }
 
@@ -388,30 +1097,50 @@
   ///
   /// If [mergeKind] is `MergeKind.supertypes`, [member] is implicitly
   /// abstract, and not implemented.
-  void handleOnlyB(
-      KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
+  Declaration handleOnlyB(Declaration member, MergeKind mergeKind) {
+    if (mergeKind == MergeKind.interfacesMembers ||
+        mergeKind == MergeKind.interfacesSetters) {
+      return member;
+    }
+    // TODO(ahe): Enable this optimization:
+    // if (cls is DillClassBuilder) return member;
     Member target = member.target;
-    if (mergeKind == MergeKind.supertypes ||
-        (mergeKind == MergeKind.superclass && target.isAbstract)) {
+    if ((mergeKind == MergeKind.supertypesMembers ||
+            mergeKind == MergeKind.supertypesSetters) ||
+        ((mergeKind == MergeKind.superclassMembers ||
+                mergeKind == MergeKind.superclassSetters) &&
+            target.isAbstract)) {
       if (isNameVisibleIn(target.name, cls.library)) {
-        (abstractMembers ??= <Declaration>[]).add(member);
+        recordAbstractMember(member);
       }
     }
-    if (member.parent != objectClass &&
-        target.name == noSuchMethodName &&
-        !target.isAbstract) {
+    if (mergeKind == MergeKind.superclassMembers &&
+        target.enclosingClass != objectClass.cls &&
+        target.name == noSuchMethodName) {
       hasNoSuchMethod = true;
     }
+    if (mergeKind != MergeKind.membersWithSetters &&
+        mergeKind != MergeKind.settersWithMembers &&
+        member is DelayedMember &&
+        member.isInheritableConflict) {
+      hierarchy.delayedMemberChecks.add(member.withParent(cls));
+    }
+    return member;
+  }
+
+  void recordAbstractMember(Declaration member) {
+    abstractMembers ??= <Declaration>[];
+    if (member is DelayedMember) {
+      abstractMembers.addAll(member.declarations);
+    } else {
+      abstractMembers.add(member);
+    }
   }
 
   ClassHierarchyNode build() {
-    if (cls.isPatch) {
-      // TODO(ahe): What about patch classes. Have we injected patched members
-      // into the class-builder's scope?
-      return null;
-    }
+    assert(!cls.isPatch);
     ClassHierarchyNode supernode;
-    if (objectClass != cls) {
+    if (objectClass != cls.origin) {
       supernode = hierarchy.getNodeFromType(cls.supertype);
       if (supernode == null) {
         supernode = hierarchy.getNodeFromClass(objectClass);
@@ -423,8 +1152,10 @@
     if (cls.isMixinApplication) {
       Declaration mixin = cls.mixedInType.declaration;
       inferMixinApplication();
+      // recordSupertype(cls.mixedInType);
       while (mixin.isNamedMixinApplication) {
         KernelClassBuilder named = mixin;
+        // recordSupertype(named.mixedInType);
         mixin = named.mixedInType.declaration;
       }
       if (mixin is KernelClassBuilder) {
@@ -443,7 +1174,7 @@
           ..sort(compareDeclarations);
 
     // Add implied setters from fields in [localMembers].
-    localSetters = mergeAccessors(cls, localMembers, localSetters);
+    localSetters = mergeAccessors(localMembers, localSetters);
 
     /// Members (excluding setters) declared in [cls] or its superclasses. This
     /// includes static methods of [cls], but not its superclasses.
@@ -482,23 +1213,9 @@
           new List<KernelTypeBuilder>(supernode.superclasses.length + 1);
       superclasses.setRange(0, superclasses.length - 1,
           substSupertypes(cls.supertype, supernode.superclasses));
-      superclasses[superclasses.length - 1] = cls.supertype;
+      superclasses[superclasses.length - 1] = recordSupertype(cls.supertype);
 
-      classMembers = merge(
-          cls, localMembers, supernode.classMembers, MergeKind.superclass);
-      classSetters = merge(
-          cls, localSetters, supernode.classSetters, MergeKind.superclass);
-
-      // Check if local members conflict with inherited setters. This check has
-      // already been performed in the superclass, so we only need to check the
-      // local members.
-      merge(cls, localMembers, classSetters, MergeKind.accessors);
-
-      // Check if local setters conflict with inherited members. As above, we
-      // only need to check the local setters.
-      merge(cls, localSetters, classMembers, MergeKind.accessors);
-
-      List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+      List<KernelTypeBuilder> directInterfaces = ignoreFunction(cls.interfaces);
       if (cls.isMixinApplication) {
         if (directInterfaces == null) {
           directInterfaces = <KernelTypeBuilder>[cls.mixedInType];
@@ -508,15 +1225,29 @@
         }
       }
       if (directInterfaces != null) {
-        MergeResult result = mergeInterfaces(cls, supernode, directInterfaces);
+        for (int i = 0; i < directInterfaces.length; i++) {
+          recordSupertype(directInterfaces[i]);
+        }
+      }
+      List<KernelTypeBuilder> superclassInterfaces = supernode.interfaces;
+      if (superclassInterfaces != null) {
+        superclassInterfaces =
+            substSupertypes(cls.supertype, superclassInterfaces);
+      }
+
+      classMembers = merge(
+          localMembers, supernode.classMembers, MergeKind.superclassMembers);
+      classSetters = merge(
+          localSetters, supernode.classSetters, MergeKind.superclassSetters);
+
+      if (directInterfaces != null) {
+        MergeResult result = mergeInterfaces(supernode, directInterfaces);
         interfaceMembers = result.mergedMembers;
         interfaceSetters = result.mergedSetters;
         interfaces = <KernelTypeBuilder>[];
-        if (supernode.interfaces != null) {
-          List<KernelTypeBuilder> types =
-              substSupertypes(cls.supertype, supernode.interfaces);
-          for (int i = 0; i < types.length; i++) {
-            addInterface(interfaces, superclasses, types[i]);
+        if (superclassInterfaces != null) {
+          for (int i = 0; i < superclassInterfaces.length; i++) {
+            addInterface(interfaces, superclasses, superclassInterfaces[i]);
           }
         }
         for (int i = 0; i < directInterfaces.length; i++) {
@@ -546,30 +1277,41 @@
       } else {
         interfaceMembers = supernode.interfaceMembers;
         interfaceSetters = supernode.interfaceSetters;
-        interfaces = substSupertypes(cls.supertype, supernode.interfaces);
+        interfaces = superclassInterfaces;
       }
+
+      // Check if local members conflict with inherited setters. This check has
+      // already been performed in the superclass, so we only need to check the
+      // local members. These checks have to occur late to enable inferring
+      // types between setters and getters, or from a setter to a final field.
+      merge(localMembers, classSetters, MergeKind.membersWithSetters);
+
+      // Check if local setters conflict with inherited members. As above, we
+      // only need to check the local setters.
+      merge(localSetters, classMembers, MergeKind.settersWithMembers);
+
       if (interfaceMembers != null) {
         interfaceMembers =
-            merge(cls, classMembers, interfaceMembers, MergeKind.supertypes);
+            merge(classMembers, interfaceMembers, MergeKind.supertypesMembers);
 
         // Check if class setters conflict with members inherited from
         // interfaces.
-        merge(cls, classSetters, interfaceMembers, MergeKind.accessors);
+        merge(classSetters, interfaceMembers, MergeKind.settersWithMembers);
       }
       if (interfaceSetters != null) {
         interfaceSetters =
-            merge(cls, classSetters, interfaceSetters, MergeKind.supertypes);
+            merge(classSetters, interfaceSetters, MergeKind.supertypesSetters);
 
         // Check if class members conflict with setters inherited from
         // interfaces.
-        merge(cls, classMembers, interfaceSetters, MergeKind.accessors);
+        merge(classMembers, interfaceSetters, MergeKind.membersWithSetters);
       }
     }
     if (abstractMembers != null && !cls.isAbstract) {
       if (!hasNoSuchMethod) {
-        reportMissingMembers(cls);
+        reportMissingMembers();
       } else {
-        installNsmHandlers(cls);
+        installNsmHandlers();
       }
     }
     return new ClassHierarchyNode(
@@ -581,9 +1323,45 @@
       superclasses,
       interfaces,
       maxInheritancePath,
+      hasNoSuchMethod,
     );
   }
 
+  KernelTypeBuilder recordSupertype(KernelTypeBuilder supertype) {
+    if (supertype is KernelNamedTypeBuilder) {
+      debug?.log(
+          "In ${this.cls.fullNameForErrors} recordSupertype(${supertype.fullNameForErrors})");
+      Declaration declaration = supertype.declaration;
+      if (declaration is! KernelClassBuilder) return supertype;
+      KernelClassBuilder cls = declaration;
+      if (cls.isMixinApplication) {
+        recordSupertype(cls.mixedInType);
+      }
+      List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
+          cls.typeVariables;
+      if (typeVariables == null) {
+        substitutions[cls.target] = Substitution.empty;
+        assert(cls.target.typeParameters.isEmpty);
+      } else {
+        List<KernelTypeBuilder> arguments =
+            supertype.arguments ?? computeDefaultTypeArguments(supertype);
+        if (arguments.length != typeVariables.length) {
+          arguments = computeDefaultTypeArguments(supertype);
+        }
+        List<DartType> kernelArguments = new List<DartType>(arguments.length);
+        List<TypeParameter> kernelParameters =
+            new List<TypeParameter>(arguments.length);
+        for (int i = 0; i < arguments.length; i++) {
+          kernelParameters[i] = typeVariables[i].target;
+          kernelArguments[i] = arguments[i].build(this.cls.parent);
+        }
+        substitutions[cls.target] =
+            Substitution.fromPairs(kernelParameters, kernelArguments);
+      }
+    }
+    return supertype;
+  }
+
   List<KernelTypeBuilder> substSupertypes(
       KernelNamedTypeBuilder supertype, List<KernelTypeBuilder> supertypes) {
     Declaration declaration = supertype.declaration;
@@ -591,7 +1369,13 @@
     KernelClassBuilder cls = declaration;
     List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
         cls.typeVariables;
-    if (typeVariables == null) return supertypes;
+    if (typeVariables == null) {
+      debug?.log("In ${this.cls.fullNameForErrors} $supertypes aren't substed");
+      for (int i = 0; i < supertypes.length; i++) {
+        recordSupertype(supertypes[i]);
+      }
+      return supertypes;
+    }
     Map<TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder> substitution =
         <TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder>{};
     List<KernelTypeBuilder> arguments =
@@ -602,10 +1386,14 @@
     List<KernelTypeBuilder> result;
     for (int i = 0; i < supertypes.length; i++) {
       KernelTypeBuilder supertype = supertypes[i];
-      KernelTypeBuilder substed = supertype.subst(substitution);
+      KernelTypeBuilder substed =
+          recordSupertype(supertype.subst(substitution));
       if (supertype != substed) {
+        debug?.log("In ${this.cls.fullNameForErrors} $supertype -> $substed");
         result ??= supertypes.toList();
         result[i] = substed;
+      } else {
+        debug?.log("In ${this.cls.fullNameForErrors} $supertype isn't substed");
       }
     }
     return result ?? supertypes;
@@ -616,7 +1404,9 @@
     List<KernelTypeBuilder> result =
         new List<KernelTypeBuilder>(cls.typeVariables.length);
     for (int i = 0; i < result.length; ++i) {
-      result[i] = cls.typeVariables[i].defaultType;
+      KernelTypeVariableBuilder tv = cls.typeVariables[i];
+      result[i] = tv.defaultType ??
+          cls.library.loader.computeTypeBuilder(tv.target.defaultType);
     }
     return result;
   }
@@ -644,8 +1434,10 @@
     return null;
   }
 
-  MergeResult mergeInterfaces(KernelClassBuilder cls,
+  MergeResult mergeInterfaces(
       ClassHierarchyNode supernode, List<KernelTypeBuilder> interfaces) {
+    debug?.log(
+        "mergeInterfaces($cls (${this.cls}) ${supernode.interfaces} ${interfaces}");
     List<List<Declaration>> memberLists =
         new List<List<Declaration>>(interfaces.length + 1);
     List<List<Declaration>> setterLists =
@@ -665,12 +1457,12 @@
             interfaceNode.interfaceSetters ?? interfaceNode.classSetters;
       }
     }
-    return new MergeResult(
-        mergeLists(cls, memberLists), mergeLists(cls, setterLists));
+    return new MergeResult(mergeLists(memberLists, MergeKind.interfacesMembers),
+        mergeLists(setterLists, MergeKind.interfacesSetters));
   }
 
   List<Declaration> mergeLists(
-      KernelClassBuilder cls, List<List<Declaration>> input) {
+      List<List<Declaration>> input, MergeKind mergeKind) {
     // This is a k-way merge sort (where k is `input.length + 1`). We merge the
     // lists pairwise, which reduces the number of lists to merge by half on
     // each iteration. Consequently, we perform O(log k) merges.
@@ -684,7 +1476,7 @@
         } else if (second == null) {
           output.add(first);
         } else {
-          output.add(merge(cls, first, second, MergeKind.interfaces));
+          output.add(merge(first, second, mergeKind));
         }
       }
       if (input.length.isOdd) {
@@ -698,7 +1490,7 @@
   /// Merge [and check] accessors. This entails copying mutable fields to
   /// setters to simulate implied setters, and checking that setters don't
   /// override regular methods.
-  List<Declaration> mergeAccessors(KernelClassBuilder cls,
+  List<Declaration> mergeAccessors(
       List<Declaration> members, List<Declaration> setters) {
     final List<Declaration> mergedSetters = new List<Declaration>.filled(
         members.length + setters.length, null,
@@ -743,7 +1535,7 @@
     }
   }
 
-  void reportMissingMembers(KernelClassBuilder cls) {
+  void reportMissingMembers() {
     Map<String, LocatedMessage> contextMap = <String, LocatedMessage>{};
     for (int i = 0; i < abstractMembers.length; i++) {
       Declaration declaration = abstractMembers[i];
@@ -773,12 +1565,12 @@
         context: context);
   }
 
-  void installNsmHandlers(KernelClassBuilder cls) {
+  void installNsmHandlers() {
     // TOOD(ahe): Implement this.
   }
 
-  List<Declaration> merge(KernelClassBuilder cls, List<Declaration> aList,
-      List<Declaration> bList, MergeKind mergeKind) {
+  List<Declaration> merge(
+      List<Declaration> aList, List<Declaration> bList, MergeKind mergeKind) {
     final List<Declaration> result = new List<Declaration>.filled(
         aList.length + bList.length, null,
         growable: true);
@@ -788,7 +1580,9 @@
     while (i < aList.length && j < bList.length) {
       final Declaration a = aList[i];
       final Declaration b = bList[j];
-      if (mergeKind == MergeKind.interfaces && a.isStatic) {
+      if ((mergeKind == MergeKind.interfacesMembers ||
+              mergeKind == MergeKind.interfacesSetters) &&
+          a.isStatic) {
         i++;
         continue;
       }
@@ -798,7 +1592,7 @@
       }
       final int compare = compareDeclarations(a, b);
       if (compare == 0) {
-        result[storeIndex++] = handleMergeConflict(cls, a, b, mergeKind);
+        result[storeIndex++] = handleMergeConflict(a, b, mergeKind);
         i++;
         j++;
       } else if (compare < 0) {
@@ -806,14 +1600,15 @@
         result[storeIndex++] = a;
         i++;
       } else {
-        handleOnlyB(cls, b, mergeKind);
-        result[storeIndex++] = b;
+        result[storeIndex++] = handleOnlyB(b, mergeKind);
         j++;
       }
     }
     while (i < aList.length) {
       final Declaration a = aList[i];
-      if (mergeKind != MergeKind.interfaces || !a.isStatic) {
+      if (!(mergeKind == MergeKind.interfacesMembers ||
+              mergeKind == MergeKind.interfacesSetters) ||
+          !a.isStatic) {
         handleOnlyA(a, mergeKind);
         result[storeIndex++] = a;
       }
@@ -822,8 +1617,7 @@
     while (j < bList.length) {
       final Declaration b = bList[j];
       if (!b.isStatic) {
-        handleOnlyB(cls, b, mergeKind);
-        result[storeIndex++] = b;
+        result[storeIndex++] = handleOnlyB(b, mergeKind);
       }
       j++;
     }
@@ -853,6 +1647,25 @@
     KernelNamedTypeBuilder mixedInType = cls.mixedInType;
     mixedInType.arguments = inferredArguments;
   }
+
+  /// The class Function from dart:core is supposed to be ignored when used as
+  /// an interface.
+  List<KernelTypeBuilder> ignoreFunction(List<KernelTypeBuilder> interfaces) {
+    if (interfaces == null) return null;
+    for (int i = 0; i < interfaces.length; i++) {
+      KernelClassBuilder cls = getClass(interfaces[i]);
+      if (cls != null && cls.target == hierarchy.functionKernelClass) {
+        if (interfaces.length == 1) {
+          return null;
+        } else {
+          interfaces = interfaces.toList();
+          interfaces.removeAt(i);
+          return ignoreFunction(interfaces);
+        }
+      }
+    }
+    return interfaces;
+  }
 }
 
 class ClassHierarchyNode {
@@ -893,6 +1706,8 @@
 
   int get depth => superclasses.length;
 
+  final bool hasNoSuchMethod;
+
   ClassHierarchyNode(
       this.cls,
       this.classMembers,
@@ -901,7 +1716,8 @@
       this.interfaceSetters,
       this.superclasses,
       this.interfaces,
-      this.maxInheritancePath);
+      this.maxInheritancePath,
+      this.hasNoSuchMethod);
 
   /// Returns a list of all supertypes of [cls], including this node.
   List<ClassHierarchyNode> computeAllSuperNodes(
@@ -980,6 +1796,42 @@
     }
   }
 
+  Declaration getInterfaceMember(Name name, bool isSetter) {
+    return findMember(
+        name,
+        isSetter
+            ? interfaceSetters ?? classSetters
+            : interfaceMembers ?? classMembers);
+  }
+
+  Declaration findMember(Name name, List<Declaration> declarations) {
+    // TODO(ahe): Consider creating a map or scope. The obvious choice would be
+    // to use scopes, but they don't handle private names correctly.
+
+    // This is a copy of `ClassHierarchy.findMemberByName`.
+    int low = 0, high = declarations.length - 1;
+    while (low <= high) {
+      int mid = low + ((high - low) >> 1);
+      Declaration pivot = declarations[mid];
+      int comparison = ClassHierarchy.compareNames(name, pivot.target.name);
+      if (comparison < 0) {
+        high = mid - 1;
+      } else if (comparison > 0) {
+        low = mid + 1;
+      } else if (high != mid) {
+        // Ensure we find the first element of the given name.
+        high = mid;
+      } else {
+        return pivot;
+      }
+    }
+    return null;
+  }
+
+  Declaration getDispatchTarget(Name name, bool isSetter) {
+    return findMember(name, isSetter ? classSetters : classMembers);
+  }
+
   static int compareMaxInheritancePath(
       ClassHierarchyNode a, ClassHierarchyNode b) {
     return b.maxInheritancePath.compareTo(a.maxInheritancePath);
@@ -996,17 +1848,28 @@
 
 enum MergeKind {
   /// Merging superclass members with the current class.
-  superclass,
+  superclassMembers,
 
-  /// Merging two interfaces.
-  interfaces,
+  /// Merging superclass setters with the current class.
+  superclassSetters,
+
+  /// Merging members of two interfaces.
+  interfacesMembers,
+
+  /// Merging setters of two interfaces.
+  interfacesSetters,
 
   /// Merging class members with interface members.
-  supertypes,
+  supertypesMembers,
 
-  /// Merging members with inherited setters, or setters with inherited
-  /// members.
-  accessors,
+  /// Merging class setters with interface setters.
+  supertypesSetters,
+
+  /// Merging members with inherited setters.
+  membersWithSetters,
+
+  /// Merging setters with inherited members.
+  settersWithMembers,
 }
 
 List<LocatedMessage> inheritedConflictContext(Declaration a, Declaration b) {
@@ -1123,3 +1986,641 @@
     return hierarchy.getKernelLegacyLeastUpperBound(type1, type2);
   }
 }
+
+class DelayedOverrideCheck {
+  final KernelClassBuilder cls;
+  final Declaration a;
+  final Declaration b;
+
+  const DelayedOverrideCheck(this.cls, this.a, this.b);
+
+  void check(ClassHierarchyBuilder hierarchy) {
+    void callback(
+        Member declaredMember, Member interfaceMember, bool isSetter) {
+      cls.checkOverride(
+          hierarchy.types, declaredMember, interfaceMember, isSetter, callback,
+          isInterfaceCheck: !cls.isMixinApplication);
+    }
+
+    Declaration a = this.a;
+    debug?.log(
+        "Delayed override check of ${fullName(a)} ${fullName(b)} wrt. ${cls.fullNameForErrors}");
+    if (cls == a.parent) {
+      if (a is KernelProcedureBuilder) {
+        if (a.isGetter && !hasExplicitReturnType(a)) {
+          DartType type;
+          if (b.isGetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.returnType;
+          } else if (b.isSetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.positionalParameters.single.type;
+          } else if (b.isField) {
+            Field bTarget = b.target;
+            type = bTarget.type;
+          }
+          if (type != null) {
+            type = Substitution.fromInterfaceType(
+                    hierarchy.getKernelTypeAsInstanceOf(
+                        cls.cls.thisType, b.target.enclosingClass))
+                .substituteType(type);
+            if (!a.hadTypesInferred || !b.isSetter) {
+              inferReturnType(cls, a, type, a.hadTypesInferred, hierarchy);
+            }
+          }
+        } else if (a.isSetter && !hasExplicitlyTypedFormalParameter(a, 0)) {
+          DartType type;
+          if (b.isGetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.returnType;
+          } else if (b.isSetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.positionalParameters.single.type;
+          } else if (b.isField) {
+            Field bTarget = b.target;
+            type = bTarget.type;
+          }
+          if (type != null) {
+            type = Substitution.fromInterfaceType(
+                    hierarchy.getKernelTypeAsInstanceOf(
+                        cls.cls.thisType, b.target.enclosingClass))
+                .substituteType(type);
+            if (!a.hadTypesInferred || !b.isGetter) {
+              inferParameterType(cls, a, a.formals.single, type,
+                  a.hadTypesInferred, hierarchy);
+            }
+          }
+        }
+        a.hadTypesInferred = true;
+      } else if (a is KernelFieldBuilder && a.type == null) {
+        DartType type;
+        if (b.isGetter) {
+          Procedure bTarget = b.target;
+          type = bTarget.function.returnType;
+        } else if (b.isSetter) {
+          Procedure bTarget = b.target;
+          type = bTarget.function.positionalParameters.single.type;
+        } else if (b.isField) {
+          Field bTarget = b.target;
+          type = bTarget.type;
+        }
+        if (type != null) {
+          type = Substitution.fromInterfaceType(
+                  hierarchy.getKernelTypeAsInstanceOf(
+                      cls.cls.thisType, b.target.enclosingClass))
+              .substituteType(type);
+          if (type != a.target.type) {
+            if (a.hadTypesInferred) {
+              if (b.isSetter &&
+                  (!impliesSetter(a) ||
+                      hierarchy.types.isSubtypeOfKernel(type, a.target.type))) {
+                type = a.target.type;
+              } else {
+                reportCantInferFieldType(cls, a);
+                type = const InvalidType();
+              }
+            }
+            debug?.log("Inferred type ${type} for ${fullName(a)}");
+            a.target.type = type;
+          }
+        }
+        a.hadTypesInferred = true;
+      }
+    }
+
+    callback(a.target, b.target, a.isSetter);
+  }
+}
+
+abstract class DelayedMember extends Declaration {
+  /// The class which has inherited [declarations].
+  @override
+  final KernelClassBuilder parent;
+
+  /// Conflicting declarations.
+  final List<Declaration> declarations;
+
+  final isSetter;
+
+  final bool modifyKernel;
+
+  DelayedMember(
+      this.parent, this.declarations, this.isSetter, this.modifyKernel);
+
+  void addAllDeclarationsTo(List<Declaration> declarations) {
+    for (int i = 0; i < this.declarations.length; i++) {
+      addDeclarationIfDifferent(this.declarations[i], declarations);
+    }
+    assert(declarations.toSet().length == declarations.length);
+  }
+
+  Member check(ClassHierarchyBuilder hierarchy);
+
+  DelayedMember withParent(KernelClassBuilder parent);
+
+  @override
+  Uri get fileUri => parent.fileUri;
+
+  @override
+  int get charOffset => parent.charOffset;
+
+  @override
+  String get fullNameForErrors => declarations.map(fullName).join("%");
+
+  bool get isInheritableConflict => true;
+
+  @override
+  Member get target => declarations.first.target;
+}
+
+/// This represents a concrete implementation inherited from a superclass that
+/// has conflicts with methods inherited from an interface. The concrete
+/// implementation is the first element of [declarations].
+class InheritedImplementationInterfaceConflict extends DelayedMember {
+  Member combinedMemberSignatureResult;
+
+  @override
+  final bool isInheritableConflict;
+
+  InheritedImplementationInterfaceConflict(KernelClassBuilder parent,
+      List<Declaration> declarations, bool isSetter, bool modifyKernel,
+      {this.isInheritableConflict = true})
+      : super(parent, declarations, isSetter, modifyKernel);
+
+  @override
+  String toString() {
+    return "InheritedImplementationInterfaceConflict("
+        "${parent.fullNameForErrors}, "
+        "[${declarations.map(fullName).join(', ')}])";
+  }
+
+  @override
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (combinedMemberSignatureResult != null) {
+      return combinedMemberSignatureResult;
+    }
+    if (!parent.isAbstract) {
+      Declaration concreteImplementation = declarations.first;
+      for (int i = 1; i < declarations.length; i++) {
+        new DelayedOverrideCheck(
+                parent, concreteImplementation, declarations[i])
+            .check(hierarchy);
+      }
+    }
+    return combinedMemberSignatureResult =
+        new InterfaceConflict(parent, declarations, isSetter, modifyKernel)
+            .check(hierarchy);
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new InheritedImplementationInterfaceConflict(
+            parent, declarations, isSetter, modifyKernel);
+  }
+
+  static Declaration combined(
+      KernelClassBuilder parent,
+      Declaration concreteImplementation,
+      Declaration other,
+      bool isSetter,
+      bool createForwarders,
+      {bool isInheritableConflict = true}) {
+    List<Declaration> declarations = <Declaration>[];
+    if (concreteImplementation is DelayedMember) {
+      concreteImplementation.addAllDeclarationsTo(declarations);
+    } else {
+      declarations.add(concreteImplementation);
+    }
+    if (other is DelayedMember) {
+      other.addAllDeclarationsTo(declarations);
+    } else {
+      addDeclarationIfDifferent(other, declarations);
+    }
+    if (declarations.length == 1) {
+      return declarations.single;
+    } else {
+      return new InheritedImplementationInterfaceConflict(
+          parent, declarations, isSetter, createForwarders,
+          isInheritableConflict: isInheritableConflict);
+    }
+  }
+}
+
+class InterfaceConflict extends DelayedMember {
+  InterfaceConflict(KernelClassBuilder parent, List<Declaration> declarations,
+      bool isSetter, bool modifyKernel)
+      : super(parent, declarations, isSetter, modifyKernel);
+
+  Member combinedMemberSignatureResult;
+
+  @override
+  String toString() {
+    return "InterfaceConflict(${parent.fullNameForErrors}, "
+        "[${declarations.map(fullName).join(', ')}])";
+  }
+
+  DartType computeMemberType(
+      ClassHierarchyBuilder hierarchy, DartType thisType, Member member) {
+    DartType type;
+    if (member is Procedure) {
+      if (member.isGetter) {
+        type = member.getterType;
+      } else if (member.isSetter) {
+        type = member.setterType;
+      } else {
+        type = member.function.functionType;
+      }
+    } else if (member is Field) {
+      type = member.type;
+    } else {
+      unhandled("${member.runtimeType}", "$member", parent.charOffset,
+          parent.fileUri);
+    }
+    return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+            thisType, member.enclosingClass))
+        .substituteType(type);
+  }
+
+  bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
+    if (isSetter) {
+      return hierarchy.types.isSubtypeOfKernel(b, a);
+    } else {
+      return hierarchy.types.isSubtypeOfKernel(a, b);
+    }
+  }
+
+  @override
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (combinedMemberSignatureResult != null) {
+      return combinedMemberSignatureResult;
+    }
+    if (parent.library is! KernelLibraryBuilder) {
+      return combinedMemberSignatureResult = declarations.first.target;
+    }
+    DartType thisType = parent.cls.thisType;
+    Declaration bestSoFar;
+    DartType bestTypeSoFar;
+    for (int i = declarations.length - 1; i >= 0; i--) {
+      Declaration candidate = declarations[i];
+      Member target = candidate.target;
+      DartType candidateType = computeMemberType(hierarchy, thisType, target);
+      if (bestSoFar == null) {
+        bestSoFar = candidate;
+        bestTypeSoFar = candidateType;
+      } else {
+        if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
+          debug?.log(
+              "Combined Member Signature: ${fullName(candidate)} ${candidateType} <: ${fullName(bestSoFar)} ${bestTypeSoFar}");
+          bestSoFar = candidate;
+          bestTypeSoFar = candidateType;
+        } else {
+          debug?.log(
+              "Combined Member Signature: ${fullName(candidate)} !<: ${fullName(bestSoFar)}");
+        }
+      }
+    }
+    if (bestSoFar != null) {
+      debug?.log("Combined Member Signature bestSoFar: ${fullName(bestSoFar)}");
+      for (int i = 0; i < declarations.length; i++) {
+        Declaration candidate = declarations[i];
+        Member target = candidate.target;
+        DartType candidateType = computeMemberType(hierarchy, thisType, target);
+        if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+          debug?.log(
+              "Combined Member Signature: ${fullName(bestSoFar)} !<: ${fullName(candidate)}");
+
+          String uri = '${parent.library.uri}';
+          if (uri == 'dart:js' &&
+                  parent.fileUri.pathSegments.last == 'js_dart2js.dart' ||
+              uri == 'dart:_interceptors' &&
+                  parent.fileUri.pathSegments.last == 'js_number.dart') {
+            // TODO(johnniwinther): Fix the dart2js libraries and remove the
+            // above URIs.
+          } else {
+            bestSoFar = null;
+            bestTypeSoFar = null;
+          }
+          break;
+        }
+      }
+    }
+    if (bestSoFar == null) {
+      String name = parent.fullNameForErrors;
+      int length = parent.isAnonymousMixinApplication ? 1 : name.length;
+      List<LocatedMessage> context = declarations.map((Declaration d) {
+        return messageDeclaredMemberConflictsWithInheritedMemberCause
+            .withLocation(d.fileUri, d.charOffset, d.fullNameForErrors.length);
+      }).toList();
+
+      parent.addProblem(
+          templateCombinedMemberSignatureFailed.withArguments(
+              parent.fullNameForErrors, declarations.first.fullNameForErrors),
+          parent.charOffset,
+          length,
+          context: context);
+      return null;
+    }
+    debug?.log(
+        "Combined Member Signature of ${fullNameForErrors}: ${fullName(bestSoFar)}");
+
+    ProcedureKind kind = ProcedureKind.Method;
+    if (bestSoFar.isField || bestSoFar.isSetter || bestSoFar.isGetter) {
+      kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+    } else if (bestSoFar.target is Procedure &&
+        bestSoFar.target.kind == ProcedureKind.Operator) {
+      kind = ProcedureKind.Operator;
+    }
+
+    if (modifyKernel) {
+      debug?.log(
+          "Combined Member Signature of ${fullNameForErrors}: new ForwardingNode($parent, $bestSoFar, $declarations, $kind)");
+      Member stub =
+          new ForwardingNode(hierarchy, parent, bestSoFar, declarations, kind)
+              .finalize();
+      if (parent.cls == stub.enclosingClass) {
+        parent.cls.addMember(stub);
+        KernelLibraryBuilder library = parent.library;
+        if (bestSoFar.target is Procedure) {
+          library.forwardersOrigins..add(stub)..add(bestSoFar.target);
+        }
+        debug?.log(
+            "Combined Member Signature of ${fullNameForErrors}: added stub $stub");
+        if (parent.isMixinApplication) {
+          return combinedMemberSignatureResult = bestSoFar.target;
+        } else {
+          return combinedMemberSignatureResult = stub;
+        }
+      }
+    }
+
+    debug?.log(
+        "Combined Member Signature of ${fullNameForErrors}: picked bestSoFar");
+    return combinedMemberSignatureResult = bestSoFar.target;
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new InterfaceConflict(parent, declarations, isSetter, modifyKernel);
+  }
+
+  static Declaration combined(KernelClassBuilder parent, Declaration a,
+      Declaration b, bool isSetter, bool createForwarders) {
+    List<Declaration> declarations = <Declaration>[];
+    if (a is DelayedMember) {
+      a.addAllDeclarationsTo(declarations);
+    } else {
+      declarations.add(a);
+    }
+    if (b is DelayedMember) {
+      b.addAllDeclarationsTo(declarations);
+    } else {
+      addDeclarationIfDifferent(b, declarations);
+    }
+    if (declarations.length == 1) {
+      return declarations.single;
+    } else {
+      return new InterfaceConflict(
+          parent, declarations, isSetter, createForwarders);
+    }
+  }
+}
+
+class AbstractMemberOverridingImplementation extends DelayedMember {
+  AbstractMemberOverridingImplementation(
+      KernelClassBuilder parent,
+      Declaration abstractMember,
+      Declaration concreteImplementation,
+      bool isSetter,
+      bool modifyKernel)
+      : super(parent, <Declaration>[concreteImplementation, abstractMember],
+            isSetter, modifyKernel);
+
+  Declaration get concreteImplementation => declarations[0];
+
+  Declaration get abstractMember => declarations[1];
+
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (!parent.isAbstract && !hierarchy.nodes[parent.cls].hasNoSuchMethod) {
+      new DelayedOverrideCheck(parent, concreteImplementation, abstractMember)
+          .check(hierarchy);
+    }
+
+    ProcedureKind kind = ProcedureKind.Method;
+    if (abstractMember.isSetter || abstractMember.isGetter) {
+      kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+    }
+    if (modifyKernel) {
+      // This call will add a body to the abstract method if needed for
+      // isGenericCovariantImpl checks.
+      new ForwardingNode(hierarchy, parent, abstractMember, declarations, kind)
+          .finalize();
+    }
+    return abstractMember.target;
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new AbstractMemberOverridingImplementation(parent, abstractMember,
+            concreteImplementation, isSetter, modifyKernel);
+  }
+
+  static Declaration selectAbstract(Declaration declaration) {
+    if (declaration is AbstractMemberOverridingImplementation) {
+      return declaration.abstractMember;
+    } else {
+      return declaration;
+    }
+  }
+
+  static Declaration selectConcrete(Declaration declaration) {
+    if (declaration is AbstractMemberOverridingImplementation) {
+      return declaration.concreteImplementation;
+    } else {
+      return declaration;
+    }
+  }
+}
+
+void addDeclarationIfDifferent(
+    Declaration declaration, List<Declaration> declarations) {
+  Member target = declaration.target;
+  if (target is Procedure) {
+    FunctionNode function = target.function;
+    for (int i = 0; i < declarations.length; i++) {
+      Member other = declarations[i].target;
+      if (other is Procedure) {
+        if (hasSameSignature(function, other.function)) return;
+      }
+    }
+  } else {
+    for (int i = 0; i < declarations.length; i++) {
+      if (declaration == declarations[i]) return;
+    }
+  }
+  declarations.add(declaration);
+}
+
+String fullName(Declaration declaration) {
+  String suffix = declaration.isSetter ? "=" : "";
+  if (declaration is DelayedMember) {
+    return "${declaration.fullNameForErrors}$suffix";
+  }
+  Declaration parent = declaration.parent;
+  return parent == null
+      ? "${declaration.fullNameForErrors}$suffix"
+      : "${parent.fullNameForErrors}.${declaration.fullNameForErrors}$suffix";
+}
+
+int compareNamedParameters(VariableDeclaration a, VariableDeclaration b) {
+  return a.name.compareTo(b.name);
+}
+
+bool isAbstract(Declaration declaration) {
+  return declaration.target.isAbstract || declaration is InterfaceConflict;
+}
+
+bool inferParameterType(
+    KernelClassBuilder cls,
+    KernelProcedureBuilder member,
+    FormalParameterBuilder<KernelTypeBuilder> parameter,
+    DartType type,
+    bool hadTypesInferred,
+    ClassHierarchyBuilder hierarchy) {
+  debug?.log("Inferred type ${type} for ${parameter}");
+  if (type == parameter.target.type) return true;
+  bool result = true;
+  if (hadTypesInferred) {
+    reportCantInferParameterType(cls, member, parameter, hierarchy);
+    type = const InvalidType();
+    result = false;
+  }
+  parameter.target.type = type;
+  member.hadTypesInferred = true;
+  return result;
+}
+
+void reportCantInferParameterType(
+    KernelClassBuilder cls,
+    MemberBuilder member,
+    FormalParameterBuilder<KernelTypeBuilder> parameter,
+    ClassHierarchyBuilder hierarchy) {
+  String name = parameter.name;
+  cls.addProblem(
+      templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+      parameter.charOffset,
+      name.length,
+      wasHandled: true);
+}
+
+bool inferReturnType(KernelClassBuilder cls, KernelProcedureBuilder member,
+    DartType type, bool hadTypesInferred, ClassHierarchyBuilder hierarchy) {
+  if (type == member.target.function.returnType) return true;
+  bool result = true;
+  if (hadTypesInferred) {
+    reportCantInferReturnType(cls, member, hierarchy);
+    type = const InvalidType();
+    result = false;
+  } else {
+    member.hadTypesInferred = true;
+  }
+  member.target.function.returnType = type;
+  return result;
+}
+
+void reportCantInferReturnType(KernelClassBuilder cls, MemberBuilder member,
+    ClassHierarchyBuilder hierarchy) {
+  String name = member.fullNameForErrors;
+  List<LocatedMessage> context;
+  // // TODO(ahe): The following is for debugging, but could be cleaned up and
+  // // used to improve this error message in general.
+  //
+  // context = <LocatedMessage>[];
+  // ClassHierarchyNode supernode = hierarchy.getNodeFromType(cls.supertype);
+  // // TODO(ahe): Wrong template.
+  // Template<Message Function(String)> template =
+  //     templateMissingImplementationCause;
+  // if (supernode != null) {
+  //   Declaration superMember =
+  //       supernode.getInterfaceMember(new Name(name), false);
+  //   if (superMember != null) {
+  //     context.add(template
+  //         .withArguments(name)
+  //         .withLocation(
+  //             superMember.fileUri, superMember.charOffset, name.length));
+  //   }
+  //   superMember = supernode.getInterfaceMember(new Name(name), true);
+  //   if (superMember != null) {
+  //     context.add(template
+  //         .withArguments(name)
+  //         .withLocation(
+  //             superMember.fileUri, superMember.charOffset, name.length));
+  //   }
+  // }
+  // List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+  // for (int i = 0; i < directInterfaces.length; i++) {
+  //   ClassHierarchyNode supernode =
+  //       hierarchy.getNodeFromType(directInterfaces[i]);
+  //   if (supernode != null) {
+  //     Declaration superMember =
+  //         supernode.getInterfaceMember(new Name(name), false);
+  //     if (superMember != null) {
+  //       context.add(template
+  //           .withArguments(name)
+  //           .withLocation(
+  //               superMember.fileUri, superMember.charOffset, name.length));
+  //     }
+  //     superMember = supernode.getInterfaceMember(new Name(name), true);
+  //     if (superMember != null) {
+  //       context.add(template
+  //           .withArguments(name)
+  //           .withLocation(
+  //               superMember.fileUri, superMember.charOffset, name.length));
+  //     }
+  //   }
+  // }
+  cls.addProblem(
+      templateCantInferReturnTypeDueToInconsistentOverrides.withArguments(name),
+      member.charOffset,
+      name.length,
+      wasHandled: true,
+      context: context);
+}
+
+void reportCantInferFieldType(
+    KernelClassBuilder cls, KernelFieldBuilder member) {
+  String name = member.fullNameForErrors;
+  cls.addProblem(
+      templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+      member.charOffset,
+      name.length,
+      wasHandled: true);
+}
+
+KernelClassBuilder getClass(KernelTypeBuilder type) {
+  Declaration declaration = type.declaration;
+  return declaration is KernelClassBuilder ? declaration : null;
+}
+
+bool hasExplicitReturnType(Declaration declaration) {
+  assert(
+      declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+      "${declaration.runtimeType}");
+  return declaration is KernelProcedureBuilder
+      ? declaration.returnType != null
+      : true;
+}
+
+bool hasExplicitlyTypedFormalParameter(Declaration declaration, int index) {
+  assert(
+      declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+      "${declaration.runtimeType}");
+  return declaration is KernelProcedureBuilder
+      ? declaration.formals[index].type != null
+      : true;
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index d334dac..175f066 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -306,7 +306,12 @@
 
         // If this constant is inlined, remove it.
         if (!keepVariables && shouldInline(node.initializer)) {
-          return null;
+          if (constant is! UnevaluatedConstant) {
+            // If the constant is unevaluated we need to keep the expression,
+            // so that, in the case the constant contains error but the local
+            // is unused, the error will still be reported.
+            return null;
+          }
         }
       } else {
         node.initializer = node.initializer.accept(this)..parent = node;
@@ -933,6 +938,12 @@
         instanceBuilder.setFieldValue(
             fieldRef.asField, _evaluateSubexpression(value));
       });
+      node.unusedArguments.forEach((Expression value) {
+        Constant constant = _evaluateSubexpression(value);
+        if (constant is UnevaluatedConstant) {
+          instanceBuilder.unusedArguments.add(extract(constant));
+        }
+      });
       if (shouldBeUnevaluated) {
         return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
       }
@@ -1133,6 +1144,10 @@
                 '"${init.runtimeType}".');
           }
         }
+
+        for (UnevaluatedConstant constant in env.unevaluatedUnreadConstants) {
+          instanceBuilder.unusedArguments.add(extract(constant));
+        }
       });
     });
   }
@@ -1763,7 +1778,7 @@
     final Constant constant = _evaluateSubexpression(node.operand);
     if (shouldBeUnevaluated) {
       return unevaluated(node,
-          new AsExpression(extract(constant), env.subsituteType(node.type)));
+          new AsExpression(extract(constant), env.substituteType(node.type)));
     }
     return ensureIsSubtype(constant, evaluateDartType(node, node.type), node);
   }
@@ -1808,7 +1823,7 @@
       return unevaluated(
           node,
           new Instantiation(extract(constant),
-              node.typeArguments.map((t) => env.subsituteType(t)).toList()));
+              node.typeArguments.map((t) => env.substituteType(t)).toList()));
     }
     if (constant is TearOffConstant) {
       if (node.typeArguments.length ==
@@ -1927,7 +1942,7 @@
   }
 
   DartType evaluateDartType(TreeNode node, DartType type) {
-    final result = env.subsituteType(type);
+    final result = env.substituteType(type);
 
     if (!isInstantiated(result)) {
       return report(
@@ -2118,6 +2133,8 @@
 
   final List<AssertStatement> asserts = <AssertStatement>[];
 
+  final List<Expression> unusedArguments = <Expression>[];
+
   InstanceBuilder(this.evaluator, this.klass, this.typeArguments);
 
   void setFieldValue(Field field, Constant constant) {
@@ -2131,6 +2148,7 @@
       assert(value is! UnevaluatedConstant);
       fieldValues[field.reference] = value;
     });
+    assert(unusedArguments.isEmpty);
     return new InstanceConstant(klass.reference, typeArguments, fieldValues);
   }
 
@@ -2139,9 +2157,8 @@
     fields.forEach((Field field, Constant value) {
       fieldValues[field.reference] = evaluator.extract(value);
     });
-    // TODO(askesc): Put actual unused arguments.
     return new InstanceCreation(
-        klass.reference, typeArguments, fieldValues, asserts, []);
+        klass.reference, typeArguments, fieldValues, asserts, unusedArguments);
   }
 }
 
@@ -2155,6 +2172,13 @@
   final Map<VariableDeclaration, Constant> _variables =
       <VariableDeclaration, Constant>{};
 
+  /// The variables that hold unevaluated constants.
+  ///
+  /// Variables are removed from this set when looked up, leaving only the
+  /// unread variables at the end.
+  final Set<VariableDeclaration> _unreadUnevaluatedVariables =
+      new Set<VariableDeclaration>();
+
   /// Whether the current environment is empty.
   bool get isEmpty => _typeVariables.isEmpty && _variables.isEmpty;
 
@@ -2165,6 +2189,9 @@
 
   void addVariableValue(VariableDeclaration variable, Constant value) {
     _variables[variable] = value;
+    if (value is UnevaluatedConstant) {
+      _unreadUnevaluatedVariables.add(variable);
+    }
   }
 
   DartType lookupParameterValue(TypeParameter parameter) {
@@ -2174,10 +2201,21 @@
   }
 
   Constant lookupVariable(VariableDeclaration variable) {
-    return _variables[variable];
+    Constant value = _variables[variable];
+    if (value is UnevaluatedConstant) {
+      _unreadUnevaluatedVariables.remove(variable);
+    }
+    return value;
   }
 
-  DartType subsituteType(DartType type) {
+  /// The unevaluated constants of variables that were never read.
+  Iterable<UnevaluatedConstant> get unevaluatedUnreadConstants {
+    if (_unreadUnevaluatedVariables.isEmpty) return const [];
+    return _unreadUnevaluatedVariables.map<UnevaluatedConstant>(
+        (VariableDeclaration variable) => _variables[variable]);
+  }
+
+  DartType substituteType(DartType type) {
     if (_typeVariables.isEmpty) return type;
     return substitute(type, _typeVariables);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
new file mode 100644
index 0000000..441c827
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -0,0 +1,416 @@
+// Copyright (c) 2019, 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:kernel/ast.dart"
+    show
+        Arguments,
+        Class,
+        DartType,
+        Expression,
+        Field,
+        FunctionNode,
+        Member,
+        Name,
+        NamedExpression,
+        Procedure,
+        ProcedureKind,
+        ReturnStatement,
+        SuperMethodInvocation,
+        SuperPropertyGet,
+        SuperPropertySet,
+        TypeParameter,
+        TypeParameterType,
+        VariableDeclaration,
+        VariableGet,
+        VoidType;
+
+import 'package:kernel/transformations/flags.dart' show TransformerFlag;
+
+import "package:kernel/type_algebra.dart" show Substitution;
+
+import "../problems.dart" show unhandled;
+
+import "../type_inference/type_inference_engine.dart"
+    show IncludesTypeParametersCovariantly;
+
+import "../type_inference/type_inferrer.dart" show getNamedFormal;
+
+import "kernel_builder.dart"
+    show ClassHierarchyBuilder, Declaration, DelayedMember, KernelClassBuilder;
+
+class ForwardingNode {
+  final ClassHierarchyBuilder hierarchy;
+
+  final KernelClassBuilder parent;
+
+  final Declaration combinedMemberSignatureResult;
+
+  final ProcedureKind kind;
+
+  /// A list containing the directly implemented and directly inherited
+  /// procedures of the class in question.
+  final List<Declaration> _candidates;
+
+  ForwardingNode(this.hierarchy, this.parent,
+      this.combinedMemberSignatureResult, this._candidates, this.kind);
+
+  Name get name => combinedMemberSignatureResult.target.name;
+
+  Class get enclosingClass => parent.cls;
+
+  /// Finishes handling of this node by propagating covariance and creating
+  /// forwarding stubs if necessary.
+  Member finalize() => _computeCovarianceFixes();
+
+  /// Tag the parameters of [interfaceMember] that need type checks
+  ///
+  /// Parameters can need type checks for calls coming from statically typed
+  /// call sites, due to covariant generics and overrides with explicit
+  /// `covariant` parameters.
+  ///
+  /// Tag parameters of [interfaceMember] that need such checks when the member
+  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
+  /// they would not be checked in an inherited implementation, a forwarding
+  /// stub is introduced as a place to put the checks.
+  Member _computeCovarianceFixes() {
+    Member interfaceMember = combinedMemberSignatureResult.target;
+    Substitution substitution =
+        _substitutionFor(interfaceMember, enclosingClass);
+    // We always create a forwarding stub when we've inherited a member from an
+    // interface other than the first override candidate.  This is to work
+    // around a bug in the Kernel type checker where it chooses the first
+    // override candidate.
+    //
+    // TODO(kmillikin): Fix the Kernel type checker and stop creating these
+    // extra stubs.
+    Member stub = interfaceMember.enclosingClass == enclosingClass ||
+            interfaceMember == getCandidateAt(0)
+        ? interfaceMember
+        : _createForwardingStub(substitution, interfaceMember);
+
+    FunctionNode interfaceFunction = interfaceMember.function;
+    List<VariableDeclaration> interfacePositionalParameters =
+        getPositionalParameters(interfaceMember);
+    List<VariableDeclaration> interfaceNamedParameters =
+        interfaceFunction?.namedParameters ?? [];
+    List<TypeParameter> interfaceTypeParameters =
+        interfaceFunction?.typeParameters ?? [];
+
+    void createStubIfNeeded() {
+      if (stub != interfaceMember) return;
+      if (interfaceMember.enclosingClass == enclosingClass) return;
+      stub = _createForwardingStub(substitution, interfaceMember);
+    }
+
+    bool isImplCreated = false;
+    void createImplIfNeeded() {
+      if (isImplCreated) return;
+      createStubIfNeeded();
+      _createForwardingImplIfNeeded(stub.function);
+      isImplCreated = true;
+    }
+
+    IncludesTypeParametersCovariantly needsCheckVisitor = enclosingClass
+            .typeParameters.isEmpty
+        ? null
+        // TODO(ahe): It may be necessary to cache this object.
+        : new IncludesTypeParametersCovariantly(enclosingClass.typeParameters);
+    bool needsCheck(DartType type) => needsCheckVisitor == null
+        ? false
+        : substitution.substituteType(type).accept(needsCheckVisitor);
+    for (int i = 0; i < interfacePositionalParameters.length; i++) {
+      VariableDeclaration parameter = interfacePositionalParameters[i];
+      bool isGenericCovariantImpl =
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+      bool isCovariant = parameter.isCovariant;
+      VariableDeclaration superParameter = parameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        List<VariableDeclaration> otherPositionalParameters =
+            getPositionalParameters(otherMember);
+        if (otherPositionalParameters.length <= i) continue;
+        VariableDeclaration otherParameter = otherPositionalParameters[i];
+        if (j == 0) superParameter = otherParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+        if (otherParameter.isCovariant) {
+          isCovariant = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isCovariant = true;
+        }
+      }
+    }
+    for (int i = 0; i < interfaceNamedParameters.length; i++) {
+      VariableDeclaration parameter = interfaceNamedParameters[i];
+      bool isGenericCovariantImpl =
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+      bool isCovariant = parameter.isCovariant;
+      VariableDeclaration superParameter = parameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        VariableDeclaration otherParameter =
+            getNamedFormal(otherMember.function, parameter.name);
+        if (otherParameter == null) continue;
+        if (j == 0) superParameter = otherParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+        if (otherParameter.isCovariant) {
+          isCovariant = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isCovariant = true;
+        }
+      }
+    }
+    for (int i = 0; i < interfaceTypeParameters.length; i++) {
+      TypeParameter typeParameter = interfaceTypeParameters[i];
+      bool isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
+          needsCheck(typeParameter.bound);
+      TypeParameter superTypeParameter = typeParameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        List<TypeParameter> otherTypeParameters =
+            otherMember.function.typeParameters;
+        if (otherTypeParameters.length <= i) continue;
+        TypeParameter otherTypeParameter = otherTypeParameters[i];
+        if (j == 0) superTypeParameter = otherTypeParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherTypeParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superTypeParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!typeParameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.typeParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+    }
+    return stub;
+  }
+
+  void _createForwardingImplIfNeeded(FunctionNode function) {
+    if (function.body != null) {
+      // There is already an implementation; nothing further needs to be done.
+      return;
+    }
+    // Find the concrete implementation in the superclass; this is what we need
+    // to forward to.  If we can't find one, then the method is fully abstract
+    // and we don't need to do anything.
+    Class superclass = enclosingClass.superclass;
+    if (superclass == null) return;
+    Procedure procedure = function.parent;
+    Member superTarget = hierarchy.getDispatchTargetKernel(
+        superclass, procedure.name, kind == ProcedureKind.Setter);
+    if (superTarget == null) return;
+    if (superTarget is Procedure && superTarget.isForwardingStub) {
+      superTarget = _getForwardingStubSuperTarget(superTarget);
+    }
+    procedure.isAbstract = false;
+    if (!procedure.isForwardingStub) {
+      // This procedure exists abstractly in the source code; we need to make it
+      // concrete and give it a body that is a forwarding stub.  This situation
+      // is called a "forwarding semi-stub".
+      procedure.isForwardingStub = true;
+      procedure.isForwardingSemiStub = true;
+    }
+    List<Expression> positionalArguments = function.positionalParameters
+        .map<Expression>((parameter) => new VariableGet(parameter))
+        .toList();
+    List<NamedExpression> namedArguments = function.namedParameters
+        .map((parameter) =>
+            new NamedExpression(parameter.name, new VariableGet(parameter)))
+        .toList();
+    List<DartType> typeArguments = function.typeParameters
+        .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
+        .toList();
+    Arguments arguments = new Arguments(positionalArguments,
+        types: typeArguments, named: namedArguments);
+    Expression superCall;
+    switch (kind) {
+      case ProcedureKind.Method:
+      case ProcedureKind.Operator:
+        superCall = new SuperMethodInvocation(name, arguments, superTarget);
+        break;
+      case ProcedureKind.Getter:
+        superCall = new SuperPropertyGet(name, superTarget);
+        break;
+      case ProcedureKind.Setter:
+        superCall =
+            new SuperPropertySet(name, positionalArguments[0], superTarget);
+        break;
+      default:
+        unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
+        break;
+    }
+    function.body = new ReturnStatement(superCall)..parent = function;
+    procedure.transformerFlags |= TransformerFlag.superCalls;
+    procedure.forwardingStubSuperTarget = superTarget;
+  }
+
+  /// Creates a forwarding stub based on the given [target].
+  Procedure _createForwardingStub(Substitution substitution, Member target) {
+    VariableDeclaration copyParameter(VariableDeclaration parameter) {
+      return new VariableDeclaration(parameter.name,
+          type: substitution.substituteType(parameter.type),
+          isCovariant: parameter.isCovariant)
+        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
+    }
+
+    List<TypeParameter> targetTypeParameters =
+        target.function?.typeParameters ?? [];
+    List<TypeParameter> typeParameters;
+    if (targetTypeParameters.isNotEmpty) {
+      typeParameters =
+          new List<TypeParameter>.filled(targetTypeParameters.length, null);
+      Map<TypeParameter, DartType> additionalSubstitution =
+          <TypeParameter, DartType>{};
+      for (int i = 0; i < targetTypeParameters.length; i++) {
+        TypeParameter targetTypeParameter = targetTypeParameters[i];
+        TypeParameter typeParameter = new TypeParameter(
+            targetTypeParameter.name, null)
+          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
+        typeParameters[i] = typeParameter;
+        additionalSubstitution[targetTypeParameter] =
+            new TypeParameterType(typeParameter);
+      }
+      substitution = Substitution.combine(
+          substitution, Substitution.fromMap(additionalSubstitution));
+      for (int i = 0; i < typeParameters.length; i++) {
+        typeParameters[i].bound =
+            substitution.substituteType(targetTypeParameters[i].bound);
+      }
+    }
+    List<VariableDeclaration> positionalParameters =
+        getPositionalParameters(target).map(copyParameter).toList();
+    List<VariableDeclaration> namedParameters =
+        target.function?.namedParameters?.map(copyParameter)?.toList() ?? [];
+    FunctionNode function = new FunctionNode(null,
+        positionalParameters: positionalParameters,
+        namedParameters: namedParameters,
+        typeParameters: typeParameters,
+        requiredParameterCount: getRequiredParameterCount(target),
+        returnType: substitution.substituteType(getReturnType(target)));
+    Member finalTarget;
+    if (target is Procedure && target.isForwardingStub) {
+      finalTarget = target.forwardingStubInterfaceTarget;
+    } else {
+      finalTarget = target;
+    }
+    return new Procedure(name, kind, function,
+        isAbstract: true,
+        isForwardingStub: true,
+        fileUri: enclosingClass.fileUri,
+        forwardingStubInterfaceTarget: finalTarget)
+      ..startFileOffset = enclosingClass.fileOffset
+      ..fileOffset = enclosingClass.fileOffset
+      ..parent = enclosingClass;
+  }
+
+  /// Returns the [i]th element of [_candidates], finalizing it if necessary.
+  Member getCandidateAt(int i) {
+    Declaration candidate = _candidates[i];
+    assert(candidate is! DelayedMember);
+    return candidate.target;
+  }
+
+  static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
+    // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
+    // easier.
+    ReturnStatement body = forwardingStub.function.body;
+    Expression expression = body.expression;
+    if (expression is SuperMethodInvocation) {
+      return expression.interfaceTarget;
+    } else if (expression is SuperPropertySet) {
+      return expression.interfaceTarget;
+    } else {
+      return unhandled('${expression.runtimeType}',
+          '_getForwardingStubSuperTarget', -1, null);
+    }
+  }
+
+  Substitution _substitutionFor(Member candidate, Class class_) {
+    return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+        class_.thisType, candidate.enclosingClass));
+  }
+
+  List<VariableDeclaration> getPositionalParameters(Member member) {
+    if (member is Field) {
+      if (kind == ProcedureKind.Setter) {
+        return <VariableDeclaration>[
+          new VariableDeclaration("_",
+              type: member.type, isCovariant: member.isCovariant)
+            ..isGenericCovariantImpl = member.isGenericCovariantImpl
+        ];
+      } else {
+        return <VariableDeclaration>[];
+      }
+    } else {
+      return member.function.positionalParameters;
+    }
+  }
+
+  int getRequiredParameterCount(Member member) {
+    switch (kind) {
+      case ProcedureKind.Getter:
+        return 0;
+      case ProcedureKind.Setter:
+        return 1;
+      default:
+        return member.function.requiredParameterCount;
+    }
+  }
+
+  DartType getReturnType(Member member) {
+    switch (kind) {
+      case ProcedureKind.Getter:
+        return member is Field ? member.type : member.function.returnType;
+      case ProcedureKind.Setter:
+        return const VoidType();
+      default:
+        return member.function.returnType;
+    }
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index c82886b..1074242 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -16,6 +16,10 @@
 class ImplicitFieldType extends DartType {
   final MemberBuilder member;
   Token initializerToken;
+  bool isStarted = false;
+
+  get nullability =>
+      unsupported("nullability", member.charOffset, member.fileUri);
 
   ImplicitFieldType(this.member, this.initializerToken);
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 7195bac..2a35783 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -7,7 +7,7 @@
 import 'package:kernel/ast.dart'
     show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
 
-import '../problems.dart' show unhandled;
+import '../problems.dart' show unhandled, unsupported;
 
 /// Marker type used as type argument on list, set and map literals whenever
 /// type arguments are omitted in the source.
@@ -18,6 +18,9 @@
   const ImplicitTypeArgument();
 
   @override
+  get nullability => unsupported("nullability", -1, null);
+
+  @override
   accept(DartTypeVisitor<Object> v) {
     unhandled("$runtimeType", "${v.runtimeType}", -1, null);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
index 278e742..dedf5ae 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -47,14 +47,13 @@
       KernelClassBuilder classBuilder,
       ModifierBuilder member,
       Scope scope,
-      Scope parameterScope,
       Uri fileUri)
       : forest = const Fangorn(),
         super(
             library,
             member,
             scope,
-            parameterScope,
+            null,
             library.loader.hierarchy,
             library.loader.coreTypes,
             classBuilder,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
index 0206595..146b7b2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
@@ -16,7 +16,8 @@
 
 export '../builder/builder.dart';
 
-export 'class_hierarchy_builder.dart' show ClassHierarchyBuilder;
+export 'class_hierarchy_builder.dart'
+    show ClassHierarchyBuilder, DelayedMember, DelayedOverrideCheck;
 
 export 'implicit_field_type.dart' show ImplicitFieldType;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index b36770c..cb9eaf8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -123,6 +123,8 @@
 
 import 'kernel_target.dart' show KernelTarget;
 
+import 'types.dart' show Types;
+
 abstract class KernelClassBuilder
     extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
   KernelClassBuilder actualOrigin;
@@ -233,7 +235,7 @@
     }
 
     KernelMetadataBuilder.buildAnnotations(
-        isPatch ? origin.target : cls, metadata, library, this, null, null);
+        isPatch ? origin.target : cls, metadata, library, this, null);
     constructors.forEach(build);
     scope.forEach(build);
   }
@@ -538,7 +540,7 @@
   }
 
   void handleSeenCovariant(
-      ClassHierarchy hierarchy,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       bool isSetter,
@@ -546,9 +548,8 @@
     // When a parameter is covariant we have to check that we also
     // override the same member in all parents.
     for (Supertype supertype in interfaceMember.enclosingClass.supers) {
-      Member m = hierarchy.getInterfaceMember(
-          supertype.classNode, interfaceMember.name,
-          setter: isSetter);
+      Member m = types.hierarchy.getInterfaceMemberKernel(
+          supertype.classNode, interfaceMember.name, isSetter);
       if (m != null) {
         callback(declaredMember, m, isSetter);
       }
@@ -556,8 +557,7 @@
   }
 
   void checkOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       bool isSetter,
@@ -573,25 +573,25 @@
     if (declaredMember is Procedure && interfaceMember is Procedure) {
       if (declaredMember.kind == ProcedureKind.Method &&
           interfaceMember.kind == ProcedureKind.Method) {
-        bool seenCovariant = checkMethodOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        bool seenCovariant = checkMethodOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
       if (declaredMember.kind == ProcedureKind.Getter &&
           interfaceMember.kind == ProcedureKind.Getter) {
-        checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
-            interfaceMember, isInterfaceCheck);
+        checkGetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
       }
       if (declaredMember.kind == ProcedureKind.Setter &&
           interfaceMember.kind == ProcedureKind.Setter) {
-        bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        bool seenCovariant = checkSetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
     } else {
@@ -599,19 +599,24 @@
           declaredMember is Procedure && declaredMember.isGetter;
       bool interfaceMemberHasGetter = interfaceMember is Field ||
           interfaceMember is Procedure && interfaceMember.isGetter;
-      bool declaredMemberHasSetter = declaredMember is Field ||
+      bool declaredMemberHasSetter = (declaredMember is Field &&
+              !declaredMember.isFinal &&
+              !declaredMember.isConst) ||
           declaredMember is Procedure && declaredMember.isSetter;
-      bool interfaceMemberHasSetter = interfaceMember is Field ||
+      bool interfaceMemberHasSetter = (interfaceMember is Field &&
+              !interfaceMember.isFinal &&
+              !interfaceMember.isConst) ||
           interfaceMember is Procedure && interfaceMember.isSetter;
       if (declaredMemberHasGetter && interfaceMemberHasGetter) {
-        checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
-            interfaceMember, isInterfaceCheck);
-      } else if (declaredMemberHasSetter && interfaceMemberHasSetter) {
-        bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        checkGetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
+      }
+      if (declaredMemberHasSetter && interfaceMemberHasSetter) {
+        bool seenCovariant = checkSetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
     }
@@ -619,85 +624,10 @@
   }
 
   void checkOverrides(
-      ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
-    void overridePairCallback(
-        Member declaredMember, Member interfaceMember, bool isSetter) {
-      checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
-          isSetter, overridePairCallback);
-    }
-
-    hierarchy.forEachOverridePair(cls, overridePairCallback);
-  }
+      ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {}
 
   void checkAbstractMembers(CoreTypes coreTypes, ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment) {
-    // TODO(ahe): Move this to [ClassHierarchyBuilder].
-    if (isAbstract) {
-      // Unimplemented members allowed
-      return;
-    }
-
-    bool mustHaveImplementation(Member member) {
-      // Public member
-      if (!member.name.isPrivate) return true;
-      // Private member in different library
-      if (member.enclosingLibrary != cls.enclosingLibrary) return false;
-      // Private member in patch
-      if (member.fileUri != member.enclosingClass.fileUri) return false;
-      // Private member in same library
-      return true;
-    }
-
-    void overridePairCallback(
-        Member declaredMember, Member interfaceMember, bool isSetter) {
-      checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
-          isSetter, overridePairCallback,
-          isInterfaceCheck: true);
-    }
-
-    void findMissingImplementations({bool setters}) {
-      List<Member> dispatchTargets =
-          hierarchy.getDispatchTargets(cls, setters: setters);
-      int targetIndex = 0;
-      for (Member interfaceMember
-          in hierarchy.getInterfaceMembers(cls, setters: setters)) {
-        if (mustHaveImplementation(interfaceMember)) {
-          while (targetIndex < dispatchTargets.length &&
-              ClassHierarchy.compareMembers(
-                      dispatchTargets[targetIndex], interfaceMember) <
-                  0) {
-            targetIndex++;
-          }
-          bool foundTarget = targetIndex < dispatchTargets.length &&
-              ClassHierarchy.compareMembers(
-                      dispatchTargets[targetIndex], interfaceMember) <=
-                  0;
-          if (foundTarget) {
-            Member dispatchTarget = dispatchTargets[targetIndex];
-            while (dispatchTarget is Procedure &&
-                !dispatchTarget.isExternal &&
-                dispatchTarget.forwardingStubSuperTarget != null) {
-              dispatchTarget =
-                  (dispatchTarget as Procedure).forwardingStubSuperTarget;
-            }
-            while (interfaceMember is Procedure &&
-                !interfaceMember.isExternal &&
-                interfaceMember.forwardingStubInterfaceTarget != null) {
-              interfaceMember =
-                  (interfaceMember as Procedure).forwardingStubInterfaceTarget;
-            }
-            if (!hierarchy.isSubtypeOf(dispatchTarget.enclosingClass,
-                interfaceMember.enclosingClass)) {
-              overridePairCallback(dispatchTarget, interfaceMember, setters);
-            }
-          }
-        }
-      }
-    }
-
-    findMissingImplementations(setters: false);
-    findMissingImplementations(setters: true);
-  }
+      TypeEnvironment typeEnvironment) {}
 
   bool hasUserDefinedNoSuchMethod(
       Class klass, ClassHierarchy hierarchy, Class objectClass) {
@@ -924,7 +854,7 @@
   }
 
   Substitution _computeInterfaceSubstitution(
-      ClassHierarchy hierarchy,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       FunctionNode declaredFunction,
@@ -932,8 +862,9 @@
       bool isInterfaceCheck) {
     Substitution interfaceSubstitution = Substitution.empty;
     if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
-      interfaceSubstitution = Substitution.fromSupertype(
-          hierarchy.getClassAsInstanceOf(cls, interfaceMember.enclosingClass));
+      interfaceSubstitution = Substitution.fromInterfaceType(types.hierarchy
+          .getKernelTypeAsInstanceOf(
+              cls.thisType, interfaceMember.enclosingClass));
     }
     if (declaredFunction?.typeParameters?.length !=
         interfaceFunction?.typeParameters?.length) {
@@ -1000,17 +931,18 @@
   }
 
   Substitution _computeDeclaredSubstitution(
-      ClassHierarchy hierarchy, Member declaredMember) {
+      Types types, Member declaredMember) {
     Substitution declaredSubstitution = Substitution.empty;
     if (declaredMember.enclosingClass.typeParameters.isNotEmpty) {
-      declaredSubstitution = Substitution.fromSupertype(
-          hierarchy.getClassAsInstanceOf(cls, declaredMember.enclosingClass));
+      declaredSubstitution = Substitution.fromInterfaceType(types.hierarchy
+          .getKernelTypeAsInstanceOf(
+              cls.thisType, declaredMember.enclosingClass));
     }
     return declaredSubstitution;
   }
 
-  bool _checkTypes(
-      TypeEnvironment typeEnvironment,
+  void _checkTypes(
+      Types types,
       Substitution interfaceSubstitution,
       Substitution declaredSubstitution,
       Member declaredMember,
@@ -1021,7 +953,7 @@
       VariableDeclaration declaredParameter,
       bool isInterfaceCheck,
       {bool asIfDeclaredParameter = false}) {
-    if (library.loader.target.backendTarget.legacyMode) return false;
+    if (library.loader.target.backendTarget.legacyMode) return;
 
     if (interfaceSubstitution != null) {
       interfaceType = interfaceSubstitution.substituteType(interfaceType);
@@ -1034,9 +966,9 @@
     DartType subtype = inParameter ? interfaceType : declaredType;
     DartType supertype = inParameter ? declaredType : interfaceType;
 
-    if (typeEnvironment.isSubtypeOf(subtype, supertype)) {
+    if (types.isSubtypeOfKernel(subtype, supertype)) {
       // No problem--the proper subtyping relation is satisfied.
-    } else if (isCovariant && typeEnvironment.isSubtypeOf(supertype, subtype)) {
+    } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
       // No problem--the overriding parameter is marked "covariant" and has
       // a type which is a subtype of the parameter it overrides.
     } else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1074,19 +1006,13 @@
                         interfaceMember.fileOffset, noLength)
               ] +
               inheritedContext(isInterfaceCheck, declaredMember));
-      return true;
     }
-    return false;
   }
 
   /// Returns whether a covariant parameter was seen and more methods thus have
   /// to be checked.
-  bool checkMethodOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Procedure declaredMember,
-      Procedure interfaceMember,
-      bool isInterfaceCheck) {
+  bool checkMethodOverride(Types types, Procedure declaredMember,
+      Procedure interfaceMember, bool isInterfaceCheck) {
     assert(declaredMember.kind == ProcedureKind.Method);
     assert(interfaceMember.kind == ProcedureKind.Method);
     bool seenCovariant = false;
@@ -1094,7 +1020,7 @@
     FunctionNode interfaceFunction = interfaceMember.function;
 
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
+        types,
         declaredMember,
         interfaceMember,
         declaredFunction,
@@ -1102,10 +1028,10 @@
         isInterfaceCheck);
 
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
 
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
@@ -1160,7 +1086,7 @@
       var declaredParameter = declaredFunction.positionalParameters[i];
       var interfaceParameter = interfaceFunction.positionalParameters[i];
       _checkTypes(
-          typeEnvironment,
+          types,
           interfaceSubstitution,
           declaredSubstitution,
           declaredMember,
@@ -1237,7 +1163,7 @@
       }
       var declaredParameter = declaredNamedParameters.current;
       _checkTypes(
-          typeEnvironment,
+          types,
           interfaceSubstitution,
           declaredSubstitution,
           declaredMember,
@@ -1252,25 +1178,16 @@
     return seenCovariant;
   }
 
-  void checkGetterOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Member declaredMember,
-      Member interfaceMember,
-      bool isInterfaceCheck) {
+  void checkGetterOverride(Types types, Member declaredMember,
+      Member interfaceMember, bool isInterfaceCheck) {
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
-        declaredMember,
-        interfaceMember,
-        null,
-        null,
-        isInterfaceCheck);
+        types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
     var declaredType = declaredMember.getterType;
     var interfaceType = interfaceMember.getterType;
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
@@ -1284,29 +1201,25 @@
 
   /// Returns whether a covariant parameter was seen and more methods thus have
   /// to be checked.
-  bool checkSetterOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Member declaredMember,
-      Member interfaceMember,
-      bool isInterfaceCheck) {
+  bool checkSetterOverride(Types types, Member declaredMember,
+      Member interfaceMember, bool isInterfaceCheck) {
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
-        declaredMember,
-        interfaceMember,
-        null,
-        null,
-        isInterfaceCheck);
+        types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
     var declaredType = declaredMember.setterType;
     var interfaceType = interfaceMember.setterType;
     var declaredParameter =
         declaredMember.function?.positionalParameters?.elementAt(0);
     bool isCovariant = declaredParameter?.isCovariant ?? false;
-    if (declaredMember is Field) isCovariant = declaredMember.isCovariant;
+    if (!isCovariant && declaredMember is Field) {
+      isCovariant = declaredMember.isCovariant;
+    }
+    if (!isCovariant && interfaceMember is Field) {
+      isCovariant = interfaceMember.isCovariant;
+    }
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 484c95e..8ee7d22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -25,8 +25,6 @@
         ThisExpression,
         VariableGet;
 
-import 'kernel_shadow_ast.dart' show ShadowClass;
-
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -85,7 +83,7 @@
       String name,
       Scope scope,
       Scope constructors,
-      ShadowClass cls,
+      Class cls,
       this.enumConstantInfos,
       this.intType,
       this.listType,
@@ -115,7 +113,7 @@
     KernelTypeBuilder stringType = new KernelNamedTypeBuilder("String", null);
     KernelNamedTypeBuilder objectType =
         new KernelNamedTypeBuilder("Object", null);
-    ShadowClass cls = new ShadowClass(name: name);
+    Class cls = new Class(name: name);
     Map<String, MemberBuilder> members = <String, MemberBuilder>{};
     Map<String, MemberBuilder> constructors = <String, MemberBuilder>{};
     KernelNamedTypeBuilder selfType = new KernelNamedTypeBuilder(name, null);
@@ -255,7 +253,6 @@
     members.forEach(setParent);
     constructors.forEach(setParent);
     selfType.bind(enumBuilder);
-    ShadowClass.setBuilder(cls, enumBuilder);
     return enumBuilder;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index 88a91b4..3a22dbb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -5,13 +5,16 @@
 library fasta.kernel_field_builder;
 
 import 'package:kernel/ast.dart'
-    show Class, DartType, DynamicType, Expression, Field, Name, NullLiteral;
+    show Class, DartType, Expression, Field, InvalidType, Name, NullLiteral;
 
 import '../constant_context.dart' show ConstantContext;
 
-import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
+import '../fasta_codes.dart'
+    show
+        messageInternalProblemAlreadyInitialized,
+        templateCantInferTypeDueToCircularity;
 
-import '../problems.dart' show internalProblem, unsupported;
+import '../problems.dart' show internalProblem;
 
 import '../scanner.dart' show Token;
 
@@ -22,6 +25,10 @@
 import '../type_inference/type_inference_engine.dart'
     show IncludesTypeParametersCovariantly;
 
+import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
 import 'kernel_body_builder.dart' show KernelBodyBuilder;
 
 import 'kernel_builder.dart'
@@ -36,18 +43,17 @@
         LibraryBuilder,
         MetadataBuilder;
 
-import 'kernel_shadow_ast.dart' show ShadowField;
-
 class KernelFieldBuilder extends FieldBuilder<Expression> {
-  final ShadowField field;
+  final Field field;
   final List<MetadataBuilder> metadata;
   final KernelTypeBuilder type;
   Token constInitializerToken;
 
+  bool hadTypesInferred = false;
+
   KernelFieldBuilder(this.metadata, this.type, String name, int modifiers,
       Declaration compilationUnit, int charOffset, int charEndOffset)
-      : field = new ShadowField(null, type == null,
-            fileUri: compilationUnit?.fileUri)
+      : field = new Field(null, fileUri: compilationUnit?.fileUri)
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset,
         super(name, modifiers, compilationUnit, charOffset);
@@ -95,10 +101,6 @@
       ..hasImplicitGetter = isInstanceMember
       ..hasImplicitSetter = isInstanceMember && !isConst && !isFinal
       ..isStatic = !isInstanceMember;
-    if (isEligibleForInference && !isInstanceMember) {
-      library.loader.typeInferenceEngine
-          .recordStaticFieldInferenceCandidate(field, library);
-    }
     return field;
   }
 
@@ -106,12 +108,12 @@
   void buildOutlineExpressions(LibraryBuilder library) {
     ClassBuilder classBuilder = isClassMember ? parent : null;
     KernelMetadataBuilder.buildAnnotations(
-        field, metadata, library, classBuilder, this, null);
+        field, metadata, library, classBuilder, this);
     if (constInitializerToken != null) {
       Scope scope = classBuilder?.scope ?? library.scope;
       KernelBodyBuilder bodyBuilder =
           new KernelBodyBuilder.forOutlineExpression(
-              library, classBuilder, this, scope, null, fileUri);
+              library, classBuilder, this, scope, fileUri);
       bodyBuilder.constantContext =
           isConst ? ConstantContext.inferred : ConstantContext.none;
       initializer = bodyBuilder.parseFieldInitializer(constInitializerToken)
@@ -130,27 +132,75 @@
 
   Field get target => field;
 
-  void prepareTopLevelInference() {
-    if (!isEligibleForInference) return;
+  @override
+  void inferType() {
     KernelLibraryBuilder library = this.library;
-    var typeInferrer = library.loader.typeInferenceEngine
-        .createTopLevelTypeInferrer(
-            field.enclosingClass?.thisType, field, null);
-    if (hasInitializer) {
-      if (field.type is! ImplicitFieldType) {
-        unsupported(
-            "$name has unexpected type ${field.type}", charOffset, fileUri);
-        return;
-      }
-      ImplicitFieldType type = field.type;
-      field.type = const DynamicType();
-      KernelBodyBuilder bodyBuilder =
-          new KernelBodyBuilder.forField(this, typeInferrer);
-      bodyBuilder.constantContext =
-          isConst ? ConstantContext.inferred : ConstantContext.none;
-      initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
-      type.initializerToken = null;
+    if (field.type is! ImplicitFieldType) {
+      // We have already inferred a type.
+      return;
     }
+    ImplicitFieldType type = field.type;
+    if (type.member != this) {
+      // The implicit type was inherited.
+      KernelFieldBuilder other = type.member;
+      other.inferCopiedType(field);
+      return;
+    }
+    if (type.isStarted) {
+      library.addProblem(
+          templateCantInferTypeDueToCircularity.withArguments(name),
+          charOffset,
+          name.length,
+          fileUri);
+      field.type = const InvalidType();
+      return;
+    }
+    type.isStarted = true;
+    TypeInferrerImpl typeInferrer = library.loader.typeInferenceEngine
+        .createTopLevelTypeInferrer(
+            fileUri, field.enclosingClass?.thisType, null);
+    KernelBodyBuilder bodyBuilder =
+        new KernelBodyBuilder.forField(this, typeInferrer);
+    bodyBuilder.constantContext =
+        isConst ? ConstantContext.inferred : ConstantContext.none;
+    initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
+    type.initializerToken = null;
+
+    DartType inferredType = typeInferrer.inferDeclarationType(typeInferrer
+        .inferExpression(field.initializer, const UnknownType(), true,
+            isVoidAllowed: true));
+
+    if (field.type is ImplicitFieldType) {
+      // `field.type` may have changed if a circularity was detected when
+      // [inferredType] was computed.
+      field.type = inferredType;
+
+      IncludesTypeParametersCovariantly needsCheckVisitor;
+      if (parent is ClassBuilder) {
+        Class enclosingClass = parent.target;
+        if (enclosingClass.typeParameters.isNotEmpty) {
+          needsCheckVisitor = new IncludesTypeParametersCovariantly(
+              enclosingClass.typeParameters);
+        }
+      }
+      if (needsCheckVisitor != null) {
+        if (field.type.accept(needsCheckVisitor)) {
+          field.isGenericCovariantImpl = true;
+        }
+      }
+    }
+
+    // The following is a hack. The outline should contain the compiled
+    // initializers, however, as top-level inference is subtly different from
+    // we need to compile the field initializer again when everything else is
+    // compiled.
+    field.initializer = null;
+  }
+
+  void inferCopiedType(Field other) {
+    inferType();
+    other.type = field.type;
+    other.initializer = null;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 91a846a..06303d6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -103,6 +103,8 @@
         namedMixinApplicationMask,
         staticMask;
 
+import '../names.dart' show indexSetName;
+
 import '../problems.dart' show unexpected, unhandled;
 
 import '../severity.dart' show Severity;
@@ -203,6 +205,8 @@
 
   List<KernelFormalParameterBuilder> untypedInitializingFormals;
 
+  List<KernelFieldBuilder> implicitlyTypedFields;
+
   KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
       [Scope scope, Library target])
       : library = target ??
@@ -648,6 +652,7 @@
     addBuilder(name, field, charOffset);
     if (!legacyMode && type == null && initializerToken != null) {
       field.target.type = new ImplicitFieldType(field, initializerToken);
+      (implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(field);
     }
     loader.target.metadataCollector
         ?.setDocumentationComment(field.target, documentationComment);
@@ -666,9 +671,10 @@
       int charOffset,
       int charOpenParenOffset,
       int charEndOffset,
-      String nativeMethodName) {
+      String nativeMethodName,
+      {Token beginInitializers}) {
     MetadataCollector metadataCollector = loader.target.metadataCollector;
-    ProcedureBuilder procedure = new KernelConstructorBuilder(
+    KernelConstructorBuilder procedure = new KernelConstructorBuilder(
         metadata,
         modifiers & ~abstractMask,
         returnType,
@@ -694,7 +700,12 @@
     if (nativeMethodName != null) {
       addNativeMethod(procedure);
     }
-    if (procedure.isConst) currentDeclaration?.hasConstConstructor = true;
+    if (procedure.isConst) {
+      currentDeclaration?.hasConstConstructor = true;
+      // const constructors will have their initializers compiled and written
+      // into the outline.
+      procedure.beginInitializers = beginInitializers;
+    }
   }
 
   void addProcedure(
@@ -713,6 +724,14 @@
       String nativeMethodName,
       {bool isTopLevel}) {
     MetadataCollector metadataCollector = loader.target.metadataCollector;
+    if (returnType == null) {
+      if (kind == ProcedureKind.Operator &&
+          identical(name, indexSetName.name)) {
+        returnType = addVoidType(charOffset);
+      } else if (kind == ProcedureKind.Setter) {
+        returnType = addVoidType(charOffset);
+      }
+    }
     ProcedureBuilder procedure = new KernelProcedureBuilder(
         metadata,
         modifiers,
@@ -904,8 +923,7 @@
 
   @override
   void buildOutlineExpressions() {
-    KernelMetadataBuilder.buildAnnotations(
-        library, metadata, this, null, null, null);
+    KernelMetadataBuilder.buildAnnotations(library, metadata, this, null, null);
   }
 
   @override
@@ -1361,9 +1379,9 @@
   }
 
   @override
-  void includePart(
+  bool includePart(
       covariant KernelLibraryBuilder part, Set<Uri> usedParts, int partOffset) {
-    super.includePart(part, usedParts, partOffset);
+    if (!super.includePart(part, usedParts, partOffset)) return false;
     nativeMethods.addAll(part.nativeMethods);
     boundlessTypeVariables.addAll(part.boundlessTypeVariables);
     // Check that the targets are different. This is not normally a problem
@@ -1372,6 +1390,16 @@
       target.problemsAsJson ??= <String>[];
       target.problemsAsJson.addAll(part.target.problemsAsJson);
     }
+    List<KernelFieldBuilder> partImplicitlyTypedFields =
+        part.takeImplicitlyTypedFields();
+    if (partImplicitlyTypedFields != null) {
+      if (implicitlyTypedFields == null) {
+        implicitlyTypedFields = partImplicitlyTypedFields;
+      } else {
+        implicitlyTypedFields.addAll(partImplicitlyTypedFields);
+      }
+    }
+    return true;
   }
 
   @override
@@ -1827,6 +1855,13 @@
     untypedInitializingFormals = null;
     return count;
   }
+
+  @override
+  List<KernelFieldBuilder> takeImplicitlyTypedFields() {
+    List<KernelFieldBuilder> result = implicitlyTypedFields;
+    implicitlyTypedFields = null;
+    return result;
+  }
 }
 
 Uri computeLibraryUri(Declaration declaration) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
index 1c9f1f0..81970a0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_metadata_builder.dart
@@ -31,15 +31,14 @@
       List<MetadataBuilder> metadata,
       KernelLibraryBuilder library,
       KernelClassBuilder classBuilder,
-      MemberBuilder member,
-      Scope parameterScope) {
+      MemberBuilder member) {
     if (metadata == null) return;
     Uri fileUri = member?.fileUri ?? classBuilder?.fileUri ?? library.fileUri;
     Scope scope = parent is Library || parent is Class || classBuilder == null
         ? library.scope
         : classBuilder.scope;
     KernelBodyBuilder bodyBuilder = new KernelBodyBuilder.forOutlineExpression(
-        library, classBuilder, member, scope, parameterScope, fileUri);
+        library, classBuilder, member, scope, fileUri);
     for (int i = 0; i < metadata.length; ++i) {
       KernelMetadataBuilder annotationBuilder = metadata[i];
       parent.addAnnotation(
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index 0e9e42e..8d0df44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -30,11 +30,12 @@
         TypeParameter,
         TypeParameterType,
         VariableDeclaration,
-        VoidType,
         setParents;
 
 import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
 
+import '../../scanner/token.dart' show Token;
+
 import '../loader.dart' show Loader;
 
 import '../messages.dart'
@@ -74,8 +75,7 @@
         TypeVariableBuilder,
         isRedirectingGenerativeConstructorImplementation;
 
-import 'kernel_shadow_ast.dart'
-    show ShadowProcedure, VariableDeclarationJudgment;
+import 'kernel_shadow_ast.dart' show VariableDeclarationJudgment;
 
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
 
@@ -275,7 +275,7 @@
 }
 
 class KernelProcedureBuilder extends KernelFunctionBuilder {
-  final ShadowProcedure procedure;
+  final Procedure procedure;
   final int charOpenParenOffset;
 
   AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
@@ -283,6 +283,8 @@
   @override
   KernelProcedureBuilder actualOrigin;
 
+  bool hadTypesInferred = false;
+
   KernelProcedureBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -297,11 +299,11 @@
       this.charOpenParenOffset,
       int charEndOffset,
       [String nativeMethodName])
-      : procedure = new ShadowProcedure(null, kind, null, returnType == null,
-            fileUri: compilationUnit?.fileUri)
-          ..startFileOffset = startCharOffset
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset,
+      : procedure =
+            new Procedure(null, kind, null, fileUri: compilationUnit?.fileUri)
+              ..startFileOffset = startCharOffset
+              ..fileOffset = charOffset
+              ..fileEndOffset = charEndOffset,
         super(metadata, modifiers, returnType, name, typeVariables, formals,
             compilationUnit, charOffset, nativeMethodName);
 
@@ -354,24 +356,13 @@
       procedure.isConst = isConst;
       procedure.name = new Name(name, library.target);
     }
-    if (!library.loader.target.legacyMode &&
-        (isSetter || (isOperator && name == '[]=')) &&
-        returnType == null) {
-      procedure.function.returnType = const VoidType();
-    }
     return procedure;
   }
 
   @override
   void buildOutlineExpressions(LibraryBuilder library) {
-    ClassBuilder classBuilder = isClassMember ? parent : null;
     KernelMetadataBuilder.buildAnnotations(
-        target,
-        metadata,
-        library,
-        classBuilder,
-        this,
-        computeFormalParameterScope(classBuilder?.scope ?? library.scope));
+        target, metadata, library, isClassMember ? parent : null, this);
   }
 
   Procedure get target => origin.procedure;
@@ -426,6 +417,8 @@
 
   RedirectingInitializer redirectingInitializer;
 
+  Token beginInitializers;
+
   @override
   KernelConstructorBuilder actualOrigin;
 
@@ -498,14 +491,9 @@
 
   @override
   void buildOutlineExpressions(LibraryBuilder library) {
-    ClassBuilder classBuilder = isClassMember ? parent : null;
     KernelMetadataBuilder.buildAnnotations(
-        target,
-        metadata,
-        library,
-        classBuilder,
-        this,
-        computeFormalParameterScope(classBuilder?.scope ?? library.scope));
+        target, metadata, library, parent, this);
+    beginInitializers = null;
   }
 
   FunctionNode buildFunction(LibraryBuilder library) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index e91b0a4..4a5bc98 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -59,10 +59,8 @@
 
 import '../type_inference/inference_helper.dart' show InferenceHelper;
 
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
 import '../type_inference/type_inference_engine.dart'
-    show IncludesTypeParametersCovariantly, InferenceNode, TypeInferenceEngine;
+    show IncludesTypeParametersCovariantly, TypeInferenceEngine;
 
 import '../type_inference/type_inferrer.dart'
     show ExpressionInferenceResult, TypeInferrer, TypeInferrerImpl;
@@ -280,59 +278,6 @@
   }
 }
 
-/// Shadow object representing a class in kernel form.
-class ShadowClass extends Class {
-  ClassInferenceInfo _inferenceInfo;
-
-  ShadowClass(
-      {String name,
-      Supertype supertype,
-      Supertype mixedInType,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes,
-      List<Procedure> procedures,
-      List<Field> fields})
-      : super(
-            name: name,
-            supertype: supertype,
-            mixedInType: mixedInType,
-            typeParameters: typeParameters,
-            implementedTypes: implementedTypes,
-            procedures: procedures,
-            fields: fields);
-
-  /// Resolves all forwarding nodes for this class, propagates covariance
-  /// annotations, and creates forwarding stubs as needed.
-  void finalizeCovariance(InterfaceResolver interfaceResolver) {
-    interfaceResolver.finalizeCovariance(
-        this, _inferenceInfo.gettersAndMethods, _inferenceInfo.builder.library);
-    interfaceResolver.finalizeCovariance(
-        this, _inferenceInfo.setters, _inferenceInfo.builder.library);
-  }
-
-  /// Creates API members for this class.
-  void setupApiMembers(InterfaceResolver interfaceResolver) {
-    interfaceResolver.createApiMembers(this, _inferenceInfo.gettersAndMethods,
-        _inferenceInfo.setters, _inferenceInfo.builder.library);
-  }
-
-  static void clearClassInferenceInfo(ShadowClass class_) {
-    class_._inferenceInfo = null;
-  }
-
-  static ClassInferenceInfo getClassInferenceInfo(Class class_) {
-    if (class_ is ShadowClass) return class_._inferenceInfo;
-    return null;
-  }
-
-  /// Initializes the class inference information associated with the given
-  /// [class_], starting with the fact that it is associated with the given
-  /// [builder].
-  static void setBuilder(ShadowClass class_, SourceClassBuilder builder) {
-    class_._inferenceInfo = new ClassInferenceInfo(builder);
-  }
-}
-
 /// Abstract shadow object representing a complex assignment in kernel form.
 ///
 /// Since there are many forms a complex assignment might have been desugared
@@ -635,32 +580,6 @@
   }
 }
 
-/// Concrete shadow object representing a field in kernel form.
-class ShadowField extends Field implements ShadowMember {
-  @override
-  InferenceNode inferenceNode;
-
-  ShadowTypeInferrer _typeInferrer;
-
-  final bool _isImplicitlyTyped;
-
-  ShadowField(Name name, this._isImplicitlyTyped, {Uri fileUri})
-      : super(name, fileUri: fileUri) {}
-
-  @override
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType) {
-    type = inferredType;
-  }
-
-  static bool isImplicitlyTyped(ShadowField field) => field._isImplicitlyTyped;
-
-  static void setInferenceNode(ShadowField field, InferenceNode node) {
-    assert(field.inferenceNode == null);
-    field.inferenceNode = node;
-  }
-}
-
 /// Concrete shadow object representing a field initializer in kernel form.
 class ShadowFieldInitializer extends FieldInitializer
     implements InitializerJudgment {
@@ -1000,18 +919,6 @@
   }
 }
 
-/// Abstract shadow object representing a field or procedure in kernel form.
-abstract class ShadowMember implements Member {
-  Uri get fileUri;
-
-  InferenceNode get inferenceNode;
-
-  void set inferenceNode(InferenceNode value);
-
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType);
-}
-
 /// Shadow object for [MethodInvocation].
 class MethodInvocationJudgment extends MethodInvocation
     implements ExpressionJudgment {
@@ -1110,37 +1017,6 @@
   }
 }
 
-/// Concrete shadow object representing a procedure in kernel form.
-class ShadowProcedure extends Procedure implements ShadowMember {
-  @override
-  InferenceNode inferenceNode;
-
-  final bool _hasImplicitReturnType;
-
-  ShadowProcedure(Name name, ProcedureKind kind, FunctionNode function,
-      this._hasImplicitReturnType,
-      {Uri fileUri, bool isAbstract: false})
-      : super(name, kind, function, fileUri: fileUri, isAbstract: isAbstract);
-
-  @override
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType) {
-    if (isSetter) {
-      if (function.positionalParameters.length > 0) {
-        function.positionalParameters[0].type = inferredType;
-      }
-    } else if (isGetter) {
-      function.returnType = inferredType;
-    } else {
-      unhandled("setInferredType", "not accessor", fileOffset, uri);
-    }
-  }
-
-  static bool hasImplicitReturnType(ShadowProcedure procedure) {
-    return procedure._hasImplicitReturnType;
-  }
-}
-
 /// Concrete shadow object representing an assignment to a property.
 class PropertyAssignmentJudgment extends ComplexAssignmentJudgmentWithReceiver {
   /// If this assignment uses null-aware access (`?.`), the conditional
@@ -1470,14 +1346,8 @@
 
   @override
   ShadowTypeInferrer createTopLevelTypeInferrer(
-      InterfaceType thisType, ShadowField field, KernelLibraryBuilder library) {
-    return field._typeInferrer =
-        new TypeInferrer(this, field.fileUri, true, thisType, library);
-  }
-
-  @override
-  ShadowTypeInferrer getFieldTypeInferrer(ShadowField field) {
-    return field._typeInferrer;
+      Uri uri, InterfaceType thisType, KernelLibraryBuilder library) {
+    return new TypeInferrer(this, uri, true, thisType, library);
   }
 }
 
@@ -1493,7 +1363,7 @@
         super.private(engine, uri, topLevel, thisType, library);
 
   @override
-  Expression getFieldInitializer(ShadowField field) {
+  Expression getFieldInitializer(Field field) {
     return field.initializer;
   }
 
@@ -1536,13 +1406,6 @@
   }
 
   @override
-  DartType inferFieldTopLevel(ShadowField field) {
-    if (field.initializer == null) return const DynamicType();
-    return inferExpression(field.initializer, const UnknownType(), true,
-        isVoidAllowed: true);
-  }
-
-  @override
   void inferInitializer(
       InferenceHelper helper, kernel.Initializer initializer) {
     assert(initializer is InitializerJudgment);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 5d67c40..0128ab2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -87,7 +87,6 @@
 import 'kernel_builder.dart'
     show
         ClassBuilder,
-        ClassHierarchyBuilder,
         Declaration,
         InvalidTypeBuilder,
         KernelClassBuilder,
@@ -152,8 +151,6 @@
     loader = createLoader();
   }
 
-  void set builderHierarchy(ClassHierarchyBuilder o) {}
-
   SourceLoader createLoader() =>
       new SourceLoader(fileSystem, includeComments, this);
 
@@ -268,8 +265,7 @@
       component =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       computeCoreTypes();
-      builderHierarchy =
-          loader.buildClassHierarchy(myClasses, objectClassBuilder);
+      loader.buildClassHierarchy(myClasses, objectClassBuilder);
       loader.computeHierarchy();
       loader.performTopLevelInference(myClasses);
       loader.checkSupertypes(myClasses);
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
index 9f6d5c1..94e0b9b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -14,6 +14,7 @@
         InterfaceType,
         InvalidType,
         NamedType,
+        Nullability,
         TypeParameter,
         TypeParameterType,
         TypedefType,
@@ -30,16 +31,21 @@
 
   /// Returns true if [s] is a subtype of [t].
   bool isSubtypeOfKernel(DartType s, DartType t) {
-    if (s is BottomType) {
-      return true; // Rule 3.
-    }
     if (s is InvalidType) {
-      // InvalidType is also a bottom type.
+      // InvalidType is a bottom type.
       return true;
     }
     if (t is InvalidType) {
       return false;
     }
+    return isSubtypeOfKernelNullability(s, s.nullability, t, t.nullability);
+  }
+
+  bool isSubtypeOfKernelNullability(
+      DartType s, Nullability sNullability, DartType t, tNullability) {
+    if (s is BottomType) {
+      return true; // Rule 3.
+    }
     if (t is DynamicType) {
       return true; // Rule 2.
     }
@@ -57,121 +63,161 @@
       if (cls == hierarchy.futureOrKernelClass) {
         const IsFutureOrSubtypeOf relation = const IsFutureOrSubtypeOf();
         if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
+          return relation.isDynamicRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
+          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
         } else if (s is InterfaceType) {
           return s.classNode == hierarchy.futureOrKernelClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
+              ? relation.isFutureOrRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isInterfaceRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
+          return relation.isFunctionRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is TypeParameterType) {
           return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
+              ? relation.isTypeParameterRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isIntersectionRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
+          return relation.isTypedefRelated(
+              s, sNullability, t, tNullability, this);
         }
       } else {
         const IsInterfaceSubtypeOf relation = const IsInterfaceSubtypeOf();
         if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
+          return relation.isDynamicRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
+          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
         } else if (s is InterfaceType) {
           return s.classNode == hierarchy.futureOrKernelClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
+              ? relation.isFutureOrRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isInterfaceRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
+          return relation.isFunctionRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is TypeParameterType) {
           return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
+              ? relation.isTypeParameterRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isIntersectionRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
+          return relation.isTypedefRelated(
+              s, sNullability, t, tNullability, this);
         }
       }
     } else if (t is FunctionType) {
       const IsFunctionSubtypeOf relation = const IsFunctionSubtypeOf();
       if (s is DynamicType) {
-        return relation.isDynamicRelated(s, t, this);
+        return relation.isDynamicRelated(
+            s, sNullability, t, tNullability, this);
       } else if (s is VoidType) {
-        return relation.isVoidRelated(s, t, this);
+        return relation.isVoidRelated(s, sNullability, t, tNullability, this);
       } else if (s is InterfaceType) {
         return s.classNode == hierarchy.futureOrKernelClass
-            ? relation.isFutureOrRelated(s, t, this)
-            : relation.isInterfaceRelated(s, t, this);
+            ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
+            : relation.isInterfaceRelated(
+                s, sNullability, t, tNullability, this);
       } else if (s is FunctionType) {
-        return relation.isFunctionRelated(s, t, this);
+        return relation.isFunctionRelated(
+            s, sNullability, t, tNullability, this);
       } else if (s is TypeParameterType) {
         return s.promotedBound == null
-            ? relation.isTypeParameterRelated(s, t, this)
-            : relation.isIntersectionRelated(s, t, this);
+            ? relation.isTypeParameterRelated(
+                s, sNullability, t, tNullability, this)
+            : relation.isIntersectionRelated(
+                s, sNullability, t, tNullability, this);
       } else if (s is TypedefType) {
-        return relation.isTypedefRelated(s, t, this);
+        return relation.isTypedefRelated(
+            s, sNullability, t, tNullability, this);
       }
     } else if (t is TypeParameterType) {
       if (t.promotedBound == null) {
         const IsTypeParameterSubtypeOf relation =
             const IsTypeParameterSubtypeOf();
         if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
+          return relation.isDynamicRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
+          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
         } else if (s is InterfaceType) {
           return s.classNode == hierarchy.futureOrKernelClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
+              ? relation.isFutureOrRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isInterfaceRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
+          return relation.isFunctionRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is TypeParameterType) {
           return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
+              ? relation.isTypeParameterRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isIntersectionRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
+          return relation.isTypedefRelated(
+              s, sNullability, t, tNullability, this);
         }
       } else {
         const IsIntersectionSubtypeOf relation =
             const IsIntersectionSubtypeOf();
         if (s is DynamicType) {
-          return relation.isDynamicRelated(s, t, this);
+          return relation.isDynamicRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is VoidType) {
-          return relation.isVoidRelated(s, t, this);
+          return relation.isVoidRelated(s, sNullability, t, tNullability, this);
         } else if (s is InterfaceType) {
           return s.classNode == hierarchy.futureOrKernelClass
-              ? relation.isFutureOrRelated(s, t, this)
-              : relation.isInterfaceRelated(s, t, this);
+              ? relation.isFutureOrRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isInterfaceRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is FunctionType) {
-          return relation.isFunctionRelated(s, t, this);
+          return relation.isFunctionRelated(
+              s, sNullability, t, tNullability, this);
         } else if (s is TypeParameterType) {
           return s.promotedBound == null
-              ? relation.isTypeParameterRelated(s, t, this)
-              : relation.isIntersectionRelated(s, t, this);
+              ? relation.isTypeParameterRelated(
+                  s, sNullability, t, tNullability, this)
+              : relation.isIntersectionRelated(
+                  s, sNullability, t, tNullability, this);
         } else if (s is TypedefType) {
-          return relation.isTypedefRelated(s, t, this);
+          return relation.isTypedefRelated(
+              s, sNullability, t, tNullability, this);
         }
       }
     } else if (t is TypedefType) {
       const IsTypedefSubtypeOf relation = const IsTypedefSubtypeOf();
       if (s is DynamicType) {
-        return relation.isDynamicRelated(s, t, this);
+        return relation.isDynamicRelated(
+            s, sNullability, t, tNullability, this);
       } else if (s is VoidType) {
-        return relation.isVoidRelated(s, t, this);
+        return relation.isVoidRelated(s, sNullability, t, tNullability, this);
       } else if (s is InterfaceType) {
         return s.classNode == hierarchy.futureOrKernelClass
-            ? relation.isFutureOrRelated(s, t, this)
-            : relation.isInterfaceRelated(s, t, this);
+            ? relation.isFutureOrRelated(s, sNullability, t, tNullability, this)
+            : relation.isInterfaceRelated(
+                s, sNullability, t, tNullability, this);
       } else if (s is FunctionType) {
-        return relation.isFunctionRelated(s, t, this);
+        return relation.isFunctionRelated(
+            s, sNullability, t, tNullability, this);
       } else if (s is TypeParameterType) {
         return s.promotedBound == null
-            ? relation.isTypeParameterRelated(s, t, this)
-            : relation.isIntersectionRelated(s, t, this);
+            ? relation.isTypeParameterRelated(
+                s, sNullability, t, tNullability, this)
+            : relation.isIntersectionRelated(
+                s, sNullability, t, tNullability, this);
       } else if (s is TypedefType) {
-        return relation.isTypedefRelated(s, t, this);
+        return relation.isTypedefRelated(
+            s, sNullability, t, tNullability, this);
       }
     } else {
       throw "Unhandled type: ${t.runtimeType}";
@@ -198,28 +244,45 @@
 abstract class TypeRelation<T extends DartType> {
   const TypeRelation();
 
-  bool isDynamicRelated(DynamicType s, T t, Types types);
+  bool isDynamicRelated(DynamicType s, Nullability sNullability, T t,
+      Nullability tNullability, Types types);
 
-  bool isVoidRelated(VoidType s, T t, Types types);
+  bool isVoidRelated(VoidType s, Nullability sNullability, T t,
+      Nullability tNullability, Types types);
 
-  bool isInterfaceRelated(InterfaceType s, T t, Types types);
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability, T t,
+      Nullability tNullability, Types types);
 
-  bool isIntersectionRelated(TypeParameterType intersection, T t, Types types);
+  bool isIntersectionRelated(
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      T t,
+      Nullability tNullability,
+      Types types);
 
-  bool isFunctionRelated(FunctionType s, T t, Types types);
+  bool isFunctionRelated(FunctionType s, Nullability sNullability, T t,
+      Nullability tNullability, Types types);
 
-  bool isFutureOrRelated(InterfaceType futureOr, T t, Types types);
+  bool isFutureOrRelated(
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      T t,
+      Nullability tNullability,
+      Types types);
 
-  bool isTypeParameterRelated(TypeParameterType s, T t, Types types);
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      T t, Nullability tNullability, Types types);
 
-  bool isTypedefRelated(TypedefType s, T t, Types types);
+  bool isTypedefRelated(TypedefType s, Nullability sNullability, T t,
+      Nullability tNullability, Types types);
 }
 
 class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
   const IsInterfaceSubtypeOf();
 
   @override
-  bool isInterfaceRelated(InterfaceType s, InterfaceType t, Types types) {
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+      InterfaceType t, Nullability tNullability, Types types) {
     if (s.classNode == types.hierarchy.nullKernelClass) {
       // This is an optimization, to avoid instantating unnecessary type
       // arguments in getKernelTypeAsInstanceOf.
@@ -236,13 +299,18 @@
   }
 
   @override
-  bool isTypeParameterRelated(
-      TypeParameterType s, InterfaceType t, Types types) {
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      InterfaceType t, Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s.parameter.bound, t);
   }
 
   @override
-  bool isFutureOrRelated(InterfaceType futureOr, InterfaceType t, Types types) {
+  bool isFutureOrRelated(
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      InterfaceType t,
+      Nullability tNullability,
+      Types types) {
     List<DartType> arguments = futureOr.typeArguments;
     if (!types.isSubtypeOfKernel(arguments.single, t)) {
       return false; // Rule 7.1
@@ -256,28 +324,36 @@
 
   @override
   bool isIntersectionRelated(
-      TypeParameterType intersection, InterfaceType t, Types types) {
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      InterfaceType t,
+      Nullability tNullability,
+      Types types) {
     return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
   }
 
   @override
-  bool isDynamicRelated(DynamicType s, InterfaceType t, Types types) {
+  bool isDynamicRelated(DynamicType s, Nullability sNullability,
+      InterfaceType t, Nullability tNullability, Types types) {
     return false;
   }
 
   @override
-  bool isFunctionRelated(FunctionType s, InterfaceType t, Types types) {
+  bool isFunctionRelated(FunctionType s, Nullability sNullability,
+      InterfaceType t, Nullability tNullability, Types types) {
     return t.classNode == types.hierarchy.functionKernelClass; // Rule 14.
   }
 
   @override
-  bool isTypedefRelated(TypedefType s, InterfaceType t, Types types) {
+  bool isTypedefRelated(TypedefType s, Nullability sNullability,
+      InterfaceType t, Nullability tNullability, Types types) {
     // Rule 5.
     return types.isSubtypeOfKernel(s.unalias, t);
   }
 
   @override
-  bool isVoidRelated(VoidType s, InterfaceType t, Types types) {
+  bool isVoidRelated(VoidType s, Nullability sNullability, InterfaceType t,
+      Nullability tNullability, Types types) {
     return false;
   }
 }
@@ -286,7 +362,8 @@
   const IsFunctionSubtypeOf();
 
   @override
-  bool isFunctionRelated(FunctionType s, FunctionType t, Types types) {
+  bool isFunctionRelated(FunctionType s, Nullability sNullability,
+      FunctionType t, Nullability tNullability, Types types) {
     List<TypeParameter> sTypeVariables = s.typeParameters;
     List<TypeParameter> tTypeVariables = t.typeParameters;
     if (sTypeVariables.length != tTypeVariables.length) return false;
@@ -364,40 +441,55 @@
   }
 
   @override
-  bool isInterfaceRelated(InterfaceType s, FunctionType t, Types types) {
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+      FunctionType t, Nullability tNullability, Types types) {
     return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
   }
 
   @override
-  bool isDynamicRelated(DynamicType s, FunctionType t, Types types) => false;
+  bool isDynamicRelated(DynamicType s, Nullability sNullability, FunctionType t,
+      Nullability tNullability, Types types) {
+    return false;
+  }
 
   @override
-  bool isFutureOrRelated(InterfaceType futureOr, FunctionType t, Types types) {
+  bool isFutureOrRelated(
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      FunctionType t,
+      Nullability tNullability,
+      Types types) {
     return false;
   }
 
   @override
   bool isIntersectionRelated(
-      TypeParameterType intersection, FunctionType t, Types types) {
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      FunctionType t,
+      Nullability tNullability,
+      Types types) {
     // Rule 12.
     return types.isSubtypeOfKernel(intersection.promotedBound, t);
   }
 
   @override
-  bool isTypeParameterRelated(
-      TypeParameterType s, FunctionType t, Types types) {
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      FunctionType t, Nullability tNullability, Types types) {
     // Rule 13.
     return types.isSubtypeOfKernel(s.parameter.bound, t);
   }
 
   @override
-  bool isTypedefRelated(TypedefType s, FunctionType t, Types types) {
+  bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
+      Nullability tNullability, Types types) {
     // Rule 5.
     return types.isSubtypeOfKernel(s.unalias, t);
   }
 
   @override
-  bool isVoidRelated(VoidType s, FunctionType t, Types types) {
+  bool isVoidRelated(VoidType s, Nullability sNullability, FunctionType t,
+      Nullability tNullability, Types types) {
     return false;
   }
 }
@@ -406,8 +498,8 @@
   const IsTypeParameterSubtypeOf();
 
   @override
-  bool isTypeParameterRelated(
-      TypeParameterType s, TypeParameterType t, Types types) {
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      TypeParameterType t, Nullability tNullability, Types types) {
     return s.parameter == t.parameter ||
         // Rule 13.
         types.isSubtypeOfKernel(s.bound, t);
@@ -415,38 +507,51 @@
 
   @override
   bool isIntersectionRelated(
-      TypeParameterType intersection, TypeParameterType t, Types types) {
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      TypeParameterType t,
+      Nullability tNullability,
+      Types types) {
     return intersection.parameter == t.parameter; // Rule 8.
   }
 
   @override
-  bool isInterfaceRelated(InterfaceType s, TypeParameterType t, Types types) {
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+      TypeParameterType t, Nullability tNullability, Types types) {
     return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
   }
 
   @override
-  bool isDynamicRelated(DynamicType s, TypeParameterType t, Types types) {
+  bool isDynamicRelated(DynamicType s, Nullability sNullability,
+      TypeParameterType t, Nullability tNullability, Types types) {
     return false;
   }
 
   @override
-  bool isFunctionRelated(FunctionType s, TypeParameterType t, Types types) {
+  bool isFunctionRelated(FunctionType s, Nullability sNullability,
+      TypeParameterType t, Nullability tNullability, Types types) {
     return false;
   }
 
   @override
   bool isFutureOrRelated(
-      InterfaceType futureOr, TypeParameterType t, Types types) {
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      TypeParameterType t,
+      Nullability tNullability,
+      Types types) {
     return false;
   }
 
   @override
-  bool isTypedefRelated(TypedefType s, TypeParameterType t, Types types) {
+  bool isTypedefRelated(TypedefType s, Nullability sNullability,
+      TypeParameterType t, Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s.unalias, t);
   }
 
   @override
-  bool isVoidRelated(VoidType s, TypeParameterType t, Types types) {
+  bool isVoidRelated(VoidType s, Nullability sNullability, TypeParameterType t,
+      Nullability tNullability, Types types) {
     return false;
   }
 }
@@ -455,43 +560,58 @@
   const IsTypedefSubtypeOf();
 
   @override
-  bool isInterfaceRelated(InterfaceType s, TypedefType t, Types types) {
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+      TypedefType t, Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s, t.unalias);
   }
 
   @override
-  bool isDynamicRelated(DynamicType s, TypedefType t, Types types) {
+  bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
+      Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s, t.unalias);
   }
 
   @override
-  bool isFunctionRelated(FunctionType s, TypedefType t, Types types) {
+  bool isFunctionRelated(FunctionType s, Nullability sNullability,
+      TypedefType t, Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s, t.unalias);
   }
 
   @override
-  bool isFutureOrRelated(InterfaceType futureOr, TypedefType t, Types types) {
+  bool isFutureOrRelated(
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      TypedefType t,
+      Nullability tNullability,
+      Types types) {
     return types.isSubtypeOfKernel(futureOr, t.unalias);
   }
 
   @override
   bool isIntersectionRelated(
-      TypeParameterType intersection, TypedefType t, Types types) {
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      TypedefType t,
+      Nullability tNullability,
+      Types types) {
     return types.isSubtypeOfKernel(intersection, t.unalias);
   }
 
   @override
-  bool isTypeParameterRelated(TypeParameterType s, TypedefType t, Types types) {
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      TypedefType t, Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s, t.unalias);
   }
 
   @override
-  bool isTypedefRelated(TypedefType s, TypedefType t, Types types) {
+  bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
+      Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s.unalias, t.unalias);
   }
 
   @override
-  bool isVoidRelated(VoidType s, TypedefType t, Types types) {
+  bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
+      Nullability tNullability, Types types) {
     return types.isSubtypeOfKernel(s, t.unalias);
   }
 }
@@ -500,8 +620,8 @@
   const IsFutureOrSubtypeOf();
 
   @override
-  bool isInterfaceRelated(
-      InterfaceType s, InterfaceType futureOr, Types types) {
+  bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
     if (types.isSubtypeOfKernel(s, arguments.single)) {
       return true; // Rule 11.
@@ -513,27 +633,33 @@
 
   @override
   bool isFutureOrRelated(
-      InterfaceType sFutureOr, InterfaceType tFutureOr, Types types) {
+      InterfaceType sFutureOr,
+      Nullability sFutureOrNullability,
+      InterfaceType tFutureOr,
+      Nullability tFutureOrNullability,
+      Types types) {
     // This follows from combining rules 7, 10, and 11.
     return types.isSubtypeOfKernel(
         sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
   }
 
   @override
-  bool isDynamicRelated(DynamicType s, InterfaceType futureOr, Types types) {
+  bool isDynamicRelated(DynamicType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
     return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
   }
 
   @override
-  bool isVoidRelated(VoidType s, InterfaceType futureOr, Types types) {
+  bool isVoidRelated(VoidType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
     return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
   }
 
   @override
-  bool isTypeParameterRelated(
-      TypeParameterType s, InterfaceType futureOr, Types types) {
+  bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
     if (types.isSubtypeOfKernel(s, arguments.single)) {
       // Rule 11.
@@ -551,15 +677,21 @@
   }
 
   @override
-  bool isFunctionRelated(FunctionType s, InterfaceType futureOr, Types types) {
+  bool isFunctionRelated(FunctionType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
     return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
   }
 
   @override
   bool isIntersectionRelated(
-      TypeParameterType intersection, InterfaceType futureOr, Types types) {
-    if (isTypeParameterRelated(intersection, futureOr, types)) {
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      Types types) {
+    if (isTypeParameterRelated(intersection, intersectionNullability, futureOr,
+        futureOrNullability, types)) {
       // Rule 8.
       return true;
     }
@@ -568,7 +700,8 @@
   }
 
   @override
-  bool isTypedefRelated(TypedefType s, InterfaceType futureOr, Types types) {
+  bool isTypedefRelated(TypedefType s, Nullability sNullability,
+      InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     return types.isSubtypeOfKernel(s.unalias, futureOr);
   }
 }
@@ -577,51 +710,93 @@
   const IsIntersectionSubtypeOf();
 
   @override
-  bool isIntersectionRelated(TypeParameterType sIntersection,
-      TypeParameterType tIntersection, Types types) {
+  bool isIntersectionRelated(
+      TypeParameterType sIntersection,
+      Nullability sIntersectionNullability,
+      TypeParameterType tIntersection,
+      Nullability tIntersectionNullability,
+      Types types) {
     // Rule 9.
-    return const IsTypeParameterSubtypeOf()
-            .isIntersectionRelated(sIntersection, tIntersection, types) &&
+    return const IsTypeParameterSubtypeOf().isIntersectionRelated(
+            sIntersection,
+            sIntersectionNullability,
+            tIntersection,
+            tIntersectionNullability,
+            types) &&
         types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
   }
 
   @override
   bool isTypeParameterRelated(
-      TypeParameterType s, TypeParameterType intersection, Types types) {
+      TypeParameterType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     // Rule 9.
-    return const IsTypeParameterSubtypeOf()
-            .isTypeParameterRelated(s, intersection, types) &&
+    return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
+            s, sNullability, intersection, intersectionNullability, types) &&
         types.isSubtypeOfKernel(s, intersection.promotedBound);
   }
 
   @override
   bool isInterfaceRelated(
-      InterfaceType s, TypeParameterType intersection, Types types) {
+      InterfaceType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
   }
 
+  @override
   bool isDynamicRelated(
-      DynamicType s, TypeParameterType intersection, Types types) {
+      DynamicType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     return false;
   }
 
+  @override
   bool isFunctionRelated(
-      FunctionType s, TypeParameterType intersection, Types types) {
+      FunctionType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     return false;
   }
 
+  @override
   bool isFutureOrRelated(
-      InterfaceType futureOr, TypeParameterType intersection, Types types) {
+      InterfaceType futureOr,
+      Nullability futureOrNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     return false;
   }
 
+  @override
   bool isTypedefRelated(
-      TypedefType s, TypeParameterType intersection, Types types) {
+      TypedefType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     // Rule 5.
     return types.isSubtypeOfKernel(s.unalias, intersection);
   }
 
-  bool isVoidRelated(VoidType s, TypeParameterType intersection, Types types) {
+  @override
+  bool isVoidRelated(
+      VoidType s,
+      Nullability sNullability,
+      TypeParameterType intersection,
+      Nullability intersectionNullability,
+      Types types) {
     return false;
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 64ec528..e2471a4 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -480,6 +480,12 @@
   }
 
   @override
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    listener?.endInvalidAwaitExpression(beginToken, endToken, errorCode);
+  }
+
+  @override
   void endBinaryExpression(Token token) {
     listener?.endBinaryExpression(token);
   }
@@ -774,9 +780,10 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
-    listener?.endMethod(getOrSet, beginToken, beginParam, endToken);
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
+    listener?.endMethod(
+        getOrSet, beginToken, beginParam, beginInitializers, endToken);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index e92f6f3..fcedb9b 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -6,7 +6,8 @@
 
 import '../../scanner/token.dart' show Token;
 
-import '../fasta_codes.dart' show Message, templateExperimentNotEnabled;
+import '../fasta_codes.dart'
+    show Message, MessageCode, templateExperimentNotEnabled;
 
 import '../quote.dart' show UnescapeErrorListener;
 
@@ -57,6 +58,11 @@
     logEvent("AwaitExpression");
   }
 
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    logEvent("InvalidAwaitExpression");
+  }
+
   void beginBlock(Token token) {}
 
   void endBlock(int count, Token beginToken, Token endToken) {
@@ -747,8 +753,8 @@
   /// - initializers
   /// - async marker
   /// - body
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     logEvent("Method");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index ed13bfe..d6a0d065 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2516,7 +2516,7 @@
 
   Token parseInitializersOpt(Token token) {
     if (optional(':', token.next)) {
-      return parseInitializers(token);
+      return parseInitializers(token.next);
     } else {
       listener.handleNoInitializers();
       return token;
@@ -2529,7 +2529,7 @@
   /// ;
   /// ```
   Token parseInitializers(Token token) {
-    Token begin = token.next;
+    Token begin = token;
     assert(optional(':', begin));
     listener.beginInitializers(begin);
     int count = 0;
@@ -3241,8 +3241,10 @@
         ? MemberKind.StaticMethod
         : MemberKind.NonStaticMethod;
     Token beforeParam = token;
-    token = parseGetterOrFormalParameters(token, name, isGetter, kind);
-    token = parseInitializersOpt(token);
+    Token beforeInitializers =
+        parseGetterOrFormalParameters(token, name, isGetter, kind);
+    token = parseInitializersOpt(beforeInitializers);
+    if (token == beforeInitializers) beforeInitializers = null;
 
     AsyncModifier savedAsyncModifier = asyncState;
     Token asyncToken = token.next;
@@ -3264,7 +3266,8 @@
           (staticToken == null || externalToken != null) && inPlainSync);
     }
     asyncState = savedAsyncModifier;
-    listener.endMethod(getOrSet, beforeStart.next, beforeParam.next, token);
+    listener.endMethod(getOrSet, beforeStart.next, beforeParam.next,
+        beforeInitializers?.next, token);
     return token;
   }
 
@@ -5741,12 +5744,15 @@
     Token awaitToken = token.next;
     assert(optional('await', awaitToken));
     listener.beginAwaitExpression(awaitToken);
-    if (!inAsync) {
-      reportRecoverableError(awaitToken, fasta.messageAwaitNotAsync);
-    }
     token = parsePrecedenceExpression(
         awaitToken, POSTFIX_PRECEDENCE, allowCascades);
-    listener.endAwaitExpression(awaitToken, token.next);
+    if (inAsync) {
+      listener.endAwaitExpression(awaitToken, token.next);
+    } else {
+      fasta.MessageCode errorCode = fasta.messageAwaitNotAsync;
+      reportRecoverableError(awaitToken, errorCode);
+      listener.endInvalidAwaitExpression(awaitToken, token.next, errorCode);
+    }
     return token;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/parser/parser_main.dart b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
index a282842..0079797 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser_main.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
@@ -36,6 +36,7 @@
       Uri uri = Uri.base.resolve(argument.substring(1));
       await for (String file in new File.fromUri(uri)
           .openRead()
+          .cast<List<int>>()
           .transform(utf8.decoder)
           .transform(const LineSplitter())) {
         outLine(uri.resolve(file));
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index c556487..52ee5db 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -575,8 +575,8 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     debugEvent("Method");
     // TODO(danrubel): Consider removing the beginParam parameter
     // and using bodyToken, but pushing a NullValue on the stack
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 964646f..1ed1f9e 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -754,8 +754,8 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     debugEvent("Method");
     MethodBody bodyKind = pop();
     if (bodyKind == MethodBody.RedirectingFactoryBody) {
@@ -871,7 +871,8 @@
           charOffset,
           formalsOffset,
           endToken.charOffset,
-          nativeMethodName);
+          nativeMethodName,
+          beginInitializers: beginInitializers);
     } else {
       if (isConst) {
         addProblem(messageConstMethod, varFinalOrConstOffset, 5);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 09cd1c9..3adef89 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -41,21 +41,19 @@
         TypeVariableBuilder,
         compareProcedures;
 
-import '../kernel/kernel_shadow_ast.dart' show ShadowClass;
-
 import '../kernel/type_algorithms.dart' show Variance, computeVariance;
 
 import '../problems.dart' show unexpected, unhandled;
 
-ShadowClass initializeClass(
-    ShadowClass cls,
+Class initializeClass(
+    Class cls,
     List<TypeVariableBuilder> typeVariables,
     String name,
     KernelLibraryBuilder parent,
     int startCharOffset,
     int charOffset,
     int charEndOffset) {
-  cls ??= new ShadowClass(
+  cls ??= new Class(
       name: name,
       typeParameters:
           KernelTypeVariableBuilder.kernelTypeParametersFromBuilders(
@@ -105,12 +103,10 @@
       : actualCls = initializeClass(cls, typeVariables, name, parent,
             startCharOffset, charOffset, charEndOffset),
         super(metadata, modifiers, name, typeVariables, supertype, interfaces,
-            scope, constructors, parent, charOffset) {
-    ShadowClass.setBuilder(this.cls, this);
-  }
+            scope, constructors, parent, charOffset);
 
   @override
-  ShadowClass get cls => origin.actualCls;
+  Class get cls => origin.actualCls;
 
   @override
   KernelLibraryBuilder get library => super.library;
@@ -278,20 +274,6 @@
     constructorScopeBuilder.addMember(name, memberBuilder);
   }
 
-  void prepareTopLevelInference() {
-    scope.forEach((String name, Declaration declaration) {
-      do {
-        if (declaration is KernelFieldBuilder) {
-          declaration.prepareTopLevelInference();
-        }
-        declaration = declaration.next;
-      } while (declaration != null);
-    });
-    if (!isPatch) {
-      cls.setupApiMembers(library.loader.interfaceResolver);
-    }
-  }
-
   @override
   int finishPatch() {
     if (!isPatch) return 0;
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 89abbb2..77579d0 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -431,7 +431,8 @@
       int charOffset,
       int charOpenParenOffset,
       int charEndOffset,
-      String nativeMethodName);
+      String nativeMethodName,
+      {Token beginInitializers});
 
   void addProcedure(
       String documentationComment,
@@ -703,7 +704,7 @@
     }
   }
 
-  void includePart(
+  bool includePart(
       SourceLibraryBuilder<T, R> part, Set<Uri> usedParts, int partOffset) {
     if (part.partOfUri != null) {
       if (uriIsValid(part.partOfUri) && part.partOfUri != uri) {
@@ -715,7 +716,7 @@
             partOffset,
             noLength,
             fileUri);
-        return;
+        return false;
       }
     } else if (part.partOfName != null) {
       if (name != null) {
@@ -728,7 +729,7 @@
               partOffset,
               noLength,
               fileUri);
-          return;
+          return false;
         }
       } else {
         // This is an error, but the part is not removed from the list of parts,
@@ -739,7 +740,7 @@
             partOffset,
             noLength,
             fileUri);
-        return;
+        return false;
       }
     } else {
       // This is an error, but the part is not removed from the list of parts,
@@ -749,7 +750,7 @@
         addProblem(templateMissingPartOf.withArguments(part.fileUri),
             partOffset, noLength, fileUri);
       }
-      return;
+      return false;
     }
     part.validatePart(this, usedParts);
     NameIterator partDeclarations = part.nameIterator;
@@ -798,6 +799,7 @@
     part.partOfLibrary = this;
     part.scope.becomePartOf(scope);
     // TODO(ahe): Include metadata from part?
+    return true;
   }
 
   void buildInitialScopes() {
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3040e27..74fcaa1 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -68,17 +68,18 @@
         templateSourceOutlineSummary,
         templateUntranslatableUri;
 
-import '../kernel/kernel_shadow_ast.dart'
-    show ShadowClass, ShadowTypeInferenceEngine;
+import '../kernel/kernel_shadow_ast.dart' show ShadowTypeInferenceEngine;
 
 import '../kernel/kernel_builder.dart'
     show
         ClassBuilder,
         ClassHierarchyBuilder,
         Declaration,
+        DelayedMember,
+        DelayedOverrideCheck,
         EnumBuilder,
+        FieldBuilder,
         KernelClassBuilder,
-        KernelFieldBuilder,
         KernelProcedureBuilder,
         KernelTypeBuilder,
         LibraryBuilder,
@@ -107,8 +108,6 @@
 import '../scanner.dart'
     show ErrorToken, ScannerConfiguration, ScannerResult, Token, scan;
 
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
 import 'diet_listener.dart' show DietListener;
 
 import 'diet_parser.dart' show DietParser;
@@ -128,6 +127,8 @@
 
   final Map<Uri, List<int>> sourceBytes = <Uri, List<int>>{};
 
+  ClassHierarchyBuilder builderHierarchy;
+
   // Used when building directly to kernel.
   ClassHierarchy hierarchy;
   CoreTypes coreTypes;
@@ -138,8 +139,6 @@
 
   ShadowTypeInferenceEngine typeInferenceEngine;
 
-  InterfaceResolver interfaceResolver;
-
   Instrumentation instrumentation;
 
   CollectionTransformer collectionTransformer;
@@ -609,6 +608,10 @@
             break;
           }
         }
+        if (allSupertypesProcessed && cls.isPatch) {
+          allSupertypesProcessed =
+              topologicallySortedClasses.contains(cls.origin);
+        }
         if (allSupertypesProcessed) {
           topologicallySortedClasses.add(cls);
           checkClassSupertypes(cls, directSupertypes, blackListedClasses);
@@ -884,27 +887,33 @@
   }
 
   void checkOverrides(List<SourceClassBuilder> sourceClasses) {
-    assert(hierarchy != null);
-    for (SourceClassBuilder builder in sourceClasses) {
-      if (builder.library.loader == this && !builder.isPatch) {
-        builder.checkOverrides(
-            hierarchy, typeInferenceEngine?.typeSchemaEnvironment);
-      }
+    List<DelayedOverrideCheck> overrideChecks =
+        builderHierarchy.overrideChecks.toList();
+    builderHierarchy.overrideChecks.clear();
+    for (int i = 0; i < overrideChecks.length; i++) {
+      overrideChecks[i].check(builderHierarchy);
     }
-    ticker.logMs("Checked overrides");
+    ticker.logMs("Checked ${overrideChecks.length} overrides");
+
+    typeInferenceEngine?.finishTopLevelInitializingFormals();
+    ticker.logMs("Finished initializing formals");
   }
 
   void checkAbstractMembers(List<SourceClassBuilder> sourceClasses) {
-    // TODO(ahe): Move this to [ClassHierarchyBuilder].
-    if (target.legacyMode) return;
-    assert(hierarchy != null);
-    for (SourceClassBuilder builder in sourceClasses) {
-      if (builder.library.loader == this && !builder.isPatch) {
-        builder.checkAbstractMembers(
-            coreTypes, hierarchy, typeInferenceEngine.typeSchemaEnvironment);
-      }
+    List<DelayedMember> delayedMemberChecks =
+        builderHierarchy.delayedMemberChecks.toList();
+    builderHierarchy.delayedMemberChecks.clear();
+    Set<Class> changedClasses = new Set<Class>();
+    for (int i = 0; i < delayedMemberChecks.length; i++) {
+      delayedMemberChecks[i].check(builderHierarchy);
+      changedClasses.add(delayedMemberChecks[i].parent.cls);
     }
-    ticker.logMs("Checked abstract members");
+    ticker.logMs(
+        "Computed ${delayedMemberChecks.length} combined member signatures");
+
+    hierarchy.applyMemberChanges(changedClasses, findDescendants: false);
+    ticker
+        .logMs("Updated ${changedClasses.length} classes in kernel hierarchy");
   }
 
   void checkRedirectingFactories(List<SourceClassBuilder> sourceClasses) {
@@ -968,12 +977,12 @@
     });
   }
 
-  ClassHierarchyBuilder buildClassHierarchy(
+  void buildClassHierarchy(
       List<SourceClassBuilder> sourceClasses, ClassBuilder objectClass) {
-    ClassHierarchyBuilder hierarchy = ClassHierarchyBuilder.build(
+    builderHierarchy = ClassHierarchyBuilder.build(
         objectClass, sourceClasses, this, coreTypes);
+    typeInferenceEngine?.hierarchyBuilder = builderHierarchy;
     ticker.logMs("Built class hierarchy");
-    return hierarchy;
   }
 
   void createTypeInferenceEngine() {
@@ -989,58 +998,30 @@
     /// might be subject to type inference, and records dependencies between
     /// them.
     typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
-    interfaceResolver = new InterfaceResolver(typeInferenceEngine,
-        typeInferenceEngine.typeSchemaEnvironment, instrumentation);
+    List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
     for (LibraryBuilder library in builders.values) {
       if (library.loader == this) {
-        Iterator<Declaration> iterator = library.iterator;
-        while (iterator.moveNext()) {
-          Declaration member = iterator.current;
-          if (member is KernelFieldBuilder) {
-            member.prepareTopLevelInference();
-          }
+        List<FieldBuilder> implicitlyTypedFields =
+            library.takeImplicitlyTypedFields();
+        if (implicitlyTypedFields != null) {
+          allImplicitlyTypedFields.addAll(implicitlyTypedFields);
         }
       }
     }
-    for (int i = 0; i < sourceClasses.length; i++) {
-      sourceClasses[i].prepareTopLevelInference();
+
+    for (int i = 0; i < allImplicitlyTypedFields.length; i++) {
+      // TODO(ahe): This can cause a crash for parts that failed to get
+      // included, see for example,
+      // tests/standalone_2/io/http_cookie_date_test.dart.
+      allImplicitlyTypedFields[i].inferType();
     }
+
     typeInferenceEngine.isTypeInferencePrepared = true;
-    ticker.logMs("Prepared top level inference");
 
-    /// The second phase of top level initializer inference, which is to visit
-    /// fields and top level variables in topologically-sorted order and assign
-    /// their types.
-    typeInferenceEngine.finishTopLevelFields();
-    List<Class> changedClasses = new List<Class>();
-    for (var builder in sourceClasses) {
-      if (builder.isPatch) continue;
-      ShadowClass class_ = builder.target;
-      int memberCount = class_.fields.length +
-          class_.constructors.length +
-          class_.procedures.length +
-          class_.redirectingFactoryConstructors.length;
-      class_.finalizeCovariance(interfaceResolver);
-      ShadowClass.clearClassInferenceInfo(class_);
-      int newMemberCount = class_.fields.length +
-          class_.constructors.length +
-          class_.procedures.length +
-          class_.redirectingFactoryConstructors.length;
-      if (newMemberCount != memberCount) {
-        // The inference potentially adds new members (but doesn't otherwise
-        // change the classes), so if the member count has changed we need to
-        // update the class in the class hierarchy.
-        changedClasses.add(class_);
-      }
-    }
-
-    typeInferenceEngine.finishTopLevelInitializingFormals();
-    interfaceResolver = null;
     // Since finalization of covariance may have added forwarding stubs, we need
     // to recompute the class hierarchy so that method compilation will properly
     // target those forwarding stubs.
     hierarchy.onAmbiguousSupertypes = ignoreAmbiguousSupertypes;
-    hierarchy.applyMemberChanges(changedClasses, findDescendants: true);
     ticker.logMs("Performed top level inference");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index 621a14e..a1faa23 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -6,7 +6,7 @@
 
 import '../builder/builder.dart' show Declaration;
 
-import '../messages.dart' show LocatedMessage, Message;
+import '../messages.dart' show LocatedMessage, Message, MessageCode;
 
 import '../parser.dart'
     show Assert, IdentifierContext, FormalParameterKind, Listener, MemberKind;
@@ -210,6 +210,13 @@
   }
 
   @override
+  void endInvalidAwaitExpression(
+      Token beginToken, Token endToken, MessageCode errorCode) {
+    debugEvent("InvalidAwaitExpression", beginToken);
+    state.popPushNull(beginToken.lexeme, beginToken); // Expression.
+  }
+
+  @override
   void endBinaryExpression(Token token) {
     debugEvent("BinaryExpression", token);
     state.pop(); // Right-hand side.
@@ -962,8 +969,8 @@
   }
 
   @override
-  void endMethod(
-      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
+  void endMethod(Token getOrSet, Token beginToken, Token beginParam,
+      Token beginInitializers, Token endToken) {
     debugEvent("endMethod", endToken);
     state.pop(); // Method name.
     state.checkEmpty(endToken);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
deleted file mode 100644
index 5c8dbfa..0000000
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ /dev/null
@@ -1,1235 +0,0 @@
-// Copyright (c) 2017, 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.md file.
-
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        Class,
-        DartType,
-        DynamicType,
-        Expression,
-        Field,
-        FunctionNode,
-        FunctionType,
-        InvalidType,
-        Member,
-        Name,
-        NamedExpression,
-        Procedure,
-        ProcedureKind,
-        ReturnStatement,
-        SuperMethodInvocation,
-        SuperPropertyGet,
-        SuperPropertySet,
-        TypeParameter,
-        TypeParameterType,
-        VariableDeclaration,
-        VariableGet,
-        VoidType;
-
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
-import 'package:kernel/transformations/flags.dart' show TransformerFlag;
-
-import 'package:kernel/type_algebra.dart' show Substitution;
-
-import 'package:kernel/src/hierarchy_based_type_environment.dart'
-    show HierarchyBasedTypeEnvironment;
-
-import '../../base/instrumentation.dart'
-    show Instrumentation, InstrumentationValueLiteral;
-
-import '../builder/builder.dart' show LibraryBuilder;
-
-import '../kernel/kernel_library_builder.dart' show KernelLibraryBuilder;
-
-import '../kernel/kernel_shadow_ast.dart'
-    show ShadowClass, ShadowField, ShadowProcedure, VariableDeclarationJudgment;
-
-import '../messages.dart'
-    show
-        noLength,
-        templateCantInferTypeDueToCircularity,
-        templateCantInferTypeDueToInconsistentOverrides;
-
-import '../names.dart' show indexSetName;
-
-import '../problems.dart' show unhandled;
-
-import 'type_inference_engine.dart'
-    show
-        FieldInitializerInferenceNode,
-        IncludesTypeParametersCovariantly,
-        InferenceNode,
-        TypeInferenceEngine;
-
-import 'type_inferrer.dart' show getNamedFormal;
-
-import 'type_schema_environment.dart'
-    show
-        getNamedParameterType,
-        getPositionalParameterType,
-        substituteTypeParams;
-
-/// Concrete class derived from [InferenceNode] to represent type inference of
-/// getters, setters, and fields based on inheritance.
-class AccessorInferenceNode extends InferenceNode {
-  final InterfaceResolver _interfaceResolver;
-
-  /// The method whose return type and/or parameter types should be inferred.
-  final Procedure _declaredMethod;
-
-  /// A list containing the methods overridden by [_declaredMethod], if any.
-  final List<Member> _candidates;
-
-  /// The index of the first method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _start;
-
-  /// The past-the-end index of the last method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _end;
-
-  final LibraryBuilder _library;
-
-  final Uri _fileUri;
-
-  AccessorInferenceNode(this._interfaceResolver, this._declaredMethod,
-      this._candidates, this._start, this._end, this._library, this._fileUri);
-
-  String get _name {
-    if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
-      return _declaredMethod.function.positionalParameters[0].name;
-    }
-    return _declaredMethod.name.name;
-  }
-
-  int get _offset {
-    if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
-      return _declaredMethod.function.positionalParameters[0].fileOffset;
-    }
-    return _declaredMethod.fileOffset;
-  }
-
-  @override
-  void resolveInternal() {
-    var declaredMethod = _declaredMethod;
-    var kind = declaredMethod.kind;
-    var overriddenTypes = _computeAccessorOverriddenTypes();
-    DartType inferredType;
-    if (isCircular) {
-      inferredType = const InvalidType();
-      _library.addProblem(
-          templateCantInferTypeDueToCircularity.withArguments(_name),
-          _offset,
-          noLength,
-          _fileUri);
-    } else {
-      inferredType = _interfaceResolver.matchTypes(
-          overriddenTypes, _library, _name, _fileUri, _offset);
-    }
-    if (declaredMethod is SyntheticAccessor) {
-      declaredMethod._field.type = inferredType;
-      declaredMethod._field.initializer = null;
-    } else {
-      if (kind == ProcedureKind.Getter) {
-        declaredMethod.function.returnType = inferredType;
-      } else {
-        declaredMethod.function.positionalParameters[0].type = inferredType;
-      }
-    }
-  }
-
-  /// Computes the types of the getters and setters overridden by
-  /// [_declaredMethod], with appropriate type parameter substitutions.
-  List<DartType> _computeAccessorOverriddenTypes() {
-    var overriddenTypes = <DartType>[];
-    for (int i = _start; i < _end; i++) {
-      var candidate = _candidates[i];
-      Procedure resolvedCandidate;
-      if (candidate is ForwardingNode) {
-        resolvedCandidate = candidate.resolve();
-      } else {
-        resolvedCandidate = candidate;
-      }
-      DartType overriddenType;
-      if (resolvedCandidate is SyntheticAccessor) {
-        var field = resolvedCandidate._field;
-        TypeInferenceEngine.resolveInferenceNode(field);
-        overriddenType = field.type;
-      } else if (resolvedCandidate.function != null) {
-        switch (resolvedCandidate.kind) {
-          case ProcedureKind.Getter:
-            overriddenType = resolvedCandidate.function.returnType;
-            break;
-          case ProcedureKind.Setter:
-            overriddenType =
-                resolvedCandidate.function.positionalParameters[0].type;
-            break;
-          default:
-            // Illegal override (error will be reported elsewhere).  Just skip
-            // this override.
-            continue;
-        }
-      } else {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      overriddenTypes.add(_interfaceResolver
-          ._substitutionFor(resolvedCandidate, _declaredMethod.enclosingClass)
-          .substituteType(overriddenType));
-    }
-    return overriddenTypes;
-  }
-}
-
-/// A [ForwardingNode] represents a method, getter, or setter within a class's
-/// interface that is either implemented in the class directly or inherited from
-/// a superclass.
-///
-/// This class allows us to defer the determination of exactly which member is
-/// inherited, as well as the propagation of covariance annotations, and
-/// the creation of forwarding stubs, until type inference.
-class ForwardingNode extends Procedure {
-  /// The [InterfaceResolver] that created this [ForwardingNode].
-  final InterfaceResolver _interfaceResolver;
-
-  /// A list containing the directly implemented and directly inherited
-  /// procedures of the class in question.
-  ///
-  /// Note that many [ForwardingNode]s share the same [_candidates] list;
-  /// consult [_start] and [_end] to see which entries in this list are relevant
-  /// to this [ForwardingNode].
-  final List<Member> _candidates;
-
-  /// Index of the first entry in [_candidates] relevant to this
-  /// [ForwardingNode].
-  final int _start;
-
-  /// Index just beyond the last entry in [_candidates] relevant to this
-  /// [ForwardingNode].
-  final int _end;
-
-  /// The member this node resolves to (if it has been computed); otherwise
-  /// `null`.
-  Member _resolution;
-
-  /// The result of finalizing this node (if the node has been finalized);
-  /// otherwise `null`.
-  Member _finalResolution;
-
-  /// If this forwarding node represents a member that needs type inference, the
-  /// corresponding [InferenceNode]; otherwise `null`.
-  InferenceNode _inferenceNode;
-
-  ForwardingNode(this._interfaceResolver, this._inferenceNode, Class class_,
-      Name name, ProcedureKind kind, this._candidates, this._start, this._end)
-      : super(name, kind, null) {
-    parent = class_;
-  }
-
-  /// Finishes handling of this node by propagating covariance and creating
-  /// forwarding stubs if necessary.
-  Procedure finalize() => _finalResolution ??= _finalize();
-
-  /// Returns the declared or inherited member this node resolves to.
-  ///
-  /// Does not create forwarding stubs.
-  Procedure resolve() => _resolution ??= _resolve();
-
-  /// Tag the parameters of [interfaceMember] that need type checks
-  ///
-  /// Parameters can need type checks for calls coming from statically typed
-  /// call sites, due to covariant generics and overrides with explicit
-  /// `covariant` parameters.
-  ///
-  /// Tag parameters of [interfaceMember] that need such checks when the member
-  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
-  /// they would not be checked in an inherited implementation, a forwarding
-  /// stub is introduced as a place to put the checks.
-  Procedure _computeCovarianceFixes(Procedure interfaceMember) {
-    var substitution =
-        _interfaceResolver._substitutionFor(interfaceMember, enclosingClass);
-    // We always create a forwarding stub when we've inherited a member from an
-    // interface other than the first override candidate.  This is to work
-    // around a bug in the Kernel type checker where it chooses the first
-    // override candidate.
-    //
-    // TODO(kmillikin): Fix the Kernel type checker and stop creating these
-    // extra stubs.
-    var stub = interfaceMember.enclosingClass == enclosingClass ||
-            interfaceMember == _resolvedCandidate(_start)
-        ? interfaceMember
-        : _createForwardingStub(substitution, interfaceMember);
-
-    var interfaceFunction = interfaceMember.function;
-    var interfacePositionalParameters = interfaceFunction.positionalParameters;
-    var interfaceNamedParameters = interfaceFunction.namedParameters;
-    var interfaceTypeParameters = interfaceFunction.typeParameters;
-
-    void createStubIfNeeded() {
-      if (stub != interfaceMember) return;
-      if (interfaceMember.enclosingClass == enclosingClass) return;
-      stub = _createForwardingStub(substitution, interfaceMember);
-    }
-
-    bool isImplCreated = false;
-    void createImplIfNeeded() {
-      if (isImplCreated) return;
-      createStubIfNeeded();
-      _createForwardingImplIfNeeded(stub.function);
-      isImplCreated = true;
-    }
-
-    IncludesTypeParametersCovariantly needsCheckVisitor =
-        enclosingClass.typeParameters.isEmpty
-            ? null
-            : ShadowClass.getClassInferenceInfo(enclosingClass)
-                    .needsCheckVisitor ??=
-                new IncludesTypeParametersCovariantly(
-                    enclosingClass.typeParameters);
-    bool needsCheck(DartType type) => needsCheckVisitor == null
-        ? false
-        : substitution.substituteType(type).accept(needsCheckVisitor);
-    for (int i = 0; i < interfacePositionalParameters.length; i++) {
-      var parameter = interfacePositionalParameters[i];
-      var isGenericCovariantImpl =
-          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
-      var isCovariant = parameter.isCovariant;
-      var superParameter = parameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherPositionalParameters =
-            otherMember.function.positionalParameters;
-        if (otherPositionalParameters.length <= i) continue;
-        var otherParameter = otherPositionalParameters[i];
-        if (j == _start) superParameter = otherParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-        if (otherParameter.isCovariant) {
-          isCovariant = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.positionalParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-      if (isCovariant) {
-        if (!superParameter.isCovariant) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isCovariant) {
-          createStubIfNeeded();
-          stub.function.positionalParameters[i].isCovariant = true;
-        }
-      }
-    }
-    for (int i = 0; i < interfaceNamedParameters.length; i++) {
-      var parameter = interfaceNamedParameters[i];
-      var isGenericCovariantImpl =
-          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
-      var isCovariant = parameter.isCovariant;
-      var superParameter = parameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherParameter =
-            getNamedFormal(otherMember.function, parameter.name);
-        if (otherParameter == null) continue;
-        if (j == _start) superParameter = otherParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-        if (otherParameter.isCovariant) {
-          isCovariant = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.namedParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-      if (isCovariant) {
-        if (!superParameter.isCovariant) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isCovariant) {
-          createStubIfNeeded();
-          stub.function.namedParameters[i].isCovariant = true;
-        }
-      }
-    }
-    for (int i = 0; i < interfaceTypeParameters.length; i++) {
-      var typeParameter = interfaceTypeParameters[i];
-      var isGenericCovariantImpl = typeParameter.isGenericCovariantImpl;
-      var superTypeParameter = typeParameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherTypeParameters = otherMember.function.typeParameters;
-        if (otherTypeParameters.length <= i) continue;
-        var otherTypeParameter = otherTypeParameters[i];
-        if (j == _start) superTypeParameter = otherTypeParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherTypeParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superTypeParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!typeParameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.typeParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-    }
-    return stub;
-  }
-
-  void _createForwardingImplIfNeeded(FunctionNode function) {
-    if (function.body != null) {
-      // There is already an implementation; nothing further needs to be done.
-      return;
-    }
-    // Find the concrete implementation in the superclass; this is what we need
-    // to forward to.  If we can't find one, then the method is fully abstract
-    // and we don't need to do anything.
-    var superclass = enclosingClass.superclass;
-    if (superclass == null) return;
-    Procedure procedure = function.parent;
-    var superTarget = _interfaceResolver._typeEnvironment.hierarchy
-        .getDispatchTarget(superclass, procedure.name,
-            setter: kind == ProcedureKind.Setter);
-    if (superTarget == null) return;
-    if (superTarget is Procedure && superTarget.isForwardingStub) {
-      superTarget = _getForwardingStubSuperTarget(superTarget);
-    }
-    procedure.isAbstract = false;
-    if (!procedure.isForwardingStub) {
-      // This procedure exists abstractly in the source code; we need to make it
-      // concrete and give it a body that is a forwarding stub.  This situation
-      // is called a "forwarding semi-stub".
-      procedure.isForwardingStub = true;
-      procedure.isForwardingSemiStub = true;
-      _interfaceResolver._instrumentation?.record(
-          procedure.fileUri,
-          procedure.fileOffset,
-          'forwardingStub',
-          new InstrumentationValueLiteral('semi-stub'));
-    }
-    var positionalArguments = function.positionalParameters
-        .map<Expression>((parameter) => new VariableGet(parameter))
-        .toList();
-    var namedArguments = function.namedParameters
-        .map((parameter) =>
-            new NamedExpression(parameter.name, new VariableGet(parameter)))
-        .toList();
-    var typeArguments = function.typeParameters
-        .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
-        .toList();
-    var arguments = new Arguments(positionalArguments,
-        types: typeArguments, named: namedArguments);
-    Expression superCall;
-    switch (kind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
-        superCall = new SuperMethodInvocation(name, arguments, superTarget);
-        break;
-      case ProcedureKind.Getter:
-        superCall = new SuperPropertyGet(
-            name,
-            superTarget is SyntheticAccessor
-                ? superTarget._field
-                : superTarget);
-        break;
-      case ProcedureKind.Setter:
-        superCall = new SuperPropertySet(
-            name,
-            positionalArguments[0],
-            superTarget is SyntheticAccessor
-                ? superTarget._field
-                : superTarget);
-        break;
-      default:
-        unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
-        break;
-    }
-    function.body = new ReturnStatement(superCall)..parent = function;
-    procedure.transformerFlags |= TransformerFlag.superCalls;
-    procedure.forwardingStubSuperTarget = superTarget;
-  }
-
-  /// Creates a forwarding stub based on the given [target].
-  Procedure _createForwardingStub(Substitution substitution, Procedure target) {
-    VariableDeclaration copyParameter(VariableDeclaration parameter) {
-      return new VariableDeclaration(parameter.name,
-          type: substitution.substituteType(parameter.type),
-          isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
-    }
-
-    var targetTypeParameters = target.function.typeParameters;
-    List<TypeParameter> typeParameters;
-    if (targetTypeParameters.isNotEmpty) {
-      typeParameters =
-          new List<TypeParameter>.filled(targetTypeParameters.length, null);
-      var additionalSubstitution = <TypeParameter, DartType>{};
-      for (int i = 0; i < targetTypeParameters.length; i++) {
-        var targetTypeParameter = targetTypeParameters[i];
-        var typeParameter = new TypeParameter(targetTypeParameter.name, null)
-          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
-        typeParameters[i] = typeParameter;
-        additionalSubstitution[targetTypeParameter] =
-            new TypeParameterType(typeParameter);
-      }
-      substitution = Substitution.combine(
-          substitution, Substitution.fromMap(additionalSubstitution));
-      for (int i = 0; i < typeParameters.length; i++) {
-        typeParameters[i].bound =
-            substitution.substituteType(targetTypeParameters[i].bound);
-      }
-    }
-    var positionalParameters =
-        target.function.positionalParameters.map(copyParameter).toList();
-    var namedParameters =
-        target.function.namedParameters.map(copyParameter).toList();
-    var function = new FunctionNode(null,
-        positionalParameters: positionalParameters,
-        namedParameters: namedParameters,
-        typeParameters: typeParameters,
-        requiredParameterCount: target.function.requiredParameterCount,
-        returnType: substitution.substituteType(target.function.returnType));
-    Member finalTarget;
-    if (target is Procedure && target.isForwardingStub) {
-      finalTarget = target.forwardingStubInterfaceTarget;
-    } else if (target is SyntheticAccessor) {
-      finalTarget = target._field;
-    } else {
-      finalTarget = target;
-    }
-    return new Procedure(name, kind, function,
-        isAbstract: true,
-        isForwardingStub: true,
-        fileUri: enclosingClass.fileUri,
-        forwardingStubInterfaceTarget: finalTarget)
-      ..startFileOffset = enclosingClass.fileOffset
-      ..fileOffset = enclosingClass.fileOffset
-      ..parent = enclosingClass;
-  }
-
-  /// Creates a forwarding stub for this node if necessary, and propagates
-  /// covariance information.
-  Procedure _finalize() {
-    return _computeCovarianceFixes(resolve());
-  }
-
-  /// Returns the [i]th element of [_candidates], finalizing it if necessary.
-  Procedure _finalizedCandidate(int i) {
-    Procedure candidate = _candidates[i];
-    return candidate is ForwardingNode &&
-            _interfaceResolver.isTypeInferencePrepared
-        ? candidate.finalize()
-        : candidate;
-  }
-
-  /// Determines which inherited member this node resolves to, and also performs
-  /// type inference.
-  Procedure _resolve() {
-    Procedure inheritedMember = _candidates[_start];
-    bool isDeclaredInThisClass =
-        identical(inheritedMember.enclosingClass, enclosingClass);
-    if (isDeclaredInThisClass) {
-      if (_inferenceNode != null) {
-        _inferenceNode.resolve();
-        _inferenceNode = null;
-      }
-    } else {
-      // If there are multiple inheritance candidates, the inherited member is
-      // the member whose type is a subtype of all the others.  We can find it
-      // by two passes over the list of members.  For the first pass, we step
-      // through the candidates, updating inheritedMember each time we find a
-      // member whose type is a subtype of the previous inheritedMember.  As we
-      // do this, we also work out the necessary substitution for matching up
-      // type parameters between this class and the corresponding superclass.
-      //
-      // Since the subtyping relation is reflexive, we will favor the most
-      // recently visited candidate in the case where the types are the same.
-      // We want to favor earlier candidates, so we visit the candidate list
-      // backwards.
-      inheritedMember = _resolvedCandidate(_end - 1);
-      var inheritedMemberSubstitution =
-          _interfaceResolver._substitutionFor(inheritedMember, enclosingClass);
-      var inheritedMemberType = inheritedMember is ForwardingNode
-          ? const DynamicType()
-          : inheritedMemberSubstitution.substituteType(
-              kind == ProcedureKind.Setter
-                  ? inheritedMember.setterType
-                  : inheritedMember.getterType);
-      for (int i = _end - 2; i >= _start; i--) {
-        var candidate = _resolvedCandidate(i);
-        var substitution =
-            _interfaceResolver._substitutionFor(candidate, enclosingClass);
-        bool isBetter;
-        DartType type;
-        if (kind == ProcedureKind.Setter) {
-          type = candidate is ForwardingNode
-              ? const DynamicType()
-              : substitution.substituteType(candidate.setterType);
-          // Setters are contravariant in their setter type, so we have to
-          // reverse the check.
-          isBetter = _interfaceResolver._typeEnvironment
-              .isSubtypeOf(inheritedMemberType, type);
-        } else {
-          type = candidate is ForwardingNode
-              ? const DynamicType()
-              : substitution.substituteType(candidate.getterType);
-          isBetter = _interfaceResolver._typeEnvironment
-              .isSubtypeOf(type, inheritedMemberType);
-        }
-        if (isBetter) {
-          inheritedMember = candidate;
-          inheritedMemberSubstitution = substitution;
-          inheritedMemberType = type;
-        }
-      }
-      // For the second pass, we verify that inheritedMember is a subtype of all
-      // the other potentially inherited members.
-      // TODO(paulberry): implement this.
-    }
-    return inheritedMember;
-  }
-
-  /// Returns the [i]th element of [_candidates], resolving it if necessary.
-  Procedure _resolvedCandidate(int i) {
-    Procedure candidate = _candidates[i];
-    return candidate is ForwardingNode &&
-            _interfaceResolver.isTypeInferencePrepared
-        ? candidate.resolve()
-        : candidate;
-  }
-
-  static void createForwardingImplIfNeededForTesting(
-      ForwardingNode node, FunctionNode function) {
-    node._createForwardingImplIfNeeded(function);
-  }
-
-  /// Public method allowing tests to access [_createForwardingStub].
-  ///
-  /// This method is static so that it can be easily eliminated by tree shaking
-  /// when not needed.
-  static Procedure createForwardingStubForTesting(
-      ForwardingNode node, Substitution substitution, Procedure target) {
-    return node._createForwardingStub(substitution, target);
-  }
-
-  /// For testing: get the list of candidates relevant to a given node.
-  static List<Procedure> getCandidates(ForwardingNode node) {
-    return node._candidates.sublist(node._start, node._end);
-  }
-
-  static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
-    // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
-    // easier.
-    ReturnStatement body = forwardingStub.function.body;
-    var expression = body.expression;
-    if (expression is SuperMethodInvocation) {
-      return expression.interfaceTarget;
-    } else if (expression is SuperPropertySet) {
-      return expression.interfaceTarget;
-    } else {
-      return unhandled('${expression.runtimeType}',
-          '_getForwardingStubSuperTarget', -1, null);
-    }
-  }
-}
-
-/// An [InterfaceResolver] keeps track of the information necessary to resolve
-/// method calls, gets, and sets within a chunk of code being compiled, to
-/// infer covariance annotations, and to create forwarwding stubs when necessary
-/// to meet covariance requirements.
-class InterfaceResolver {
-  final TypeInferenceEngine _typeInferenceEngine;
-
-  final HierarchyBasedTypeEnvironment _typeEnvironment;
-
-  final Instrumentation _instrumentation;
-
-  InterfaceResolver(
-      this._typeInferenceEngine, this._typeEnvironment, this._instrumentation);
-
-  /// Indicates whether the "prepare" phase of type inference is complete.
-  bool get isTypeInferencePrepared =>
-      _typeInferenceEngine.isTypeInferencePrepared;
-
-  /// Report an error if all types in [types] are not equal using `==`.
-  ///
-  /// Returns the type if there is at least one and they are all equal,
-  /// otherwise the type `dynamic`.  [library], [name], [fileUri], and
-  /// [charOffset] are used to report the error.
-  DartType matchTypes(Iterable<DartType> types, LibraryBuilder library,
-      String name, Uri fileUri, int charOffset) {
-    DartType first;
-    for (var type in types) {
-      if (first == null) {
-        first = type;
-      } else if (first != type) {
-        // Types don't match.  Report an error.
-        library.addProblem(
-            templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
-            charOffset,
-            noLength,
-            fileUri);
-        return const DynamicType();
-      }
-    }
-    // If there are no overridden types, infer `dynamic`.
-    return first ?? const DynamicType();
-  }
-
-  /// Computes the types of the methods overridden by [method] in [class_].
-  ///
-  /// The types have the type parameters of [class_] substituted appropriately.
-  ///
-  /// [candidates] has the list of inherited interface methods with the same
-  /// name as [method] as a sublist from [start] inclusive to [end] exclusive.
-  List<FunctionType> _computeMethodOverriddenTypes(Class class_,
-      Procedure method, List<Member> candidates, int start, int end) {
-    var overriddenTypes = <FunctionType>[];
-    var declaredTypeParameters = method.function.typeParameters;
-    for (int i = start; i < end; ++i) {
-      var candidate = candidates[i];
-      if (candidate is SyntheticAccessor) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var candidateFunction = candidate.function;
-      if (candidateFunction == null) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var substitution = _substitutionFor(candidate, class_);
-      FunctionType overriddenType =
-          substitution.substituteType(candidateFunction.functionType);
-      var overriddenTypeParameters = overriddenType.typeParameters;
-      if (overriddenTypeParameters.length != declaredTypeParameters.length) {
-        // Generic arity mismatch.  Don't do any inference for this method.
-        // TODO(paulberry): report an error.
-        overriddenTypes.clear();
-        break;
-      } else if (overriddenTypeParameters.isNotEmpty) {
-        var substitutionMap = <TypeParameter, DartType>{};
-        for (int i = 0; i < declaredTypeParameters.length; ++i) {
-          substitutionMap[overriddenTypeParameters[i]] =
-              new TypeParameterType(declaredTypeParameters[i]);
-        }
-        overriddenType = substituteTypeParams(
-            overriddenType, substitutionMap, declaredTypeParameters);
-      }
-      overriddenTypes.add(overriddenType);
-    }
-    return overriddenTypes;
-  }
-
-  void inferMethodType(LibraryBuilder library, Class class_, Procedure method,
-      List<Member> candidates, int start, int end) {
-    var overriddenTypes =
-        _computeMethodOverriddenTypes(class_, method, candidates, start, end);
-    if (ShadowProcedure.hasImplicitReturnType(method) &&
-        method.name != indexSetName) {
-      method.function.returnType = matchTypes(
-          overriddenTypes.map((type) => type.returnType),
-          library,
-          method.name.name,
-          class_.fileUri,
-          method.fileOffset);
-    }
-    var positionalParameters = method.function.positionalParameters;
-    for (int i = 0; i < positionalParameters.length; ++i) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(
-          positionalParameters[i])) {
-        // Note that if the parameter is not present in the overridden method,
-        // getPositionalParameterType treats it as dynamic.  This is consistent
-        // with the behavior called for in the informal top level type inference
-        // spec, which says:
-        //
-        //     If there is no corresponding parameter position in the overridden
-        //     method to infer from and the signatures are compatible, it is
-        //     treated as dynamic (e.g. overriding a one parameter method with a
-        //     method that takes a second optional parameter).  Note: if there
-        //     is no corresponding parameter position in the overridden method to
-        //     infer from and the signatures are incompatible (e.g. overriding a
-        //     one parameter method with a method that takes a second
-        //     non-optional parameter), the inference result is not defined and
-        //     tools are free to either emit an error, or to defer the error to
-        //     override checking.
-        positionalParameters[i].type = matchTypes(
-            overriddenTypes.map((type) => getPositionalParameterType(type, i)),
-            library,
-            positionalParameters[i].name,
-            class_.fileUri,
-            positionalParameters[i].fileOffset);
-      }
-    }
-    var namedParameters = method.function.namedParameters;
-    for (int i = 0; i < namedParameters.length; i++) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(namedParameters[i])) {
-        var name = namedParameters[i].name;
-        namedParameters[i].type = matchTypes(
-            overriddenTypes.map((type) => getNamedParameterType(type, name)),
-            library,
-            namedParameters[i].name,
-            class_.fileUri,
-            namedParameters[i].fileOffset);
-      }
-    }
-  }
-
-  /// Populates [getters] and [setters] with the members of the given [class_]'s
-  /// interface.
-  ///
-  /// [getters] will contain methods and getters, [setters] will contain
-  /// setters.  Some members cannot be resolved immediately.  For instance,
-  /// top-level type inference has not yet inferred field types based on
-  /// initializers and so we cannot yet do override based resolution of getters
-  /// and setters.  Members of the class's interface that need to be resolved
-  /// later are represented by a [ForwardingNode] object.
-  void createApiMembers(Class class_, List<Member> getters,
-      List<Member> setters, LibraryBuilder library) {
-    var candidates = ClassHierarchy.mergeSortedLists(
-        getCandidates(class_, false), getCandidates(class_, true));
-    // Now create getter and perhaps setter forwarding nodes for each unique
-    // name.
-    getters.length = candidates.length;
-    setters.length = candidates.length;
-    int getterIndex = 0;
-    int setterIndex = 0;
-    // To detect conflicts between instance members (possibly inherited ones)
-    // and static members, use a map from names to lists of members.  There can
-    // be more than one static member with a given name, e.g., if there is a
-    // getter and a setter.  We will report both conflicts.
-    forEachApiMember(candidates, (int start, int end, Name name) {
-      Procedure member = candidates[start];
-      ProcedureKind kind = _kindOf(member);
-      if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
-        for (int i = start + 1; i < end; ++i) {
-          if (_kindOf(candidates[i]) != kind) return;
-        }
-        if (member.enclosingClass == class_ && _requiresTypeInference(member)) {
-          inferMethodType(library, class_, member, candidates, start + 1, end);
-        }
-        var forwardingNode = new ForwardingNode(
-            this, null, class_, name, kind, candidates, start, end);
-        getters[getterIndex++] = forwardingNode.finalize();
-        if (library is KernelLibraryBuilder &&
-            forwardingNode.finalize() != forwardingNode.resolve()) {
-          library.forwardersOrigins.add(forwardingNode.finalize());
-          library.forwardersOrigins.add(forwardingNode.resolve());
-        }
-        return;
-      }
-
-      Procedure declaredGetter;
-      int inheritedGetterStart = start;
-      int getterEnd = start;
-      if (kind == ProcedureKind.Getter) {
-        if (member.enclosingClass == class_) {
-          declaredGetter = member;
-          ++inheritedGetterStart;
-        }
-        while (++getterEnd < end) {
-          ProcedureKind currentKind = _kindOf(candidates[getterEnd]);
-          if (currentKind == ProcedureKind.Setter) break;
-          if (currentKind != ProcedureKind.Getter) return;
-        }
-      }
-
-      Procedure declaredSetter;
-      int inheritedSetterStart = getterEnd;
-      if (getterEnd < end) {
-        member = candidates[getterEnd];
-        if (member.enclosingClass == class_) {
-          declaredSetter = member;
-          ++inheritedSetterStart;
-        }
-      }
-
-      InferenceNode getterInferenceNode;
-      if (start < getterEnd) {
-        if (declaredGetter != null) {
-          getterInferenceNode = _createInferenceNode(
-              class_,
-              declaredGetter,
-              candidates,
-              inheritedGetterStart,
-              getterEnd,
-              inheritedSetterStart,
-              end,
-              library,
-              class_.fileUri);
-        }
-        // Getters need to be resolved later, as part of type inference, so just
-        // save the forwarding node for now.
-        //
-        // Choose a representative to use for error reporting, such as if a
-        // class inherits this getter and tries to declare a method with the
-        // same name.
-        Member representative = candidates[start];
-        getters[getterIndex++] = new ForwardingNode(this, getterInferenceNode,
-            class_, name, ProcedureKind.Getter, candidates, start, getterEnd)
-          ..fileUri = representative.fileUri
-          ..fileOffset = representative.fileOffset
-          ..fileEndOffset = representative.fileEndOffset;
-      }
-      if (getterEnd < end) {
-        InferenceNode setterInferenceNode;
-        if (declaredSetter != null) {
-          setterInferenceNode = declaredSetter is SyntheticAccessor
-              ? getterInferenceNode
-              : _createInferenceNode(
-                  class_,
-                  declaredSetter,
-                  candidates,
-                  inheritedSetterStart,
-                  end,
-                  inheritedGetterStart,
-                  getterEnd,
-                  library,
-                  class_.fileUri);
-        }
-        Member representative = candidates[getterEnd];
-        var forwardingNode = new ForwardingNode(this, setterInferenceNode,
-            class_, name, ProcedureKind.Setter, candidates, getterEnd, end)
-          ..fileUri = representative.fileUri
-          ..fileOffset = representative.fileOffset
-          ..fileEndOffset = representative.fileEndOffset;
-        // Setters need to be resolved later, as part of type inference, so just
-        // save the forwarding node for now.
-        setters[setterIndex++] = forwardingNode;
-      }
-    });
-    getters.length = getterIndex;
-    setters.length = setterIndex;
-  }
-
-  void finalizeCovariance(
-      Class class_, List<Member> apiMembers, LibraryBuilder library) {
-    for (int i = 0; i < apiMembers.length; i++) {
-      var member = apiMembers[i];
-      Member resolution;
-      if (member is ForwardingNode) {
-        apiMembers[i] = resolution = member.finalize();
-        if (library is KernelLibraryBuilder &&
-            member.finalize() != member.resolve()) {
-          library.forwardersOrigins.add(member.finalize());
-          library.forwardersOrigins.add(member.resolve());
-        }
-      } else {
-        resolution = member;
-      }
-      if (resolution is Procedure &&
-          resolution.isSyntheticForwarder &&
-          identical(resolution.enclosingClass, class_)) {
-        class_.addMember(resolution);
-      }
-    }
-  }
-
-  /// Gets a list of members implemented or potentially inherited by [class_],
-  /// sorted so that members with the same name are contiguous.
-  ///
-  /// If [setters] is `true`, setters are reported; otherwise getters, methods,
-  /// and operators are reported.
-  List<Procedure> getCandidates(Class class_, bool setters) {
-    // First create a list of candidates for inheritance based on the members
-    // declared directly in the class.
-    List<Procedure> candidates = _typeEnvironment.hierarchy
-        .getDeclaredMembers(class_, setters: setters)
-        .map((member) => makeCandidate(member, setters))
-        .toList();
-    // Merge in candidates from superclasses.
-    if (class_.superclass != null) {
-      candidates = _mergeCandidates(candidates, class_.superclass, setters);
-    }
-    for (var supertype in class_.implementedTypes) {
-      candidates = _mergeCandidates(candidates, supertype.classNode, setters);
-    }
-    return candidates;
-  }
-
-  /// Creates the appropriate [InferenceNode] for inferring [procedure] in the
-  /// context of [class_].
-  ///
-  /// [candidates] a list containing the procedures overridden by [procedure],
-  /// if any.  [start] is the index of the first such procedure, and [end] is
-  /// the past-the-end index of the last such procedure.
-  ///
-  /// For getters and setters, [crossStart] and [crossEnd] are the start and end
-  /// indices of the corresponding overridden setters/getters, respectively.
-  InferenceNode _createInferenceNode(
-      Class class_,
-      Procedure procedure,
-      List<Member> candidates,
-      int start,
-      int end,
-      int crossStart,
-      int crossEnd,
-      LibraryBuilder library,
-      Uri fileUri) {
-    InferenceNode node;
-    if (procedure.isAccessor && _requiresTypeInference(procedure)) {
-      if (start < end) {
-        node = new AccessorInferenceNode(
-            this, procedure, candidates, start, end, library, fileUri);
-      } else if (crossStart < crossEnd) {
-        node = new AccessorInferenceNode(this, procedure, candidates,
-            crossStart, crossEnd, library, fileUri);
-      } else if (procedure is SyntheticAccessor &&
-          procedure._field.initializer != null) {
-        node = new FieldInitializerInferenceNode(
-            _typeInferenceEngine, procedure._field, library);
-      }
-
-      if (node != null && procedure is SyntheticAccessor) {
-        ShadowField.setInferenceNode(procedure._field, node);
-      }
-    }
-    return node;
-  }
-
-  /// Retrieves a list of the interface members of the given [class_].
-  ///
-  /// If [setters] is true, setters are retrieved; otherwise getters and methods
-  /// are retrieved.
-  List<Member> _getInterfaceMembers(Class class_, bool setters) {
-    // If class_ is being compiled from source, retrieve its forwarding nodes.
-    var inferenceInfo = ShadowClass.getClassInferenceInfo(class_);
-    if (inferenceInfo != null) {
-      return setters ? inferenceInfo.setters : inferenceInfo.gettersAndMethods;
-    } else {
-      return _typeEnvironment.hierarchy
-          .getInterfaceMembers(class_, setters: setters);
-    }
-  }
-
-  /// Merges together the list of interface inheritance candidates in
-  /// [candidates] with interface inheritance candidates from superclass
-  /// [class_].
-  ///
-  /// Any candidates from [class_] are converted into interface inheritance
-  /// candidates using [_makeCandidate].
-  List<Procedure> _mergeCandidates(
-      List<Procedure> candidates, Class class_, bool setters) {
-    List<Member> members = _getInterfaceMembers(class_, setters);
-    if (candidates.isEmpty) {
-      return members.map((member) => makeCandidate(member, setters)).toList();
-    }
-    if (members.isEmpty) return candidates;
-    List<Procedure> result = <Procedure>[]..length =
-        candidates.length + members.length;
-    int storeIndex = 0;
-    int i = 0, j = 0;
-    while (i < candidates.length && j < members.length) {
-      Procedure candidate = candidates[i];
-      Member member = members[j];
-      int compare = ClassHierarchy.compareMembers(candidate, member);
-      if (compare <= 0) {
-        result[storeIndex++] = candidate;
-        ++i;
-        // If the same member occurs in both lists, skip the duplicate.
-        if (identical(candidate, member)) ++j;
-      } else {
-        result[storeIndex++] = makeCandidate(member, setters);
-        ++j;
-      }
-    }
-    while (i < candidates.length) {
-      result[storeIndex++] = candidates[i++];
-    }
-    while (j < members.length) {
-      result[storeIndex++] = makeCandidate(members[j++], setters);
-    }
-    result.length = storeIndex;
-    return result;
-  }
-
-  /// Determines the appropriate substitution to translate type parameters
-  /// mentioned in the given [candidate] to type parameters on [class_].
-  Substitution _substitutionFor(Procedure candidate, Class class_) {
-    return Substitution.fromInterfaceType(_typeEnvironment.getTypeAsInstanceOf(
-        class_.thisType, candidate.enclosingClass));
-  }
-
-  /// Executes [callback] once for each uniquely named member of [candidates].
-  ///
-  /// The [start] and [end] values passed to [callback] are the start and
-  /// past-the-end indices into [candidates] of a group of members having the
-  /// same name.  The [name] value passed to [callback] is the common name.
-  static void forEachApiMember(
-      List<Member> candidates, void callback(int start, int end, Name name)) {
-    int i = 0;
-    while (i < candidates.length) {
-      var name = candidates[i].name;
-      int j = i + 1;
-      while (j < candidates.length && candidates[j].name == name) {
-        j++;
-      }
-      callback(i, j, name);
-      i = j;
-    }
-  }
-
-  /// Transforms [member] into a candidate for interface inheritance.
-  ///
-  /// Fields are transformed into getters and setters; methods are passed
-  /// through unchanged.
-  static Procedure makeCandidate(Member member, bool setter) {
-    if (member is Procedure) return member;
-    if (member is Field) {
-      // TODO(paulberry): don't set the type or covariance annotations here,
-      // since they might not have been inferred yet.  Instead, ensure that this
-      // information is propagated to the getter/setter during type inference.
-      var type = member.type;
-      var isGenericCovariantImpl = member.isGenericCovariantImpl;
-      var isCovariant = member.isCovariant;
-      if (setter) {
-        var valueParam = new VariableDeclaration('_', type: type)
-          ..isGenericCovariantImpl = isGenericCovariantImpl
-          ..isCovariant = isCovariant;
-        var function = new FunctionNode(null,
-            positionalParameters: [valueParam], returnType: const VoidType());
-        return new SyntheticAccessor(
-            member.name, ProcedureKind.Setter, function, member)
-          ..parent = member.enclosingClass;
-      } else {
-        var function = new FunctionNode(null, returnType: type);
-        return new SyntheticAccessor(
-            member.name, ProcedureKind.Getter, function, member)
-          ..parent = member.enclosingClass;
-      }
-    }
-    return unhandled('${member.runtimeType}', 'makeCandidate', -1, null);
-  }
-
-  static ProcedureKind _kindOf(Procedure procedure) => procedure.kind;
-
-  /// Determines whether the given [procedure] will require type inference.
-  static bool _requiresTypeInference(Procedure procedure) {
-    if (procedure is SyntheticAccessor) {
-      return ShadowField.isImplicitlyTyped(procedure._field);
-    }
-    if (procedure.kind != ProcedureKind.Setter &&
-        ShadowProcedure.hasImplicitReturnType(procedure)) {
-      // Inference of the return type of `[]=` is handled separately by
-      // KernelProcedureBuilder.build, since there are no dependencies.
-      if (procedure.kind != ProcedureKind.Operator ||
-          procedure.name.name != '[]=') {
-        return true;
-      }
-    }
-    var function = procedure.function;
-    for (var parameter in function.positionalParameters) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
-    }
-    for (var parameter in function.namedParameters) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
-    }
-    return false;
-  }
-}
-
-/// A [SyntheticAccessor] represents the getter or setter implied by a field.
-class SyntheticAccessor extends Procedure {
-  /// The field associated with the synthetic accessor.
-  final Field _field;
-
-  SyntheticAccessor(
-      Name name, ProcedureKind kind, FunctionNode function, this._field)
-      : super(
-            name,
-            kind,
-            kind == ProcedureKind.Setter
-                ? new SyntheticAccessorFunctionNode.setter(_field)
-                : new SyntheticAccessorFunctionNode.getter(_field),
-            fileUri: _field.fileUri) {
-    fileOffset = _field.fileOffset;
-  }
-
-  @override
-  DartType get getterType => _field.type;
-
-  static getField(SyntheticAccessor accessor) => accessor._field;
-}
-
-/// A [SyntheticAccessorFunctionNode] represents the [FunctionNode] part of the
-/// getter or setter implied by a field.
-///
-/// For getters, [returnType] maps to the underlying field's type, so that if
-/// type inference fills in the type of the field, the change will automatically
-/// be reflected in the synthetic getter.
-class SyntheticAccessorFunctionNode extends FunctionNode {
-  final Field _field;
-
-  SyntheticAccessorFunctionNode.getter(this._field)
-      : super(new ReturnStatement());
-
-  SyntheticAccessorFunctionNode.setter(this._field)
-      : super(new ReturnStatement(),
-            positionalParameters: [new SyntheticSetterParameter(_field)]);
-
-  @override
-  DartType get returnType =>
-      positionalParameters.isEmpty ? _field.type : const VoidType();
-}
-
-/// A [SyntheticSetterParameter] represents the "value" parameter of the setter
-/// implied by a field.
-///
-/// The getters [isCovariant], [isGenericCovariantImpl],
-/// [isGenericCovariantInterface], and [type] map to the underlying field's
-/// properties, so that if these properties are modified on the field, the
-/// change will automatically be reflected in the synthetic setter.  Similarly,
-/// the setters [isCovariant], [isGenericCovariantImpl], and
-/// [isGenericCovariantInterface] update the corresponding properties on the
-/// field, so that covariance propagation logic can act uniformly on [Procedure]
-/// objects without having to have special case handling for fields.
-class SyntheticSetterParameter extends VariableDeclaration {
-  final Field _field;
-
-  SyntheticSetterParameter(this._field)
-      : super('_', isCovariant: _field.isCovariant);
-
-  @override
-  bool get isCovariant => _field.isCovariant;
-
-  @override
-  void set isCovariant(bool value) {
-    _field.isCovariant = value;
-  }
-
-  @override
-  bool get isGenericCovariantImpl => _field.isGenericCovariantImpl;
-
-  @override
-  void set isGenericCovariantImpl(bool value) {
-    _field.isGenericCovariantImpl = value;
-  }
-
-  @override
-  DartType get type => _field.type;
-}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index bbf090a..b28fc43 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -11,7 +11,6 @@
         Field,
         FunctionType,
         InterfaceType,
-        InvalidType,
         Member,
         TypeParameter,
         TypeParameterType,
@@ -25,63 +24,16 @@
 import '../../base/instrumentation.dart' show Instrumentation;
 
 import '../kernel/kernel_builder.dart'
-    show LibraryBuilder, KernelLibraryBuilder;
+    show
+        ClassHierarchyBuilder,
+        ImplicitFieldType,
+        LibraryBuilder,
+        KernelLibraryBuilder;
 
-import '../kernel/kernel_shadow_ast.dart' show ShadowField, ShadowMember;
-
-import '../messages.dart' show noLength, templateCantInferTypeDueToCircularity;
-
-import 'type_inferrer.dart' show TypeInferrer, TypeInferrerImpl;
+import 'type_inferrer.dart' show TypeInferrer;
 
 import 'type_schema_environment.dart' show TypeSchemaEnvironment;
 
-/// Concrete class derived from [InferenceNode] to represent type inference of a
-/// field based on its initializer.
-class FieldInitializerInferenceNode extends InferenceNode {
-  final TypeInferenceEngine _typeInferenceEngine;
-
-  /// The field whose type should be inferred.
-  final ShadowField field;
-
-  final LibraryBuilder _library;
-
-  FieldInitializerInferenceNode(
-      this._typeInferenceEngine, this.field, this._library);
-
-  @override
-  void resolveInternal() {
-    var typeInferrer = _typeInferenceEngine.getFieldTypeInferrer(field);
-    // Note: in the event that there is erroneous code, it's possible for
-    // typeInferrer to be null.  If this happens, just skip type inference for
-    // this field.
-    if (typeInferrer != null) {
-      var inferredType = typeInferrer
-          .inferDeclarationType(typeInferrer.inferFieldTopLevel(field));
-      if (isCircular) {
-        // Report the appropriate error.
-        _library.addProblem(
-            templateCantInferTypeDueToCircularity
-                .withArguments(field.name.name),
-            field.fileOffset,
-            noLength,
-            field.fileUri);
-        inferredType = const InvalidType();
-      }
-      field.setInferredType(
-          _typeInferenceEngine, typeInferrer.uri, inferredType);
-      // TODO(paulberry): if type != null, then check that the type of the
-      // initializer is assignable to it.
-    }
-    // TODO(paulberry): the following is a hack so that outlines don't contain
-    // initializers.  But it means that we rebuild the initializers when doing
-    // a full compile.  There should be a better way.
-    field.initializer = null;
-  }
-
-  @override
-  String toString() => field.toString();
-}
-
 /// Visitor to check whether a given type mentions any of a class's type
 /// parameters in a covariant fashion.
 class IncludesTypeParametersCovariantly extends DartTypeVisitor<bool> {
@@ -131,67 +83,6 @@
   }
 }
 
-/// Base class for tracking dependencies during top level type inference.
-///
-/// Fields, accessors, and methods can have their types inferred in a variety of
-/// ways; there will a derived class for each kind of inference.
-abstract class InferenceNode {
-  /// The node currently being evaluated, or `null` if no node is being
-  /// evaluated.
-  static InferenceNode _currentNode;
-
-  /// Indicates whether the type inference corresponding to this node has been
-  /// completed.
-  bool _isResolved = false;
-
-  /// Indicates whether this node participates in a circularity.
-  bool _isCircular = false;
-
-  /// If this node is currently being evaluated, and its evaluation caused a
-  /// recursive call to another node's [resolve] method, a pointer to the latter
-  /// node; otherwise `null`.
-  InferenceNode _nextNode;
-
-  /// Indicates whether this node participates in a circularity.
-  ///
-  /// This may be called at the end of [resolveInternal] to check whether a
-  /// circularity was detected during evaluation.
-  bool get isCircular => _isCircular;
-
-  /// Evaluates this node, properly accounting for circularities.
-  void resolve() {
-    if (_isResolved) return;
-    if (_nextNode != null || identical(_currentNode, this)) {
-      // An accessor depends on itself (possibly by way of intermediate
-      // accessors).  Mark all accessors involved as circular.
-      var node = this;
-      do {
-        node._isCircular = true;
-        node._isResolved = true;
-        node = node._nextNode;
-      } while (node != null);
-    } else {
-      var previousNode = _currentNode;
-      assert(previousNode?._nextNode == null);
-      _currentNode = this;
-      previousNode?._nextNode = this;
-      resolveInternal();
-      assert(identical(_currentNode, this));
-      previousNode?._nextNode = null;
-      _currentNode = previousNode;
-      _isResolved = true;
-    }
-  }
-
-  /// Evaluates this node, possibly by making recursive calls to the [resolve]
-  /// method of this node or other nodes.
-  ///
-  /// Circularity detection is handled by [resolve], which calls this method.
-  /// Once this method has made all recursive calls to [resolve], it may use
-  /// [isCircular] to detect whether a circularity has occurred.
-  void resolveInternal();
-}
-
 /// Keeps track of the global state for the type inference that occurs outside
 /// of method bodies and initializers.
 ///
@@ -201,6 +92,8 @@
 abstract class TypeInferenceEngine {
   ClassHierarchy classHierarchy;
 
+  ClassHierarchyBuilder hierarchyBuilder;
+
   CoreTypes coreTypes;
 
   /// Indicates whether the "prepare" phase of type inference is complete.
@@ -208,8 +101,6 @@
 
   TypeSchemaEnvironment typeSchemaEnvironment;
 
-  final staticInferenceNodes = <FieldInitializerInferenceNode>[];
-
   /// A map containing constructors with initializing formals whose types
   /// need to be inferred.
   ///
@@ -237,21 +128,7 @@
   /// Creates a [TypeInferrer] object which is ready to perform type inference
   /// on the given [field].
   TypeInferrer createTopLevelTypeInferrer(
-      InterfaceType thisType, ShadowField field, KernelLibraryBuilder library);
-
-  /// Retrieve the [TypeInferrer] for the given [field], which was created by
-  /// a previous call to [createTopLevelTypeInferrer].
-  TypeInferrerImpl getFieldTypeInferrer(ShadowField field);
-
-  /// Performs the second phase of top level initializer inference, which is to
-  /// visit all accessors and top level variables that were passed to
-  /// [recordAccessor] in topologically-sorted order and assign their types.
-  void finishTopLevelFields() {
-    for (var node in staticInferenceNodes) {
-      node.resolve();
-    }
-    staticInferenceNodes.clear();
-  }
+      Uri uri, InterfaceType thisType, KernelLibraryBuilder library);
 
   /// Performs the third phase of top level inference, which is to visit all
   /// constructors still needing inference and infer the types of their
@@ -295,20 +172,17 @@
         new TypeSchemaEnvironment(coreTypes, hierarchy);
   }
 
-  /// Records that the given static [field] will need top level type inference.
-  void recordStaticFieldInferenceCandidate(
-      ShadowField field, LibraryBuilder library) {
-    var node = new FieldInitializerInferenceNode(this, field, library);
-    ShadowField.setInferenceNode(field, node);
-    staticInferenceNodes.add(node);
-  }
-
-  static void resolveInferenceNode(Member member) {
-    if (member is ShadowMember) {
-      if (member.inferenceNode != null) {
-        member.inferenceNode.resolve();
-        member.inferenceNode = null;
+  static Member resolveInferenceNode(Member member) {
+    if (member is Field) {
+      DartType type = member.type;
+      if (type is ImplicitFieldType) {
+        if (type.member.target != member) {
+          type.member.inferCopiedType(member);
+        } else {
+          type.member.inferType();
+        }
       }
     }
+    return member;
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index bbe6899..6c30926 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -103,8 +103,6 @@
 import '../kernel/kernel_shadow_ast.dart'
     show
         ExpressionJudgment,
-        ShadowClass,
-        ShadowField,
         ShadowTypeInferenceEngine,
         ShadowTypeInferrer,
         VariableDeclarationJudgment,
@@ -119,8 +117,6 @@
 
 import 'inference_helper.dart' show InferenceHelper;
 
-import 'interface_resolver.dart' show ForwardingNode, SyntheticAccessor;
-
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
 
 import 'type_inference_engine.dart'
@@ -750,7 +746,8 @@
     Class classNode = receiverType is InterfaceType
         ? receiverType.classNode
         : coreTypes.objectClass;
-    Member interfaceMember = _getInterfaceMember(classNode, name, setter);
+    Member interfaceMember =
+        _getInterfaceMember(classNode, name, setter, fileOffset);
     if (instrumented &&
         receiverType != const DynamicType() &&
         interfaceMember != null) {
@@ -911,7 +908,8 @@
     if (calleeType is FunctionType) {
       return calleeType;
     } else if (followCall && calleeType is InterfaceType) {
-      var member = _getInterfaceMember(calleeType.classNode, callName, false);
+      var member =
+          _getInterfaceMember(calleeType.classNode, callName, false, -1);
       var callType = getCalleeType(member, calleeType);
       if (callType is FunctionType) {
         return callType;
@@ -969,7 +967,7 @@
 
   /// Gets the initializer for the given [field], or `null` if there is no
   /// initializer.
-  Expression getFieldInitializer(ShadowField field);
+  Expression getFieldInitializer(Field field);
 
   /// If the [member] is a forwarding stub, return the target it forwards to.
   /// Otherwise return the given [member].
@@ -1160,12 +1158,6 @@
     this.helper = null;
   }
 
-  /// Performs type inference on the given [field]'s initializer expression.
-  ///
-  /// Derived classes should provide an implementation that calls
-  /// [inferExpression] for the given [field]'s initializer expression.
-  DartType inferFieldTopLevel(ShadowField field);
-
   @override
   void inferFunctionBody(InferenceHelper helper, DartType returnType,
       AsyncMarker asyncMarker, Statement body) {
@@ -1454,7 +1446,9 @@
     // Let `N'` be `N[T/S]`.  The [ClosureContext] constructor will adjust
     // accordingly if the closure is declared with `async`, `async*`, or
     // `sync*`.
-    returnContext = substitution.substituteType(returnContext);
+    if (returnContext is! UnknownType) {
+      returnContext = substitution.substituteType(returnContext);
+    }
 
     // Apply type inference to `B` in return context `N’`, with any references
     // to `xi` in `B` having type `Pi`.  This produces `B’`.
@@ -1830,25 +1824,16 @@
     }
   }
 
-  Member _getInterfaceMember(Class class_, Name name, bool setter) {
-    if (class_ is ShadowClass) {
-      var classInferenceInfo = ShadowClass.getClassInferenceInfo(class_);
-      if (classInferenceInfo != null) {
-        var member = ClassHierarchy.findMemberByName(
-            setter
-                ? classInferenceInfo.setters
-                : classInferenceInfo.gettersAndMethods,
-            name);
-        if (member == null) return null;
-        member = member is ForwardingNode ? member.resolve() : member;
-        member = member is SyntheticAccessor
-            ? SyntheticAccessor.getField(member)
-            : member;
-        TypeInferenceEngine.resolveInferenceNode(member);
-        return member;
-      }
+  Member _getInterfaceMember(
+      Class class_, Name name, bool setter, int charOffset) {
+    Member member = engine.hierarchyBuilder.getCombinedMemberSignatureKernel(
+        class_, name, setter, charOffset, library);
+    if (member == null && (library?.isPatch ?? false)) {
+      // TODO(dmitryas): Hack for parts.
+      member ??=
+          classHierarchy.getInterfaceMember(class_, name, setter: setter);
     }
-    return classHierarchy.getInterfaceMember(class_, name, setter: setter);
+    return TypeInferenceEngine.resolveInferenceNode(member);
   }
 
   /// Determines if the given [expression]'s type is precisely known at compile
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index e742fd0..01418ae 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -17,6 +17,8 @@
 import 'package:kernel/text/ast_to_text.dart'
     show Annotator, NameSystem, Printer, globalDebuggingNames;
 
+import '../problems.dart' show unsupported;
+
 /// Determines whether a type schema contains `?` somewhere inside it.
 bool isKnown(DartType schema) => schema.accept(new _IsKnownVisitor());
 
@@ -62,6 +64,9 @@
 /// The unknown type cannot appear in programs or in final inferred types: it is
 /// purely part of the local inference process.
 class UnknownType extends DartType {
+  @override
+  get nullability => unsupported("nullability", -1, null);
+
   const UnknownType();
 
   bool operator ==(Object other) {
diff --git a/pkg/sourcemap_testing/lib/src/annotated_code_helper.dart b/pkg/front_end/lib/src/testing/annotated_code_helper.dart
similarity index 100%
rename from pkg/sourcemap_testing/lib/src/annotated_code_helper.dart
rename to pkg/front_end/lib/src/testing/annotated_code_helper.dart
diff --git a/pkg/front_end/lib/src/testing/id.dart b/pkg/front_end/lib/src/testing/id.dart
new file mode 100644
index 0000000..d8b7b77
--- /dev/null
+++ b/pkg/front_end/lib/src/testing/id.dart
@@ -0,0 +1,282 @@
+// Copyright (c) 2017, 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.
+
+enum IdKind {
+  member,
+  cls,
+  node,
+  invoke,
+  update,
+  iterator,
+  current,
+  moveNext,
+  stmt,
+}
+
+/// Id for a code point or element.
+abstract class Id {
+  IdKind get kind;
+  bool get isGlobal;
+
+  /// Display name for this id.
+  String get descriptor;
+}
+
+class IdValue {
+  final Id id;
+  final String value;
+
+  const IdValue(this.id, this.value);
+
+  @override
+  int get hashCode => id.hashCode * 13 + value.hashCode * 17;
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! IdValue) return false;
+    return id == other.id && value == other.value;
+  }
+
+  @override
+  String toString() => idToString(id, value);
+
+  static String idToString(Id id, String value) {
+    switch (id.kind) {
+      case IdKind.member:
+        MemberId elementId = id;
+        return '$memberPrefix${elementId.name}:$value';
+      case IdKind.cls:
+        ClassId classId = id;
+        return '$classPrefix${classId.name}:$value';
+      case IdKind.node:
+        return value;
+      case IdKind.invoke:
+        return '$invokePrefix$value';
+      case IdKind.update:
+        return '$updatePrefix$value';
+      case IdKind.iterator:
+        return '$iteratorPrefix$value';
+      case IdKind.current:
+        return '$currentPrefix$value';
+      case IdKind.moveNext:
+        return '$moveNextPrefix$value';
+      case IdKind.stmt:
+        return '$stmtPrefix$value';
+    }
+    throw new UnsupportedError("Unexpected id kind: ${id.kind}");
+  }
+
+  static const String globalPrefix = "global#";
+  static const String memberPrefix = "member: ";
+  static const String classPrefix = "class: ";
+  static const String invokePrefix = "invoke: ";
+  static const String updatePrefix = "update: ";
+  static const String iteratorPrefix = "iterator: ";
+  static const String currentPrefix = "current: ";
+  static const String moveNextPrefix = "moveNext: ";
+  static const String stmtPrefix = "stmt: ";
+
+  static IdValue decode(int offset, String text) {
+    Id id;
+    String expected;
+    if (text.startsWith(memberPrefix)) {
+      text = text.substring(memberPrefix.length);
+      int colonPos = text.indexOf(':');
+      if (colonPos == -1) throw "Invalid element id: '$text'";
+      String name = text.substring(0, colonPos);
+      bool isGlobal = name.startsWith(globalPrefix);
+      if (isGlobal) {
+        name = name.substring(globalPrefix.length);
+      }
+      id = new MemberId(name, isGlobal: isGlobal);
+      expected = text.substring(colonPos + 1);
+    } else if (text.startsWith(classPrefix)) {
+      text = text.substring(classPrefix.length);
+      int colonPos = text.indexOf(':');
+      if (colonPos == -1) throw "Invalid class id: '$text'";
+      String name = text.substring(0, colonPos);
+      bool isGlobal = name.startsWith(globalPrefix);
+      if (isGlobal) {
+        name = name.substring(globalPrefix.length);
+      }
+      id = new ClassId(name, isGlobal: isGlobal);
+      expected = text.substring(colonPos + 1);
+    } else if (text.startsWith(invokePrefix)) {
+      id = new NodeId(offset, IdKind.invoke);
+      expected = text.substring(invokePrefix.length);
+    } else if (text.startsWith(updatePrefix)) {
+      id = new NodeId(offset, IdKind.update);
+      expected = text.substring(updatePrefix.length);
+    } else if (text.startsWith(iteratorPrefix)) {
+      id = new NodeId(offset, IdKind.iterator);
+      expected = text.substring(iteratorPrefix.length);
+    } else if (text.startsWith(currentPrefix)) {
+      id = new NodeId(offset, IdKind.current);
+      expected = text.substring(currentPrefix.length);
+    } else if (text.startsWith(moveNextPrefix)) {
+      id = new NodeId(offset, IdKind.moveNext);
+      expected = text.substring(moveNextPrefix.length);
+    } else if (text.startsWith(stmtPrefix)) {
+      id = new NodeId(offset, IdKind.stmt);
+      expected = text.substring(stmtPrefix.length);
+    } else {
+      id = new NodeId(offset, IdKind.node);
+      expected = text;
+    }
+    // Remove newlines.
+    expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
+    return new IdValue(id, expected);
+  }
+}
+
+/// Id for an member element.
+class MemberId implements Id {
+  final String className;
+  final String memberName;
+  @override
+  final bool isGlobal;
+
+  factory MemberId(String text, {bool isGlobal: false}) {
+    int dotPos = text.indexOf('.');
+    if (dotPos != -1) {
+      return new MemberId.internal(text.substring(dotPos + 1),
+          className: text.substring(0, dotPos), isGlobal: isGlobal);
+    } else {
+      return new MemberId.internal(text, isGlobal: isGlobal);
+    }
+  }
+
+  MemberId.internal(this.memberName, {this.className, this.isGlobal: false});
+
+  @override
+  int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! MemberId) return false;
+    return className == other.className && memberName == other.memberName;
+  }
+
+  @override
+  IdKind get kind => IdKind.member;
+
+  String get name => className != null ? '$className.$memberName' : memberName;
+
+  @override
+  String get descriptor => 'member $name';
+
+  @override
+  String toString() => 'member:$name';
+}
+
+/// Id for a class.
+class ClassId implements Id {
+  final String className;
+  @override
+  final bool isGlobal;
+
+  ClassId(this.className, {this.isGlobal: false});
+
+  @override
+  int get hashCode => className.hashCode * 13;
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! ClassId) return false;
+    return className == other.className;
+  }
+
+  @override
+  IdKind get kind => IdKind.cls;
+
+  String get name => className;
+
+  @override
+  String get descriptor => 'class $name';
+
+  @override
+  String toString() => 'class:$name';
+}
+
+/// Id for a code point.
+class NodeId implements Id {
+  final int value;
+  @override
+  final IdKind kind;
+
+  const NodeId(this.value, this.kind);
+
+  @override
+  bool get isGlobal => false;
+
+  @override
+  int get hashCode => value.hashCode * 13 + kind.hashCode * 17;
+
+  @override
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! NodeId) return false;
+    return value == other.value && kind == other.kind;
+  }
+
+  @override
+  String get descriptor => 'offset $value ($kind)';
+
+  @override
+  String toString() => '$kind:$value';
+}
+
+class ActualData<T> {
+  final Id id;
+  final T value;
+  final Uri uri;
+  final int _offset;
+  final Object object;
+
+  ActualData(this.id, this.value, this.uri, this._offset, this.object);
+
+  int get offset {
+    if (id is NodeId) {
+      NodeId nodeId = id;
+      return nodeId.value;
+    } else {
+      return _offset;
+    }
+  }
+
+  String get objectText {
+    return 'object `${'$object'.replaceAll('\n', '')}` (${object.runtimeType})';
+  }
+
+  @override
+  String toString() => 'ActualData(id=$id,value=$value,uri=$uri,'
+      'offset=$offset,object=$objectText)';
+}
+
+abstract class DataRegistry<T> {
+  Map<Id, ActualData<T>> get actualMap;
+
+  void registerValue(Uri uri, int offset, Id id, T value, Object object) {
+    if (actualMap.containsKey(id)) {
+      ActualData<T> existingData = actualMap[id];
+      report(uri, offset, "Duplicate id ${id}, value=$value, object=$object");
+      report(
+          uri,
+          offset,
+          "Duplicate id ${id}, value=${existingData.value}, "
+          "object=${existingData.object}");
+      fail("Duplicate id $id.");
+    }
+    if (value != null) {
+      actualMap[id] = new ActualData<T>(id, value, uri, offset, object);
+    }
+  }
+
+  void report(Uri uri, int offset, String message);
+
+  void fail(String message);
+}
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
new file mode 100644
index 0000000..83007b5
--- /dev/null
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -0,0 +1,264 @@
+// Copyright (c) 2017, 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:kernel/ast.dart';
+import 'id.dart';
+
+/// Compute a canonical [Id] for kernel-based nodes.
+Id computeEntityId(Member node) {
+  String className;
+  if (node.enclosingClass != null) {
+    className = node.enclosingClass.name;
+  }
+  String memberName = node.name.name;
+  if (node is Procedure && node.kind == ProcedureKind.Setter) {
+    memberName += '=';
+  }
+  return new MemberId.internal(memberName, className: className);
+}
+
+TreeNode computeTreeNodeWithOffset(TreeNode node) {
+  while (node != null) {
+    if (node.fileOffset != TreeNode.noOffset) {
+      return node;
+    }
+    node = node.parent;
+  }
+  return null;
+}
+
+/// Abstract visitor for computing data corresponding to a node or element,
+/// and record it with a generic [Id]
+abstract class DataExtractor<T> extends Visitor with DataRegistry<T> {
+  @override
+  final Map<Id, ActualData<T>> actualMap;
+
+  /// Implement this to compute the data corresponding to [member].
+  ///
+  /// If `null` is returned, [member] has no associated data.
+  T computeMemberValue(Id id, Member member);
+
+  /// Implement this to compute the data corresponding to [node].
+  ///
+  /// If `null` is returned, [node] has no associated data.
+  T computeNodeValue(Id id, TreeNode node);
+
+  DataExtractor(this.actualMap);
+
+  void computeForMember(Member member) {
+    MemberId id = computeEntityId(member);
+    if (id == null) return;
+    T value = computeMemberValue(id, member);
+    TreeNode nodeWithOffset = computeTreeNodeWithOffset(member);
+    registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+        id, value, member);
+  }
+
+  void computeForNode(TreeNode node, NodeId id) {
+    if (id == null) return;
+    T value = computeNodeValue(id, node);
+    TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+        id, value, node);
+  }
+
+  NodeId computeDefaultNodeId(TreeNode node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on $node (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.node);
+  }
+
+  NodeId createInvokeId(TreeNode node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${node} (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.invoke);
+  }
+
+  NodeId createUpdateId(TreeNode node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${node} (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.update);
+  }
+
+  NodeId createIteratorId(ForInStatement node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${node} (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.iterator);
+  }
+
+  NodeId createCurrentId(ForInStatement node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${node} (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.current);
+  }
+
+  NodeId createMoveNextId(ForInStatement node) {
+    assert(node.fileOffset != TreeNode.noOffset,
+        "No fileOffset on ${node} (${node.runtimeType})");
+    return new NodeId(node.fileOffset, IdKind.moveNext);
+  }
+
+  NodeId createLabeledStatementId(LabeledStatement node) =>
+      computeDefaultNodeId(node.body);
+  NodeId createLoopId(TreeNode node) => computeDefaultNodeId(node);
+  NodeId createGotoId(TreeNode node) => computeDefaultNodeId(node);
+  NodeId createSwitchId(SwitchStatement node) => computeDefaultNodeId(node);
+  NodeId createSwitchCaseId(SwitchCase node) =>
+      new NodeId(node.expressionOffsets.first, IdKind.node);
+
+  void run(Node root) {
+    root.accept(this);
+  }
+
+  @override
+  defaultNode(Node node) {
+    node.visitChildren(this);
+  }
+
+  @override
+  defaultMember(Member node) {
+    super.defaultMember(node);
+    computeForMember(node);
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    TreeNode receiver = node.receiver;
+    if (receiver is VariableGet &&
+        receiver.variable.parent is FunctionDeclaration) {
+      // This is an invocation of a named local function.
+      computeForNode(node, createInvokeId(node.receiver));
+      node.arguments.accept(this);
+    } else if (node.name.name == '==' &&
+        receiver is VariableGet &&
+        receiver.variable.name == null) {
+      // This is a desugared `?.`.
+    } else if (node.name.name == '[]') {
+      computeForNode(node, computeDefaultNodeId(node));
+      super.visitMethodInvocation(node);
+    } else if (node.name.name == '[]=') {
+      computeForNode(node, createUpdateId(node));
+      super.visitMethodInvocation(node);
+    } else {
+      computeForNode(node, createInvokeId(node));
+      super.visitMethodInvocation(node);
+    }
+  }
+
+  @override
+  visitLoadLibrary(LoadLibrary node) {
+    computeForNode(node, createInvokeId(node));
+  }
+
+  @override
+  visitPropertyGet(PropertyGet node) {
+    computeForNode(node, computeDefaultNodeId(node));
+    super.visitPropertyGet(node);
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    if (node.name != null && node.parent is! FunctionDeclaration) {
+      // Skip synthetic variables and function declaration variables.
+      computeForNode(node, computeDefaultNodeId(node));
+    }
+    super.visitVariableDeclaration(node);
+  }
+
+  @override
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    computeForNode(node, computeDefaultNodeId(node));
+    super.visitFunctionDeclaration(node);
+  }
+
+  @override
+  visitFunctionExpression(FunctionExpression node) {
+    computeForNode(node, computeDefaultNodeId(node));
+    super.visitFunctionExpression(node);
+  }
+
+  @override
+  visitVariableGet(VariableGet node) {
+    if (node.variable.name != null && !node.variable.isFieldFormal) {
+      // Skip use of synthetic variables.
+      computeForNode(node, computeDefaultNodeId(node));
+    }
+    super.visitVariableGet(node);
+  }
+
+  @override
+  visitPropertySet(PropertySet node) {
+    computeForNode(node, createUpdateId(node));
+    super.visitPropertySet(node);
+  }
+
+  @override
+  visitVariableSet(VariableSet node) {
+    if (node.variable.name != null) {
+      // Skip use of synthetic variables.
+      computeForNode(node, createUpdateId(node));
+    }
+    super.visitVariableSet(node);
+  }
+
+  @override
+  visitDoStatement(DoStatement node) {
+    computeForNode(node, createLoopId(node));
+    super.visitDoStatement(node);
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    computeForNode(node, createLoopId(node));
+    super.visitForStatement(node);
+  }
+
+  @override
+  visitForInStatement(ForInStatement node) {
+    computeForNode(node, createLoopId(node));
+    computeForNode(node, createIteratorId(node));
+    computeForNode(node, createCurrentId(node));
+    computeForNode(node, createMoveNextId(node));
+    super.visitForInStatement(node);
+  }
+
+  @override
+  visitWhileStatement(WhileStatement node) {
+    computeForNode(node, createLoopId(node));
+    super.visitWhileStatement(node);
+  }
+
+  @override
+  visitLabeledStatement(LabeledStatement node) {
+    // TODO(johnniwinther): Call computeForNode for label statements that are
+    // not placeholders for loop and switch targets.
+    super.visitLabeledStatement(node);
+  }
+
+  @override
+  visitBreakStatement(BreakStatement node) {
+    computeForNode(node, createGotoId(node));
+    super.visitBreakStatement(node);
+  }
+
+  @override
+  visitSwitchStatement(SwitchStatement node) {
+    computeForNode(node, createSwitchId(node));
+    super.visitSwitchStatement(node);
+  }
+
+  @override
+  visitSwitchCase(SwitchCase node) {
+    if (node.expressionOffsets.isNotEmpty) {
+      computeForNode(node, createSwitchCaseId(node));
+    }
+    super.visitSwitchCase(node);
+  }
+
+  @override
+  visitContinueSwitchStatement(ContinueSwitchStatement node) {
+    computeForNode(node, createGotoId(node));
+    super.visitContinueSwitchStatement(node);
+  }
+}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 8f99626..f1fc567 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -28,6 +28,8 @@
 BadTypeVariableInSupertype/analyzerCode: Fail
 BuiltInIdentifierAsType/example: Fail
 BuiltInIdentifierInDeclaration/example: Fail
+BytecodeLimitExceededTooManyArguments/analyzerCode: Fail
+BytecodeLimitExceededTooManyArguments/example: Fail
 CannotAssignToParenthesizedExpression/example: Fail
 CannotAssignToSuper/example: Fail
 CannotReadPackagesFile/analyzerCode: Fail
@@ -42,7 +44,6 @@
 CantInferPackagesFromPackageUri/analyzerCode: Fail
 CantInferPackagesFromPackageUri/example: Fail
 CantInferTypeDueToCircularity/example: Fail
-CantInferTypeDueToInconsistentOverrides/example: Fail
 CantReadFile/part_wrapped_script: Fail # Importing file in the (now) part.
 CantUseControlFlowOrSpreadAsConstant/example: Fail
 CantUseDeferredPrefixAsConstant/part_wrapped_script: Fail # Importing file in the (now) part.
@@ -252,6 +253,10 @@
 FfiTypeInvalid/analyzerCode: Fail
 FfiTypeMismatch/analyzerCode: Fail
 FfiTypeUnsized/analyzerCode: Fail
+FfiDartTypeMismatch/analyzerCode: Fail
+FfiExtendsOrImplementsSealedClass/analyzerCode: Fail
+FfiStructGeneric/analyzerCode: Fail
+FfiWrongStructInheritance/analyzerCode: Fail
 FieldInitializedOutsideDeclaringClass/part_wrapped_script1: Fail
 FieldInitializedOutsideDeclaringClass/script1: Fail
 FieldInitializerOutsideConstructor/part_wrapped_script1: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index d2b0dac..93da19c 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2926,6 +2926,13 @@
   template: "Can't infer a type for '#name' as some of the inherited members have different types."
   tip: "Try adding an explicit type."
   analyzerCode: INVALID_METHOD_OVERRIDE
+  external: testcases/inference/inconsistent_overrides.dart
+
+CantInferReturnTypeDueToInconsistentOverrides:
+  template: "Can't infer a return type for '#name' as some of the inherited members have different types."
+  tip: "Try adding an explicit type."
+  analyzerCode: INVALID_METHOD_OVERRIDE
+  external: testcases/inference/inconsistent_overrides.dart
 
 CantInferTypeDueToCircularity:
   template: "Can't infer the type of '#string': circularity found during type inference."
@@ -3452,7 +3459,7 @@
 
 FfiFieldAnnotation:
   # Used by dart:ffi
-  template: "Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields."
+  template: "Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi Structs cannot have regular Dart fields."
   external: test/ffi_test.dart
 
 FfiNotStatic:
@@ -3465,9 +3472,24 @@
   template: "Field '#name' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution."
   external: test/ffi_test.dart
 
-FfiStructAnnotation:
+FfiExtendsOrImplementsSealedClass:
   # Used by dart:ffi
-  template: "Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields."
+  template: "Class '#name' cannot be extended or implemented."
+  external: test/ffi_test.dart
+
+FfiStructGeneric:
+  # Used by dart:ffi
+  template: "Struct '#name' should not be generic."
+  external: test/ffi_test.dart
+
+FfiWrongStructInheritance:
+  # Used by dart:ffi
+  template: "Struct '#name' must inherit from 'Struct<#name>'."
+  external: test/ffi_test.dart
+
+FfiDartTypeMismatch:
+  # Used by dart:ffi
+  template: "Expected '#type' to be a subtype of '#type2'."
   external: test/ffi_test.dart
 
 SpreadTypeMismatch:
@@ -3566,3 +3588,22 @@
   script: >
     class Base<T> {}
     class Derived<T> extends Base<Derived<Derived<T>>> {}
+
+BytecodeLimitExceededTooManyArguments:
+  template: "Dart bytecode limit exceeded: too many arguments."
+
+CombinedMemberSignatureFailed:
+  template: "Class '#name' inherits multiple members named '#name2' with incompatible signatures."
+  tip: "Try adding a declaration of '#name2' to '#name'."
+  analyzerCode: INCONSISTENT_INHERITANCE
+  script:
+    - |
+      abstract class I1 {
+        foo(x);
+      }
+
+      abstract class I2 {
+        foo();
+      }
+
+      abstract class C implements I2, I1 {}
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 64e9958..e4593e7 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,19 +1,19 @@
 name: front_end
 # Currently, front_end API is not stable and users should not
 # depend on semver semantics when depending on this package.
-version: 0.1.18
+version: 0.1.20
 author: Dart Team <misc@dartlang.org>
 description: Front end for compilation of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
 environment:
   sdk: '>=2.1.0-dev.5.0 <3.0.0'
 dependencies:
-  kernel: 0.3.18
+  kernel: 0.3.20
   package_config: '^1.0.1'
   path: '^1.3.9'
   yaml: '^2.1.12'
 dev_dependencies:
-  analyzer: 0.36.3
+  analyzer: 0.37.0
   args: '>=0.13.0 <2.0.0'
   build_integration:
     path: ../build_integration
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index c183abd..9d94241 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -10,7 +10,8 @@
 
 import 'dart:io' show File, Platform;
 
-import 'package:kernel/ast.dart' show Library, Component;
+import 'package:kernel/ast.dart'
+    show AwaitExpression, Component, Library, Node, Visitor;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -111,6 +112,10 @@
     "group": "Fail"
   },
   {
+    "name": "TransformVerificationError",
+    "group": "Fail"
+  },
+  {
     "name": "TextSerializationFailure",
     "group": "Fail"
   }
@@ -368,7 +373,7 @@
       UriTranslator uriTranslator = new UriTranslator(
           const TargetLibrariesSpecification('vm'),
           context.uriTranslator.packages);
-      KernelTarget sourceTarget = new KernelTestingTarget(
+      KernelTarget sourceTarget = new KernelTarget(
           StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
       sourceTarget.setEntryPoints(<Uri>[description.uri]);
@@ -422,10 +427,41 @@
     } finally {
       backendTarget.enabled = false;
     }
+    List<String> errors = VerifyTransformed.verify(component);
+    if (errors.isNotEmpty) {
+      return new Result<Component>(
+          component,
+          context.expectationSet["TransformVerificationError"],
+          errors.join('\n'),
+          null);
+    }
     return pass(component);
   }
 }
 
+/// Visitor that checks that the component has been transformed properly.
+// TODO(johnniwinther): Add checks for all nodes that are unsupported after
+// transformation.
+class VerifyTransformed extends Visitor<void> {
+  List<String> errors = [];
+
+  @override
+  void defaultNode(Node node) {
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitAwaitExpression(AwaitExpression node) {
+    errors.add("ERROR: Untransformed await expression: $node");
+  }
+
+  static List<String> verify(Component component) {
+    VerifyTransformed visitor = new VerifyTransformed();
+    component.accept(visitor);
+    return visitor.errors;
+  }
+}
+
 class TestVmTarget extends VmTarget {
   bool enabled = false;
 
@@ -463,15 +499,6 @@
   }
 }
 
-class KernelTestingTarget extends KernelTarget {
-  @override
-  ClassHierarchyBuilder builderHierarchy;
-
-  KernelTestingTarget(StandardFileSystem fileSystem, bool includeComments,
-      DillTarget dillTarget, UriTranslator uriTranslator)
-      : super(fileSystem, includeComments, dillTarget, uriTranslator);
-}
-
 class MatchHierarchy extends Step<Component, Component, FastaContext> {
   const MatchHierarchy();
 
@@ -481,8 +508,8 @@
       Component component, FastaContext context) async {
     Uri uri =
         component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
-    KernelTestingTarget target = context.componentToTarget[component];
-    ClassHierarchyBuilder hierarchy = target.builderHierarchy;
+    KernelTarget target = context.componentToTarget[component];
+    ClassHierarchyBuilder hierarchy = target.loader.builderHierarchy;
     StringBuffer sb = new StringBuffer();
     for (ClassHierarchyNode node in hierarchy.nodes.values) {
       node.toString(sb);
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
deleted file mode 100644
index b19a80f..0000000
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ /dev/null
@@ -1,1049 +0,0 @@
-// Copyright (c) 2017, 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:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:front_end/src/fasta/type_inference/interface_resolver.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/type_algebra.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InterfaceResolverTest);
-  });
-}
-
-@reflectiveTest
-class InterfaceResolverTest {
-  final Library testLib;
-
-  final Component component;
-
-  final CoreTypes coreTypes;
-
-  ClassHierarchy cachedClassHierarchy;
-
-  TypeSchemaEnvironment cachedTypeEnvironment;
-
-  InterfaceResolver cachedInterfaceResolver;
-
-  InterfaceResolverTest()
-      : this._(new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib'),
-            createMockSdkComponent());
-
-  InterfaceResolverTest._(this.testLib, Component component)
-      : component = component..libraries.add(testLib..parent = component),
-        coreTypes = new CoreTypes(component);
-
-  ClassHierarchy get classHierarchy {
-    return cachedClassHierarchy ??= new ClassHierarchy(component);
-  }
-
-  TypeSchemaEnvironment get typeEnvironment {
-    return cachedTypeEnvironment ??=
-        new TypeSchemaEnvironment(coreTypes, classHierarchy);
-  }
-
-  InterfaceResolver get interfaceResolver {
-    return cachedInterfaceResolver ??=
-        new InterfaceResolver(null, typeEnvironment, null);
-  }
-
-  InterfaceType get intType => coreTypes.intClass.rawType;
-
-  Class get listClass => coreTypes.listClass;
-
-  InterfaceType get numType => coreTypes.numClass.rawType;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => objectClass.rawType;
-
-  void checkCandidate(Procedure procedure, bool setter) {
-    var class_ = makeClass(procedures: [procedure]);
-    var candidate = getCandidate(class_, setter);
-    expect(candidate, same(procedure));
-  }
-
-  void checkCandidateOrder(Class class_, Member member) {
-    // Check that InterfaceResolver prioritizes [member]
-    var candidates = getCandidates(class_, false);
-    expect(candidates[0], same(member));
-
-    // Check that both implementations of [ClassHierarchy] prioritize [member]
-    // ahead of [other]
-    void check(ClassHierarchy classHierarchy) {
-      var interfaceMember =
-          classHierarchy.getInterfaceMember(class_, member.name);
-      expect(interfaceMember, same(member));
-    }
-
-    check(new ClassHierarchy(component));
-  }
-
-  Procedure getCandidate(Class class_, bool setter) {
-    var candidates = getCandidates(class_, setter);
-    expect(candidates, hasLength(1));
-    return candidates[0];
-  }
-
-  List<Procedure> getCandidates(Class class_, bool setters) =>
-      interfaceResolver.getCandidates(class_, setters);
-
-  ForwardingNode getForwardingNode(Class class_, bool setter) {
-    var forwardingNodes = getForwardingNodes(class_, setter);
-    expect(forwardingNodes, hasLength(1));
-    return forwardingNodes[0];
-  }
-
-  List<ForwardingNode> getForwardingNodes(Class class_, bool setters) {
-    var forwardingNodes = <ForwardingNode>[];
-    var candidates = getCandidates(class_, setters);
-    InterfaceResolver.forEachApiMember(candidates,
-        (int start, int end, Name name) {
-      forwardingNodes.add(new ForwardingNode(interfaceResolver, null, class_,
-          name, candidates[start].kind, candidates, start, end));
-    });
-    return forwardingNodes;
-  }
-
-  Member getStubTarget(Procedure stub) {
-    var body = stub.function.body;
-    if (body == null) return null;
-    if (body is ReturnStatement) {
-      var expression = body.expression;
-      if (expression is SuperMethodInvocation) {
-        return expression.interfaceTarget;
-      } else if (expression is SuperPropertySet) {
-        return expression.interfaceTarget;
-      } else {
-        fail('Unexpected expression type: ${expression.runtimeType}');
-      }
-    } else {
-      fail('Unexpected body type: ${body.runtimeType}');
-    }
-  }
-
-  Class makeClass(
-      {String name,
-      Supertype supertype,
-      Supertype mixedInType,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes,
-      List<Procedure> procedures,
-      List<Field> fields}) {
-    resetInterfaceResolver();
-    var class_ = new ShadowClass(
-        name: name ?? 'C',
-        supertype: supertype ?? objectClass.asThisSupertype,
-        mixedInType: mixedInType,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes,
-        procedures: procedures,
-        fields: fields);
-    testLib.addClass(class_);
-    return class_;
-  }
-
-  Procedure makeEmptyMethod(
-      {ProcedureKind kind: ProcedureKind.Method,
-      String name: 'foo',
-      List<TypeParameter> typeParameters,
-      List<VariableDeclaration> positionalParameters,
-      List<VariableDeclaration> namedParameters,
-      int requiredParameterCount,
-      DartType returnType: const VoidType(),
-      bool isAbstract: false}) {
-    var body = isAbstract ? null : new ReturnStatement(new NullLiteral());
-    var function = new FunctionNode(body,
-        typeParameters: typeParameters,
-        positionalParameters: positionalParameters,
-        namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount,
-        returnType: returnType);
-    return new ShadowProcedure(new Name(name), kind, function, false,
-        isAbstract: isAbstract);
-  }
-
-  Field makeField(
-      {String name: 'foo',
-      DartType type: const DynamicType(),
-      bool isFinal: false}) {
-    return new Field(new Name(name), type: type, isFinal: isFinal);
-  }
-
-  Procedure makeForwardingStub(Procedure method, bool setter,
-      {Substitution substitution}) {
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var node = getForwardingNode(b, setter);
-    var stub = ForwardingNode.createForwardingStubForTesting(
-        node, substitution ?? Substitution.empty, method);
-    ForwardingNode.createForwardingImplIfNeededForTesting(node, stub.function);
-    return stub;
-  }
-
-  Procedure makeGetter(
-      {String name: 'foo', DartType getterType: const DynamicType()}) {
-    var body = new ReturnStatement(new NullLiteral());
-    var function = new FunctionNode(body, returnType: getterType);
-    return new ShadowProcedure(
-        new Name(name), ProcedureKind.Getter, function, false);
-  }
-
-  Procedure makeSetter(
-      {String name: 'foo',
-      DartType setterType: const DynamicType(),
-      bool isCovariant: false}) {
-    var parameter = new VariableDeclarationJudgment('value', 0,
-        type: setterType, isCovariant: isCovariant);
-    var body = new Block([]);
-    var function = new FunctionNode(body,
-        positionalParameters: [parameter], returnType: const VoidType());
-    return new ShadowProcedure(
-        new Name(name), ProcedureKind.Setter, function, false);
-  }
-
-  void resetInterfaceResolver() {
-    cachedClassHierarchy = null;
-    cachedTypeEnvironment = null;
-    cachedInterfaceResolver = null;
-  }
-
-  void test_candidate_for_field_getter() {
-    var field = makeField();
-    var class_ = makeClass(fields: [field]);
-    var candidate = getCandidate(class_, false);
-    expect(candidate, const TypeMatcher<SyntheticAccessor>());
-    expect(candidate.parent, same(class_));
-    expect(candidate.name, field.name);
-    expect(candidate.kind, ProcedureKind.Getter);
-    expect(candidate.function.positionalParameters, isEmpty);
-    expect(candidate.function.namedParameters, isEmpty);
-    expect(candidate.function.typeParameters, isEmpty);
-  }
-
-  void test_candidate_for_field_setter() {
-    var field = makeField();
-    var class_ = makeClass(fields: [field]);
-    var candidate = getCandidate(class_, true);
-    expect(candidate, const TypeMatcher<SyntheticAccessor>());
-    expect(candidate.parent, same(class_));
-    expect(candidate.name, field.name);
-    expect(candidate.kind, ProcedureKind.Setter);
-    expect(candidate.function.positionalParameters, hasLength(1));
-    expect(candidate.function.positionalParameters[0].name, '_');
-    expect(candidate.function.namedParameters, isEmpty);
-    expect(candidate.function.typeParameters, isEmpty);
-    expect(candidate.function.returnType, const VoidType());
-  }
-
-  void test_candidate_for_getter() {
-    var function = new FunctionNode(null);
-    var getter = new ShadowProcedure(
-        new Name('foo'), ProcedureKind.Getter, function, false);
-    checkCandidate(getter, false);
-  }
-
-  void test_candidate_for_method() {
-    checkCandidate(makeEmptyMethod(), false);
-  }
-
-  void test_candidate_for_setter() {
-    var parameter = new VariableDeclarationJudgment('value', 0);
-    var function = new FunctionNode(null,
-        positionalParameters: [parameter], returnType: const VoidType());
-    var setter = new ShadowProcedure(
-        new Name('foo'), ProcedureKind.Setter, function, false);
-    checkCandidate(setter, true);
-  }
-
-  void test_candidate_from_interface() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', implementedTypes: [a.asThisSupertype]);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_from_mixin() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', mixedInType: a.asThisSupertype);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_from_superclass() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_order_interfaces() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    checkCandidateOrder(c, methodA);
-  }
-
-  void test_candidate_order_mixin_before_superclass() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        mixedInType: b.asThisSupertype);
-    checkCandidateOrder(c, methodB);
-  }
-
-  void test_candidate_order_superclass_before_interface() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    checkCandidateOrder(c, methodA);
-  }
-
-  void test_createForwardingStub_abstract() {
-    var method = makeEmptyMethod(isAbstract: true);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.isAbstract, isTrue);
-    expect(stub.function.body, isNull);
-  }
-
-  void test_createForwardingStub_getter() {
-    var getter = makeGetter(getterType: numType);
-    var stub = makeForwardingStub(getter, false);
-    expect(stub.name, getter.name);
-    expect(stub.kind, ProcedureKind.Getter);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, numType);
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertyGet;
-    expect(expression.name, getter.name);
-    expect(expression.interfaceTarget, same(getter));
-  }
-
-  void test_createForwardingStub_getter_for_field() {
-    var field = makeField(type: numType);
-    var stub = makeForwardingStub(
-        InterfaceResolver.makeCandidate(field, false), false);
-    expect(stub.name, field.name);
-    expect(stub.kind, ProcedureKind.Getter);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, numType);
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertyGet;
-    expect(expression.name, field.name);
-    expect(expression.interfaceTarget, same(field));
-  }
-
-  void test_createForwardingStub_operator() {
-    var operator = makeEmptyMethod(
-        kind: ProcedureKind.Operator,
-        name: '[]=',
-        positionalParameters: [
-          new VariableDeclarationJudgment('index', 0, type: intType),
-          new VariableDeclarationJudgment('value', 0, type: numType)
-        ]);
-    var stub = makeForwardingStub(operator, false);
-    expect(stub.name, operator.name);
-    expect(stub.kind, ProcedureKind.Operator);
-    expect(stub.function.positionalParameters, hasLength(2));
-    expect(stub.function.positionalParameters[0].name,
-        operator.function.positionalParameters[0].name);
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.positionalParameters[1].name,
-        operator.function.positionalParameters[1].name);
-    expect(stub.function.positionalParameters[1].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 2);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperMethodInvocation;
-    expect(expression.name, operator.name);
-    expect(expression.interfaceTarget, same(operator));
-    var arguments = expression.arguments;
-    expect(arguments.positional, hasLength(2));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-    expect((arguments.positional[1] as VariableGet).variable,
-        same(stub.function.positionalParameters[1]));
-  }
-
-  void test_createForwardingStub_optionalNamedParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(namedParameters: [parameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.namedParameters, hasLength(1));
-    expect(stub.function.namedParameters[0].name, 'x');
-    expect(stub.function.namedParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 0);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.named, hasLength(1));
-    expect(arguments.named[0].name, 'x');
-    expect((arguments.named[0].value as VariableGet).variable,
-        same(stub.function.namedParameters[0]));
-  }
-
-  void test_createForwardingStub_optionalPositionalParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(
-        positionalParameters: [parameter], requiredParameterCount: 0);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, 'x');
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 0);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.positional, hasLength(1));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_requiredParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(positionalParameters: [parameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, 'x');
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 1);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.positional, hasLength(1));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_setter() {
-    var setter = makeSetter(setterType: numType);
-    var stub = makeForwardingStub(setter, true);
-    expect(stub.name, setter.name);
-    expect(stub.kind, ProcedureKind.Setter);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name,
-        setter.function.positionalParameters[0].name);
-    expect(stub.function.positionalParameters[0].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 1);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertySet;
-    expect(expression.name, setter.name);
-    expect(expression.interfaceTarget, same(setter));
-    expect((expression.value as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_setter_for_field() {
-    var field = makeField(type: numType);
-    var stub =
-        makeForwardingStub(InterfaceResolver.makeCandidate(field, true), true);
-    expect(stub.name, field.name);
-    expect(stub.kind, ProcedureKind.Setter);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, '_');
-    expect(stub.function.positionalParameters[0].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 1);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertySet;
-    expect(expression.name, field.name);
-    expect(expression.interfaceTarget, same(field));
-    expect((expression.value as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_simple() {
-    var method = makeEmptyMethod();
-    var stub = makeForwardingStub(method, false);
-    expect(stub.name, method.name);
-    expect(stub.kind, ProcedureKind.Method);
-    expect(stub.isAbstract, isFalse);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperMethodInvocation;
-    expect(expression.name, method.name);
-    expect(expression.interfaceTarget, same(method));
-    expect(expression.arguments.positional, isEmpty);
-    expect(expression.arguments.named, isEmpty);
-    expect(expression.arguments.types, isEmpty);
-  }
-
-  void test_createForwardingStub_substitute() {
-    // class C<T> { T foo(T x, {T y}); }
-    var T = new TypeParameter('T', objectType);
-    var x =
-        new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
-    var y =
-        new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(T));
-    var method = makeEmptyMethod(
-        positionalParameters: [x],
-        namedParameters: [y],
-        returnType: new TypeParameterType(T));
-    var substitution = Substitution.fromPairs([T], [intType]);
-    var stub = makeForwardingStub(method, false, substitution: substitution);
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.namedParameters[0].type, intType);
-    expect(stub.function.returnType, intType);
-  }
-
-  void test_createForwardingStub_typeParameter() {
-    var typeParameter = new TypeParameter('T', numType);
-    var method = makeEmptyMethod(typeParameters: [typeParameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.typeParameters, hasLength(1));
-    expect(stub.function.typeParameters[0].name, 'T');
-    expect(stub.function.typeParameters[0].bound, numType);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.types, hasLength(1));
-    var typeArgument = arguments.types[0] as TypeParameterType;
-    expect(typeArgument.parameter, same(stub.function.typeParameters[0]));
-    expect(typeArgument.promotedBound, isNull);
-  }
-
-  void test_createForwardingStub_typeParameter_and_substitution() {
-    // class C<T> { void foo<U>(T x, U y); }
-    var T = new TypeParameter('T', objectType);
-    var U = new TypeParameter('U', objectType);
-    var x =
-        new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
-    var y =
-        new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(U));
-    var method =
-        makeEmptyMethod(typeParameters: [U], positionalParameters: [x, y]);
-    var substitution = Substitution.fromPairs([T], [intType]);
-    var stub = makeForwardingStub(method, false, substitution: substitution);
-    expect(stub.function.positionalParameters[0].type, intType);
-    var stubYType =
-        stub.function.positionalParameters[1].type as TypeParameterType;
-    expect(stubYType.parameter, same(stub.function.typeParameters[0]));
-  }
-
-  void test_createForwardingStub_typeParameter_substituteUses() {
-    // class C { void foo<T>(T x); }
-    var typeParameter = new TypeParameter('T', objectType);
-    var param = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [typeParameter], positionalParameters: [param]);
-    var stub = makeForwardingStub(method, false);
-    var stubXType =
-        stub.function.positionalParameters[0].type as TypeParameterType;
-    expect(stubXType.parameter, same(stub.function.typeParameters[0]));
-  }
-
-  void test_createForwardingStub_typeParameter_substituteUses_fBounded() {
-    // class C { void foo<T extends List<T>>(T x); }
-    var typeParameter = new TypeParameter('T', null);
-    typeParameter.bound =
-        new InterfaceType(listClass, [new TypeParameterType(typeParameter)]);
-    var param = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [typeParameter], positionalParameters: [param]);
-    var stub = makeForwardingStub(method, false);
-    var stubTypeParameter = stub.function.typeParameters[0];
-    var stubTypeParameterBound = stubTypeParameter.bound as InterfaceType;
-    var stubTypeParameterBoundArg =
-        stubTypeParameterBound.typeArguments[0] as TypeParameterType;
-    expect(stubTypeParameterBoundArg.parameter, same(stubTypeParameter));
-    var stubXType =
-        stub.function.positionalParameters[0].type as TypeParameterType;
-    expect(stubXType.parameter, same(stubTypeParameter));
-  }
-
-  void test_direct_isGenericCovariant() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var u = new TypeParameter('U', new TypeParameterType(typeParameter))
-      ..isGenericCovariantImpl = true;
-    var x = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var y = new VariableDeclarationJudgment('y', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [u], positionalParameters: [x], namedParameters: [y]);
-    var class_ =
-        makeClass(typeParameters: [typeParameter], procedures: [method]);
-    var node = getForwardingNode(class_, false);
-    ShadowClass.setBuilder(class_, null);
-    var resolvedMethod = node.finalize();
-    expect(resolvedMethod, same(method));
-    expect(u.isGenericCovariantImpl, isTrue);
-    expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isCovariant, isFalse);
-    expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isCovariant, isFalse);
-  }
-
-  void test_direct_isGenericCovariant_field() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var field = makeField(type: new TypeParameterType(typeParameter));
-    var class_ = makeClass(typeParameters: [typeParameter], fields: [field]);
-    var node = getForwardingNode(class_, true);
-    ShadowClass.setBuilder(class_, null);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(field));
-    expect(field.isGenericCovariantImpl, isTrue);
-    expect(field.isCovariant, isFalse);
-  }
-
-  void test_field_isCovariant_inherited() {
-    var fieldA = makeField(type: numType)..isCovariant = true;
-    var fieldB = makeField(type: numType);
-    var a = makeClass(name: 'A', fields: [fieldA]);
-    var b = makeClass(
-        name: 'B', implementedTypes: [a.asThisSupertype], fields: [fieldB]);
-    var node = getForwardingNode(b, true);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
-    expect(fieldB.isGenericCovariantImpl, isFalse);
-    expect(fieldB.isCovariant, isTrue);
-  }
-
-  void test_field_isGenericCovariantImpl_inherited() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var fieldA = makeField(type: new TypeParameterType(typeParameter))
-      ..isGenericCovariantImpl = true;
-    var fieldB = makeField(type: numType);
-    var a =
-        makeClass(name: 'A', typeParameters: [typeParameter], fields: [fieldA]);
-    var b = makeClass(name: 'B', implementedTypes: [
-      new Supertype(a, [numType])
-    ], fields: [
-      fieldB
-    ]);
-    var node = getForwardingNode(b, true);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
-    expect(fieldB.isGenericCovariantImpl, isTrue);
-    expect(fieldB.isCovariant, isFalse);
-  }
-
-  void test_forwardingNodes_multiple() {
-    var methodAf = makeEmptyMethod(name: 'f');
-    var methodBf = makeEmptyMethod(name: 'f');
-    var methodAg = makeEmptyMethod(name: 'g');
-    var methodBg = makeEmptyMethod(name: 'g');
-    var a = makeClass(name: 'A', procedures: [methodAf, methodAg]);
-    var b = makeClass(
-        name: 'B',
-        supertype: a.asThisSupertype,
-        procedures: [methodBf, methodBg]);
-    var forwardingNodes = getForwardingNodes(b, false);
-    expect(forwardingNodes, hasLength(2));
-    var nodef = ClassHierarchy.findMemberByName(forwardingNodes, methodAf.name);
-    var nodeg = ClassHierarchy.findMemberByName(forwardingNodes, methodAg.name);
-    expect(nodef, isNot(same(nodeg)));
-    expect(nodef.parent, b);
-    expect(nodeg.parent, b);
-    {
-      var candidates = ForwardingNode.getCandidates(nodef);
-      expect(candidates, hasLength(2));
-      expect(candidates[0], same(methodBf));
-      expect(candidates[1], same(methodAf));
-    }
-    {
-      var candidates = ForwardingNode.getCandidates(nodeg);
-      expect(candidates, hasLength(2));
-      expect(candidates[0], same(methodBg));
-      expect(candidates[1], same(methodAg));
-    }
-  }
-
-  void test_forwardingNodes_single() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
-    var forwardingNodes = getForwardingNodes(b, false);
-    expect(forwardingNodes, hasLength(1));
-    expect(forwardingNodes[0].parent, b);
-    expect(forwardingNodes[0].name, methodA.name);
-    var candidates = ForwardingNode.getCandidates(forwardingNodes[0]);
-    expect(candidates, hasLength(2));
-    expect(candidates[0], same(methodB));
-    expect(candidates[1], same(methodA));
-  }
-
-  void test_forwardingStub_isCovariant_inherited() {
-    var methodA = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: numType)
-    ]);
-    var methodB = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: intType)..isCovariant = true
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: intType)..isCovariant = true
-    ]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    var x = stub.function.positionalParameters[0];
-    expect(x.isGenericCovariantImpl, isFalse);
-    expect(x.isCovariant, isTrue);
-    var y = stub.function.namedParameters[0];
-    expect(y.isGenericCovariantImpl, isFalse);
-    expect(y.isCovariant, isTrue);
-    expect(stub.forwardingStubInterfaceTarget, same(methodA));
-    expect(getStubTarget(stub), same(methodA));
-  }
-
-  void test_forwardingStub_isGenericCovariantImpl_inherited() {
-    var methodA = makeEmptyMethod(typeParameters: [
-      new TypeParameter('U', numType)
-    ], positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: numType)
-    ]);
-    var typeParameterB = new TypeParameter('T', objectType);
-    var methodB = makeEmptyMethod(typeParameters: [
-      new TypeParameter('U', new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ], positionalParameters: [
-      new VariableDeclarationJudgment('x', 0,
-          type: new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0,
-          type: new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParameterB], procedures: [methodB]);
-    var c =
-        makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
-      new Supertype(b, [numType])
-    ]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    var u = stub.function.typeParameters[0];
-    expect(u.isGenericCovariantImpl, isTrue);
-    var x = stub.function.positionalParameters[0];
-    expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isCovariant, isFalse);
-    var y = stub.function.namedParameters[0];
-    expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isCovariant, isFalse);
-    expect(stub.forwardingStubInterfaceTarget, same(methodA));
-    expect(getStubTarget(stub), same(methodA));
-  }
-
-  void test_interfaceTarget_cascaded() {
-    var methodC = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: intType),
-      new VariableDeclaration('y', type: intType)
-    ]);
-    var c = makeClass(name: 'C', procedures: [methodC]);
-    var t = new TypeParameter('T', objectType);
-    var methodI1 = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: new TypeParameterType(t))
-        ..isGenericCovariantImpl = true,
-      new VariableDeclaration('y', type: intType)
-    ]);
-    var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [methodI1]);
-    // Let's say D was previously compiled, so it already has a forwarding stub
-    var d =
-        makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
-      new Supertype(i1, [intType])
-    ]);
-    var nodeD = getForwardingNode(d, false);
-    var methodD = ForwardingNode.createForwardingStubForTesting(
-        nodeD, Substitution.empty, methodC);
-    d.addMember(methodD);
-    ForwardingNode.createForwardingImplIfNeededForTesting(
-        nodeD, methodD.function);
-    // To ensure that we don't accidentally make use of information that was
-    // computed prior to adding the forwarding stub, reset the interface
-    // resolver.
-    resetInterfaceResolver();
-    var u = new TypeParameter('U', objectType);
-    var methodI2 = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: intType),
-      new VariableDeclaration('y', type: new TypeParameterType(u))
-        ..isGenericCovariantImpl = true
-    ]);
-    var i2 = makeClass(name: 'I2', typeParameters: [u], procedures: [methodI2]);
-    var e =
-        makeClass(name: 'E', supertype: d.asThisSupertype, implementedTypes: [
-      new Supertype(i2, [intType])
-    ]);
-    var nodeE = getForwardingNode(e, false);
-    var stub = nodeE.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodC));
-    expect(getStubTarget(stub), same(methodC));
-  }
-
-  void test_interfaceTarget_cascaded_setter() {
-    var setterC = makeSetter(setterType: intType);
-    var c = makeClass(name: 'C', procedures: [setterC]);
-    var t = new TypeParameter('T', objectType);
-    var setterI1 = makeSetter(setterType: new TypeParameterType(t));
-    var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [setterI1]);
-    // Let's say D was previously compiled, so it already has a forwarding stub
-    var d =
-        makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
-      new Supertype(i1, [intType])
-    ]);
-    var nodeD = getForwardingNode(d, true);
-    var setterD = ForwardingNode.createForwardingStubForTesting(
-        nodeD, Substitution.empty, setterC);
-    d.addMember(setterD);
-    ForwardingNode.createForwardingImplIfNeededForTesting(
-        nodeD, setterD.function);
-    // To ensure that we don't accidentally make use of information that was
-    // computed prior to adding the forwarding stub, reset the interface
-    // resolver.
-    resetInterfaceResolver();
-    var setterI2 = makeSetter(setterType: intType, isCovariant: true);
-    var i2 = makeClass(name: 'I2', procedures: [setterI2]);
-    var e = makeClass(
-        name: 'E',
-        supertype: d.asThisSupertype,
-        implementedTypes: [i2.asThisSupertype]);
-    var nodeE = getForwardingNode(e, true);
-    var stub = nodeE.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(setterC));
-    expect(getStubTarget(stub), same(setterC));
-  }
-
-  void test_interfaceTarget_field() {
-    var fieldA = makeField(type: numType, isFinal: true);
-    var fieldB = makeField(type: intType, isFinal: true);
-    var a = makeClass(name: 'A', fields: [fieldA]);
-    var b = makeClass(name: 'B', fields: [fieldB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(fieldB));
-  }
-
-  void test_merge_candidates_including_mixin() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var methodC = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(name: 'C', procedures: [methodC]);
-    var d = makeClass(
-        name: 'D',
-        supertype: a.asThisSupertype,
-        mixedInType: b.asThisSupertype,
-        implementedTypes: [c.asThisSupertype]);
-    var candidates = getCandidates(d, false);
-    expect(candidates, hasLength(3));
-    expect(candidates[0], same(methodB));
-    expect(candidates[1], same(methodA));
-    expect(candidates[2], same(methodC));
-  }
-
-  void test_merge_candidates_not_including_mixin() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var methodC = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype],
-        procedures: [methodC]);
-    var candidates = getCandidates(c, false);
-    expect(candidates, hasLength(3));
-    expect(candidates[0], same(methodC));
-    expect(candidates[1], same(methodA));
-    expect(candidates[2], same(methodB));
-  }
-
-  void test_resolve_directly_declared() {
-    var parameterA = new VariableDeclarationJudgment('x', 0,
-        type: objectType, isCovariant: true);
-    var methodA = makeEmptyMethod(positionalParameters: [parameterA]);
-    var parameterB = new VariableDeclarationJudgment('x', 0,
-        type: intType, isCovariant: true);
-    var methodB = makeEmptyMethod(positionalParameters: [parameterB]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
-    var node = getForwardingNode(b, false);
-    expect(node.finalize(), same(methodB));
-  }
-
-  void test_resolve_favor_first() {
-    // When multiple methods have equivalent types, favor the first one.
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    expect(node.finalize(), same(methodA));
-  }
-
-  void test_resolve_field() {
-    var field = makeField();
-    var a = makeClass(name: 'A', fields: [field]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var node = getForwardingNode(b, false);
-    var accessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(accessor), same(field));
-  }
-
-  void test_resolve_first() {
-    var methodA = makeEmptyMethod(returnType: intType);
-    var methodB = makeEmptyMethod(returnType: numType);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    expect(node.finalize(), same(methodA));
-  }
-
-  void test_resolve_second() {
-    var methodA = makeEmptyMethod(returnType: numType);
-    var methodB = makeEmptyMethod(returnType: intType);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.returnType, intType);
-  }
-
-  void test_resolve_setters() {
-    var setterA = makeSetter(setterType: intType);
-    var setterB = makeSetter(setterType: objectType);
-    var setterC = makeSetter(setterType: numType);
-    var a = makeClass(name: 'A', procedures: [setterA]);
-    var b = makeClass(name: 'B', procedures: [setterB]);
-    var c = makeClass(name: 'C', procedures: [setterC]);
-    var d = makeClass(name: 'D', implementedTypes: [
-      a.asThisSupertype,
-      b.asThisSupertype,
-      c.asThisSupertype
-    ]);
-    var node = getForwardingNode(d, true);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(setterB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.positionalParameters[0].type, objectType);
-  }
-
-  void test_resolve_with_added_implementation() {
-    var methodA = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ]);
-    var typeParamB = new TypeParameter('T', objectType);
-    var methodB = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0,
-          type: new TypeParameterType(typeParamB))
-        ..isGenericCovariantImpl = true
-    ]);
-    var methodC = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], isAbstract: true);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
-    var c =
-        makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
-      new Supertype(b, [numType])
-    ], procedures: [
-      methodC
-    ]);
-    var node = getForwardingNode(c, false);
-    expect(methodC.function.body, isNull);
-    var resolvedMethod = node.finalize();
-    expect(resolvedMethod, same(methodC));
-    expect(methodC.function.body, isNotNull);
-    expect(methodC.forwardingStubInterfaceTarget, isNull);
-    expect(getStubTarget(methodC), same(methodA));
-  }
-
-  void test_resolve_with_substitutions() {
-    var typeParamA = new TypeParameter('T', objectType);
-    var typeParamB = new TypeParameter('T', objectType);
-    var typeParamC = new TypeParameter('T', objectType);
-    var methodA =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamA));
-    var methodB =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamB));
-    var methodC =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamC));
-    var a = makeClass(
-        name: 'A', typeParameters: [typeParamA], procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', typeParameters: [typeParamC], procedures: [methodC]);
-    var d = makeClass(
-        name: 'D',
-        supertype: new Supertype(a, [objectType]),
-        implementedTypes: [
-          new Supertype(b, [intType]),
-          new Supertype(c, [numType])
-        ]);
-    var node = getForwardingNode(d, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.returnType, intType);
-  }
-}
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser.dart b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
index 6d92bac..128559f 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
@@ -161,14 +161,14 @@
       } else if (kernelArguments.length != typeVariables.length) {
         throw "Expected ${typeVariables.length} type arguments: $node";
       }
-      return new InterfaceType(declaration, kernelArguments);
+      return new InterfaceType(declaration, kernelArguments, node.nullability);
     } else if (declaration is TypeParameter) {
       if (arguments.isNotEmpty) {
         throw "Type variable can't have arguments (${node.name})";
       }
-      return new TypeParameterType(declaration);
+      return new TypeParameterType(declaration, null, node.nullability);
     } else if (declaration is Typedef) {
-      return new TypedefType(declaration, kernelArguments);
+      return new TypedefType(declaration, kernelArguments, node.nullability);
     } else {
       throw "Unhandled ${declaration.runtimeType}";
     }
@@ -263,7 +263,8 @@
     return new FunctionType(positionalParameters, returnType,
         namedParameters: namedParameters,
         requiredParameterCount: node.arguments.required.length,
-        typeParameters: parameterEnvironment.parameters);
+        typeParameters: parameterEnvironment.parameters,
+        nullability: node.nullability);
   }
 
   VoidType visitVoidType(ParsedVoidType node, KernelEnvironment environment) {
@@ -280,7 +281,7 @@
     TypeParameterType type =
         node.a.accept<Node, KernelEnvironment>(this, environment);
     DartType bound = node.b.accept<Node, KernelEnvironment>(this, environment);
-    return new TypeParameterType(type.parameter, bound);
+    return new TypeParameterType(type.parameter, bound, type.nullability);
   }
 
   Supertype toSupertype(InterfaceType type) {
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index 2911257..37a45fd 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -412,5 +412,16 @@
     isSubtype("({int c, int b, int a}) -> void", "({int b, int c}) -> void");
     isSubtype("({int a, int b, int c}) -> void", "({int c}) -> void");
     isSubtype("({int c, int b, int a}) -> void", "({int c}) -> void");
+
+    // Parsing of nullable and legacy types.
+    isSubtype("int?", "int?");
+    isSubtype("int*", "int*");
+    isSubtype("(int) ->? int", "(int) ->? int");
+    isSubtype("(int) ->* int", "(int) ->* int");
+    isSubtype("(int, int*, int?) -> int?", "(int, int*, int?) -> int?");
+    isSubtype("List<int>?", "List<int>?");
+    isSubtype("List<int?>?", "List<int?>?");
+    isSubtype("T & int?", "T & int?", typeParameters: "T extends Object?");
+    isSubtype("T? & int?", "T? & int?", typeParameters: "T extends Object");
   }
 }
diff --git a/pkg/front_end/test/fasta/types/type_parser.dart b/pkg/front_end/test/fasta/types/type_parser.dart
index 89a21b7..9a6281e 100644
--- a/pkg/front_end/test/fasta/types/type_parser.dart
+++ b/pkg/front_end/test/fasta/types/type_parser.dart
@@ -2,6 +2,8 @@
 // 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:kernel/ast.dart" show Nullability;
+
 import "package:front_end/src/fasta/scanner.dart" show scanString, Token;
 
 import "package:front_end/src/fasta/parser/type_info_impl.dart"
@@ -16,7 +18,9 @@
 
   final List<ParsedType> arguments;
 
-  ParsedInterfaceType(this.name, this.arguments);
+  final Nullability nullability;
+
+  ParsedInterfaceType(this.name, this.arguments, this.nullability);
 
   String toString() {
     StringBuffer sb = new StringBuffer();
@@ -116,7 +120,10 @@
 
   final ParsedArguments arguments;
 
-  ParsedFunctionType(this.typeVariables, this.returnType, this.arguments);
+  final Nullability nullability;
+
+  ParsedFunctionType(
+      this.typeVariables, this.returnType, this.arguments, this.nullability);
 
   String toString() {
     StringBuffer sb = new StringBuffer();
@@ -260,6 +267,16 @@
     }
   }
 
+  Nullability parseNullability() {
+    Nullability result = Nullability.nonNullable;
+    if (optionalAdvance("?")) {
+      result = Nullability.nullable;
+    } else if (optionalAdvance("*")) {
+      result = Nullability.legacy;
+    }
+    return result;
+  }
+
   ParsedType parseType() {
     if (optional("class")) return parseClass();
     if (optional("typedef")) return parseTypedef();
@@ -269,7 +286,9 @@
       if (optional("(") || optional("<")) {
         type = parseFunctionType();
       } else if (optionalAdvance("void")) {
-        type = new ParsedInterfaceType("void", <ParsedType>[]);
+        type = new ParsedInterfaceType(
+            "void", <ParsedType>[], Nullability.nullable);
+        optionalAdvance("?");
       } else {
         String name = parseName();
         List<ParsedType> arguments = <ParsedType>[];
@@ -283,7 +302,8 @@
           peek = splitCloser(peek) ?? peek;
           expect(">");
         }
-        type = new ParsedInterfaceType(name, arguments);
+        Nullability nullability = parseNullability();
+        type = new ParsedInterfaceType(name, arguments, nullability);
       }
       if (result == null) {
         result = type;
@@ -304,8 +324,10 @@
     ParsedArguments arguments = parseArguments();
     expect("-");
     expect(">");
+    Nullability nullability = parseNullability();
     ParsedType returnType = parseReturnType();
-    return new ParsedFunctionType(typeVariables, returnType, arguments);
+    return new ParsedFunctionType(
+        typeVariables, returnType, arguments, nullability);
   }
 
   String parseName() {
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
index c39739d..93c39b2 100644
--- a/pkg/front_end/test/incremental_bulk_compiler_full.dart
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -51,7 +51,7 @@
   IncrementalCompiler compiler;
 }
 
-CompilerOptions getOptions(bool strong) {
+CompilerOptions getOptions() {
   final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
   var options = new CompilerOptions()
     ..sdkRoot = sdkRoot
@@ -59,13 +59,8 @@
     ..omitPlatform = true
     ..onDiagnostic = (DiagnosticMessage message) {
       // Ignored.
-    }
-    ..legacyMode = !strong;
-  if (strong) {
-    options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
-  } else {
-    options.sdkSummary = sdkRoot.resolve("vm_platform.dill");
-  }
+    };
+  options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
   return options;
 }
 
@@ -83,7 +78,7 @@
     List<int> oneShotSerialized;
     try {
       IncrementalCompiler compiler =
-          new IncrementalKernelGenerator(getOptions(true), uri);
+          new IncrementalKernelGenerator(getOptions(), uri);
       oneShotSerialized = util.postProcess(await compiler.computeDelta());
     } catch (e) {
       oneShotFailed = true;
@@ -95,8 +90,7 @@
     try {
       globalDebuggingNames = new NameSystem();
       if (context.compiler == null) {
-        context.compiler =
-            new IncrementalKernelGenerator(getOptions(true), uri);
+        context.compiler = new IncrementalKernelGenerator(getOptions(), uri);
       }
       Component bulkCompiledComponent = await context.compiler
           .computeDelta(entryPoints: [uri], fullComponent: true);
@@ -111,8 +105,7 @@
     try {
       globalDebuggingNames = new NameSystem();
       if (context.compiler == null) {
-        context.compiler =
-            new IncrementalKernelGenerator(getOptions(true), uri);
+        context.compiler = new IncrementalKernelGenerator(getOptions(), uri);
       }
       Component bulkCompiledComponent = await context.compiler
           .computeDelta(entryPoints: [uri], fullComponent: true);
diff --git a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
index cf270cb..f1469a1 100644
--- a/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_dart2js_load_from_dill_test.dart
@@ -3,16 +3,21 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async' show Future;
+
 import 'dart:io' show Directory, File;
 
 import 'package:expect/expect.dart' show Expect;
+
 import 'package:front_end/src/compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
+
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
+
 import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/target/targets.dart';
 
 import 'incremental_load_from_dill_test.dart'
-    show normalCompile, initializedCompile, checkIsEqual;
+    show checkIsEqual, getOptions, initializedCompile, normalCompile;
 
 Directory outDir;
 
@@ -36,13 +41,16 @@
   Uri nonexisting = outDir.uri.resolve("dart2js.nonexisting.dill");
 
   // Compile dart2js without initializing from dill.
+  // Note: Use none-target to avoid mismatches in "interface target" caused by
+  // type inference occurring before or after mixin transformation.
   Stopwatch stopwatch = new Stopwatch()..start();
-  await normalCompile(dart2jsUrl, normalDill);
+  await normalCompile(dart2jsUrl, normalDill,
+      options: getOptions()..target = new NoneTarget(new TargetFlags()));
   print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
   {
     // Check that we don't include the source from files from the sdk.
     final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
-    Uri platformUri = sdkRoot.resolve("vm_platform.dill");
+    Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
     Component cSdk = new Component();
     new BinaryBuilder(new File.fromUri(platformUri).readAsBytesSync(),
             disableLazyReading: false)
@@ -65,7 +73,7 @@
   }
 
   // Compile dart2js, initializing from the just-compiled dill,
-  // a nonexisting file and a dill file that isn't valid.
+  // a nonexisting file.
   for (List<Object> initializationData in [
     [normalDill, true],
     [nonexisting, false],
@@ -74,7 +82,8 @@
     bool initializeExpect = initializationData[1];
     stopwatch.reset();
     bool initializeResult = await initializedCompile(
-        dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri]);
+        dart2jsUrl, fullDillFromInitialized, initializeWith, [invalidateUri],
+        options: getOptions()..target = new NoneTarget(new TargetFlags()));
     Expect.equals(initializeResult, initializeExpect);
     print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
         "took ${stopwatch.elapsedMilliseconds} ms");
@@ -88,7 +97,8 @@
     // Also try without invalidating anything.
     stopwatch.reset();
     initializeResult = await initializedCompile(
-        dart2jsUrl, fullDillFromInitialized, initializeWith, []);
+        dart2jsUrl, fullDillFromInitialized, initializeWith, [],
+        options: getOptions()..target = new NoneTarget(new TargetFlags()));
     Expect.equals(initializeExpect, initializeResult);
     print("Initialized compile(s) from ${initializeWith.pathSegments.last} "
         "took ${stopwatch.elapsedMilliseconds} ms");
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index a2ec791..3c68a61 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -116,14 +116,12 @@
         await basicTest(
           map["sources"],
           map["entry"],
-          map["strong"],
           map["invalidate"],
           data.outDir,
         );
         break;
       case "newworld":
         await newWorldTest(
-          map["strong"],
           map["worlds"],
           map["modules"],
           map["omitPlatform"],
@@ -136,7 +134,7 @@
   }
 }
 
-Future<Null> basicTest(YamlMap sourceFiles, String entryPoint, bool strong,
+Future<Null> basicTest(YamlMap sourceFiles, String entryPoint,
     YamlList invalidate, Directory outDir) async {
   Uri entryPointUri = outDir.uri.resolve(entryPoint);
   Set<String> invalidateFilenames =
@@ -169,7 +167,7 @@
   Uri initializedOutput = outDir.uri.resolve("full_from_initialized.dill");
 
   Stopwatch stopwatch = new Stopwatch()..start();
-  CompilerOptions options = getOptions(strong);
+  CompilerOptions options = getOptions();
   if (packagesUri != null) {
     options.packagesFileUri = packagesUri;
   }
@@ -177,7 +175,7 @@
   print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
 
   stopwatch.reset();
-  options = getOptions(strong);
+  options = getOptions();
   if (packagesUri != null) {
     options.packagesFileUri = packagesUri;
   }
@@ -196,7 +194,7 @@
 }
 
 Future<Map<String, List<int>>> createModules(
-    Map module, final List<int> sdkSummaryData, bool strong) async {
+    Map module, final List<int> sdkSummaryData) async {
   final Uri base = Uri.parse("org-dartlang-test:///");
   final Uri sdkSummary = base.resolve("vm_platform.dill");
 
@@ -227,7 +225,7 @@
         moduleSources.add(uri);
       }
     }
-    CompilerOptions options = getOptions(strong);
+    CompilerOptions options = getOptions();
     options.fileSystem = fs;
     options.sdkRoot = null;
     options.sdkSummary = sdkSummary;
@@ -261,18 +259,12 @@
   return moduleResult;
 }
 
-Future<Null> newWorldTest(
-    bool strong, List worlds, Map modules, bool omitPlatform) async {
+Future<Null> newWorldTest(List worlds, Map modules, bool omitPlatform) async {
   final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
   final Uri base = Uri.parse("org-dartlang-test:///");
   final Uri sdkSummary = base.resolve("vm_platform.dill");
   final Uri initializeFrom = base.resolve("initializeFrom.dill");
-  Uri platformUri;
-  if (strong) {
-    platformUri = sdkRoot.resolve("vm_platform_strong.dill");
-  } else {
-    platformUri = sdkRoot.resolve("vm_platform.dill");
-  }
+  Uri platformUri = sdkRoot.resolve("vm_platform_strong.dill");
   final List<int> sdkSummaryData =
       await new File.fromUri(platformUri).readAsBytes();
 
@@ -287,7 +279,7 @@
   Map<String, Component> moduleComponents;
   Component sdk;
   if (modules != null) {
-    moduleData = await createModules(modules, sdkSummaryData, strong);
+    moduleData = await createModules(modules, sdkSummaryData);
     sdk = newestWholeComponent = new Component();
     new BinaryBuilder(sdkSummaryData, filename: null, disableLazyReading: false)
         .readComponent(newestWholeComponent);
@@ -368,7 +360,7 @@
     }
 
     if (brandNewWorld) {
-      options = getOptions(strong);
+      options = getOptions();
       options.fileSystem = fs;
       options.sdkRoot = null;
       options.sdkSummary = sdkSummary;
@@ -745,11 +737,11 @@
   Expect.equals(a.length, b.length);
 }
 
-CompilerOptions getOptions(bool strong) {
+CompilerOptions getOptions() {
   final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
   CompilerOptions options = new CompilerOptions()
     ..sdkRoot = sdkRoot
-    ..target = new VmTarget(new TargetFlags(legacyMode: !strong))
+    ..target = new VmTarget(new TargetFlags())
     ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
     ..omitPlatform = true
     ..onDiagnostic = (DiagnosticMessage message) {
@@ -758,19 +750,14 @@
         Expect.fail(
             "Unexpected error: ${message.plainTextFormatted.join('\n')}");
       }
-    }
-    ..legacyMode = !strong;
-  if (strong) {
-    options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
-  } else {
-    options.sdkSummary = sdkRoot.resolve("vm_platform.dill");
-  }
+    };
+  options.sdkSummary = sdkRoot.resolve("vm_platform_strong.dill");
   return options;
 }
 
 Future<bool> normalCompile(Uri input, Uri output,
     {CompilerOptions options}) async {
-  options ??= getOptions(false);
+  options ??= getOptions();
   TestIncrementalCompiler compiler =
       new TestIncrementalCompiler(options, input);
   Component component = await compiler.computeDelta();
@@ -783,7 +770,7 @@
 Future<bool> initializedCompile(
     Uri input, Uri output, Uri initializeWith, List<Uri> invalidateUris,
     {CompilerOptions options}) async {
-  options ??= getOptions(false);
+  options ??= getOptions();
   TestIncrementalCompiler compiler =
       new TestIncrementalCompiler(options, input, initializeWith);
   for (Uri invalidateUri in invalidateUris) {
diff --git a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
index 0d9a84e..f108317 100644
--- a/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_invalid_dill_test.dart
@@ -132,7 +132,7 @@
     errorMessages = <DiagnosticMessage>[];
     warningMessages = <DiagnosticMessage>[];
     fs = new MemoryFileSystem(base);
-    options = getOptions(true);
+    options = getOptions();
 
     options.fileSystem = fs;
     options.sdkRoot = null;
diff --git a/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
index 231e9e1..99a7137 100644
--- a/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
@@ -288,7 +288,7 @@
     Object._simpleInstanceOf
     B.bMethod
     Object._instanceOf
-    MyMock1.noSuchMethod
+    MyMock2.MyMock1.noSuchMethod%MyMock2.noSuchMethod
     A.abstractMethod
     Object._identityHashCode
     Object.hashCode
@@ -308,7 +308,7 @@
     Object._simpleInstanceOf
     B.bMethod
     Object._instanceOf
-    MyMock1.noSuchMethod
+    MyMock2.MyMock1.noSuchMethod%MyMock2.noSuchMethod
     A.abstractMethod
     Interface1.interfaceMethod1
     Object._identityHashCode
@@ -338,7 +338,7 @@
     Object._simpleInstanceOf
     B.bMethod
     Object._instanceOf
-    Object.noSuchMethod
+    MyMock3.Object.noSuchMethod%MyMock3.noSuchMethod
     A.abstractMethod
     Object._identityHashCode
     Object.hashCode
@@ -358,7 +358,7 @@
     Object._simpleInstanceOf
     B.bMethod
     Object._instanceOf
-    Object.noSuchMethod
+    MyMock3.Object.noSuchMethod%MyMock3.noSuchMethod
     A.abstractMethod
     Interface1.interfaceMethod1
     Object._identityHashCode
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
index 5a3c3d0..0322fcb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
@@ -194,7 +194,7 @@
   synthetic constructor •() → self::MyMock1
     : super self::B::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return null;
   no-such-method-forwarder method interfaceMethod2() → void
     return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -217,13 +217,13 @@
   synthetic constructor •() → self::MyMock2
     : super self::MyMock1::•()
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
 }
 class MyMock3 extends self::B {
   synthetic constructor •() → self::MyMock3
     : super self::B::•()
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
   no-such-method-forwarder get interfaceMethod1() → dynamic
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
   no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
index 5a3c3d0..0322fcb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
@@ -194,7 +194,7 @@
   synthetic constructor •() → self::MyMock1
     : super self::B::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return null;
   no-such-method-forwarder method interfaceMethod2() → void
     return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -217,13 +217,13 @@
   synthetic constructor •() → self::MyMock2
     : super self::MyMock1::•()
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
 }
 class MyMock3 extends self::B {
   synthetic constructor •() → self::MyMock3
     : super self::B::•()
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
   no-such-method-forwarder get interfaceMethod1() → dynamic
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
   no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_members.dart.outline.expect b/pkg/front_end/testcases/abstract_members.dart.outline.expect
index ad1e730..c54c9fb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.outline.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.outline.expect
@@ -197,7 +197,7 @@
 class MyMock1 extends self::B {
   synthetic constructor •() → self::MyMock1
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     ;
   no-such-method-forwarder method interfaceMethod2() → void
     return this.{self::MyMock1::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod2, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
@@ -219,12 +219,12 @@
 class MyMock2 extends self::MyMock1 {
   synthetic constructor •() → self::MyMock2
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
 }
 class MyMock3 extends self::B {
   synthetic constructor •() → self::MyMock3
     ;
-  abstract method noSuchMethod(dynamic _) → dynamic;
+  abstract method noSuchMethod(core::Invocation _) → dynamic;
   no-such-method-forwarder get interfaceMethod1() → dynamic
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod1, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
   no-such-method-forwarder set property3(dynamic _) → void
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart
new file mode 100644
index 0000000..7bba23c
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+abstract class A {
+  A foo() => null;
+}
+
+abstract class B extends A {
+  B foo();
+}
+
+class C {
+  noSuchMethod(_) => null;
+}
+
+class D extends C implements B {}
+
+main() {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect
new file mode 100644
index 0000000..344af9a
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.hierarchy.expect
@@ -0,0 +1,105 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.A.foo%B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> C
+  interfaces: B, A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.A.foo%B.foo
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → self::A
+    return null;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  abstract method foo() → self::B;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method noSuchMethod(core::Invocation _) → dynamic
+    return null;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  no-such-method-forwarder method foo() → self::B
+    return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → self::A
+    return null;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  abstract method foo() → self::B;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method noSuchMethod(core::Invocation _) → dynamic
+    return null;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  no-such-method-forwarder method foo() → self::B
+    return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect
new file mode 100644
index 0000000..5430c79
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method foo() → self::A
+    ;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  abstract method foo() → self::B;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method noSuchMethod(core::Invocation _) → dynamic
+    ;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → self::D
+    ;
+  no-such-method-forwarder method foo() → self::B
+    return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → self::A
+    return null;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  abstract method foo() → self::B;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method noSuchMethod(core::Invocation _) → dynamic
+    return null;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  no-such-method-forwarder method foo() → self::B
+    return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..f45f7c3
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_overrides_concrete_with_no_such_method.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo() → self::A
+    return null;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  abstract method foo() → self::B;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method noSuchMethod(core::Invocation _) → dynamic
+    return null;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+  no-such-method-forwarder method foo() → self::B
+    return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} self::B;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart b/pkg/front_end/testcases/await_in_non_async.dart
new file mode 100644
index 0000000..7cbf642
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, 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.
+
+main() {
+  foo();
+}
+
+foo() {
+  // ignore: await_in_wrong_context
+  await foo();
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect b/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.legacy.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await foo();
+//   ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+  self::foo();
+}
+static method foo() → dynamic {
+  invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await foo();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect b/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.legacy.transformed.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await foo();
+//   ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+  self::foo();
+}
+static method foo() → dynamic {
+  invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await foo();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.outline.expect b/pkg/front_end/testcases/await_in_non_async.dart.outline.expect
new file mode 100644
index 0000000..4c2eb20
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.strong.expect b/pkg/front_end/testcases/await_in_non_async.dart.strong.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.strong.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await foo();
+//   ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+  self::foo();
+}
+static method foo() → dynamic {
+  invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await foo();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect b/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..c3d233b
--- /dev/null
+++ b/pkg/front_end/testcases/await_in_non_async.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+//   await foo();
+//   ^^^^^
+//
+import self as self;
+
+static method main() → dynamic {
+  self::foo();
+}
+static method foo() → dynamic {
+  invalid-expression "pkg/front_end/testcases/await_in_non_async.dart:11:3: Error: 'await' can only be used in 'async' or 'async*' methods.
+  await foo();
+  ^^^^^";
+}
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
index e84ce6f..f93d1cb 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
@@ -47,13 +47,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set a(dynamic #synthetic) → dynamic {
+  set a(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
   set a();
        ^";
     ;
   }
-  set d(dynamic #synthetic) → dynamic {
+  set d(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
   set d(x, y);
        ^";
@@ -68,13 +68,13 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  set a(dynamic #synthetic) → dynamic {
+  set a(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
   set a();
        ^";
     ;
   }
-  set d(dynamic #synthetic) → dynamic {
+  set d(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
   set d(x, y);
        ^";
@@ -85,13 +85,13 @@
     }
   }
 }
-static set b(dynamic #synthetic) → dynamic {
+static set b(dynamic #synthetic) → void {
   invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
 set b();
      ^";
   ;
 }
-static set c(dynamic #synthetic) → dynamic {
+static set c(dynamic #synthetic) → void {
   invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
 set c(x, y);
      ^";
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
index e84ce6f..f93d1cb 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
@@ -47,13 +47,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set a(dynamic #synthetic) → dynamic {
+  set a(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
   set a();
        ^";
     ;
   }
-  set d(dynamic #synthetic) → dynamic {
+  set d(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
   set d(x, y);
        ^";
@@ -68,13 +68,13 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  set a(dynamic #synthetic) → dynamic {
+  set a(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
   set a();
        ^";
     ;
   }
-  set d(dynamic #synthetic) → dynamic {
+  set d(dynamic #synthetic) → void {
     invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
   set d(x, y);
        ^";
@@ -85,13 +85,13 @@
     }
   }
 }
-static set b(dynamic #synthetic) → dynamic {
+static set b(dynamic #synthetic) → void {
   invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
 set b();
      ^";
   ;
 }
-static set c(dynamic #synthetic) → dynamic {
+static set c(dynamic #synthetic) → void {
   invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
 set c(x, y);
      ^";
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
index 68dcc4d..65b27e3 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
@@ -18,22 +18,22 @@
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
-  set a(dynamic #synthetic) → dynamic
+  set a(dynamic #synthetic) → void
     ;
-  set d(dynamic #synthetic) → dynamic
+  set d(dynamic #synthetic) → void
     ;
 }
 abstract class B extends core::Object {
   synthetic constructor •() → self::B
     ;
-  set a(dynamic #synthetic) → dynamic
+  set a(dynamic #synthetic) → void
     ;
-  set d(dynamic #synthetic) → dynamic
+  set d(dynamic #synthetic) → void
     ;
 }
-static set b(dynamic #synthetic) → dynamic
+static set b(dynamic #synthetic) → void
   ;
-static set c(dynamic #synthetic) → dynamic
+static set c(dynamic #synthetic) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/bug32866.dart.legacy.expect b/pkg/front_end/testcases/bug32866.dart.legacy.expect
index f62f9f6..5cf6726 100644
--- a/pkg/front_end/testcases/bug32866.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug32866.dart.legacy.expect
@@ -9,7 +9,7 @@
   abstract get f() → core::String;
 }
 class A extends core::Object implements self::B {
-  final field dynamic f;
+  final field core::String f;
   constructor •(dynamic f) → self::A
     : self::A::f = f, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
index f62f9f6..5cf6726 100644
--- a/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug32866.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
   abstract get f() → core::String;
 }
 class A extends core::Object implements self::B {
-  final field dynamic f;
+  final field core::String f;
   constructor •(dynamic f) → self::A
     : self::A::f = f, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/bug32866.dart.outline.expect b/pkg/front_end/testcases/bug32866.dart.outline.expect
index 0b51724..c902755 100644
--- a/pkg/front_end/testcases/bug32866.dart.outline.expect
+++ b/pkg/front_end/testcases/bug32866.dart.outline.expect
@@ -8,7 +8,7 @@
   abstract get f() → core::String;
 }
 class A extends core::Object implements self::B {
-  final field dynamic f;
+  final field core::String f;
   constructor •(dynamic f) → self::A
     ;
 }
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.expect b/pkg/front_end/testcases/bug33206.dart.legacy.expect
index b0dba95..1d53254 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.expect
@@ -11,7 +11,7 @@
   constructor •(dynamic x, dynamic y) → self::X
     : self::X::x = x, self::X::y = y, super core::Object::•()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
 }
 class Y extends core::Object {
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
index 2a26c19..f484e4b 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
@@ -11,7 +11,7 @@
   constructor •(dynamic x, dynamic y) → self::X
     : self::X::x = x, self::X::y = y, super core::Object::•()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
 }
 class Y extends core::Object {
diff --git a/pkg/front_end/testcases/bug33206.dart.outline.expect b/pkg/front_end/testcases/bug33206.dart.outline.expect
index 95d83e8..3dd6634 100644
--- a/pkg/front_end/testcases/bug33206.dart.outline.expect
+++ b/pkg/front_end/testcases/bug33206.dart.outline.expect
@@ -10,7 +10,7 @@
   final field dynamic y;
   constructor •(dynamic x, dynamic y) → self::X
     ;
-  method toString() → dynamic
+  method toString() → core::String
     ;
 }
 class Y extends core::Object {
diff --git a/pkg/front_end/testcases/covariant_generic.dart.outline.expect b/pkg/front_end/testcases/covariant_generic.dart.outline.expect
index 4b44219..da79e5c 100644
--- a/pkg/front_end/testcases/covariant_generic.dart.outline.expect
+++ b/pkg/front_end/testcases/covariant_generic.dart.outline.expect
@@ -12,7 +12,7 @@
     ;
   method method(generic-covariant-impl self::Foo::T x) → void
     ;
-  set setter(generic-covariant-impl self::Foo::T x) → dynamic
+  set setter(generic-covariant-impl self::Foo::T x) → void
     ;
   method withCallback((self::Foo::T) → void callback) → void
     ;
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart
new file mode 100644
index 0000000..d9a1e90
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2019, 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.
+
+// The test checks that 'covariant' bit is propagated from the superclass of the
+// mixin application to the mixin application and its subclasses.
+
+class A {
+  void foo(covariant num x) {}
+}
+
+class B {
+  void foo(num x) {}
+}
+
+class C {
+  void foo(num x) {}
+}
+
+class D extends A with B implements C {
+  // This member declaration shouldn't result in a compile-time error.
+  void foo(int x) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect
new file mode 100644
index 0000000..d9115a1
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.hierarchy.expect
@@ -0,0 +1,138 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A with B:
+  superclasses:
+    Object
+      -> A
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A with B.B.foo%A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A with B.B.foo%A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+      -> A
+        -> _D&A&B
+  interfaces: B, C
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect
new file mode 100644
index 0000000..17ddb30
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+abstract class _D&A&B = self::A with self::B {
+  synthetic constructor •() → self::_D&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub method foo(covariant core::num x) → void
+    return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+  synthetic constructor •() → self::D
+    : super self::_D&A&B::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect
new file mode 100644
index 0000000..cec0223
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.legacy.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+abstract class _D&A&B extends self::A implements self::B {
+  synthetic constructor •() → self::_D&A&B
+    : super self::A::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class D extends self::_D&A&B implements self::C {
+  synthetic constructor •() → self::D
+    : super self::_D&A&B::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect
new file mode 100644
index 0000000..241bbe0
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.outline.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method foo(covariant core::num x) → void
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  method foo(core::num x) → void
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method foo(core::num x) → void
+    ;
+}
+abstract class _D&A&B = self::A with self::B {
+  synthetic constructor •() → self::_D&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub method foo(covariant core::num x) → void
+    return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+  synthetic constructor •() → self::D
+    ;
+  method foo(covariant core::int x) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect
new file mode 100644
index 0000000..17ddb30
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+abstract class _D&A&B = self::A with self::B {
+  synthetic constructor •() → self::_D&A&B
+    : super self::A::•()
+    ;
+  forwarding-stub method foo(covariant core::num x) → void
+    return super.{self::A::foo}(x);
+}
+class D extends self::_D&A&B implements self::C {
+  synthetic constructor •() → self::D
+    : super self::_D&A&B::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect
new file mode 100644
index 0000000..cec0223
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_parameter_in_superclass_of_mixin_application.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method foo(core::num x) → void {}
+}
+abstract class _D&A&B extends self::A implements self::B {
+  synthetic constructor •() → self::_D&A&B
+    : super self::A::•()
+    ;
+  method foo(covariant core::num x) → void {}
+}
+class D extends self::_D&A&B implements self::C {
+  synthetic constructor •() → self::D
+    : super self::_D&A&B::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/escape.dart.legacy.expect b/pkg/front_end/testcases/escape.dart.legacy.expect
index 389e93a..ec93320 100644
--- a/pkg/front_end/testcases/escape.dart.legacy.expect
+++ b/pkg/front_end/testcases/escape.dart.legacy.expect
@@ -18,7 +18,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  operator ==(dynamic x) → dynamic
+  operator ==(dynamic x) → core::bool
     return false;
 }
 class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/escape.dart.legacy.transformed.expect b/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
index 389e93a..ec93320 100644
--- a/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/escape.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  operator ==(dynamic x) → dynamic
+  operator ==(dynamic x) → core::bool
     return false;
 }
 class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/escape.dart.outline.expect b/pkg/front_end/testcases/escape.dart.outline.expect
index e98ed5f..1bccd65 100644
--- a/pkg/front_end/testcases/escape.dart.outline.expect
+++ b/pkg/front_end/testcases/escape.dart.outline.expect
@@ -15,7 +15,7 @@
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
-  operator ==(dynamic x) → dynamic
+  operator ==(dynamic x) → core::bool
     ;
 }
 class X extends core::Object implements self::A, self::B {
diff --git a/pkg/front_end/testcases/extension_methods.dart b/pkg/front_end/testcases/extension_methods.dart
new file mode 100644
index 0000000..51013db
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=extension-methods
+
+import 'package:expect/expect.dart';
+
+class C {
+  int get one => 1;
+}
+
+extension E on C {
+  int get two => 2;
+}
+
+main() {
+  C c = C();
+  var result = c.one + c.two;
+  Expect.equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect b/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..af7781c
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.hierarchy.expect
@@ -0,0 +1,418 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.one
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/extension_methods.dart.legacy.expect b/pkg/front_end/testcases/extension_methods.dart.legacy.expect
new file mode 100644
index 0000000..7fd1230
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.legacy.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+//                ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+//                ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+//             ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+//   int get two => 2;
+//       ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   int get two => 2;
+//               ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//   ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get one() → core::int
+    return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+  invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+  C c = C();
+        ^".call();
+  dynamic result = c.one.+(c.two);
+  exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect b/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect
new file mode 100644
index 0000000..7fd1230
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.legacy.transformed.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+//                ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+//                ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+//             ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+//   int get two => 2;
+//       ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   int get two => 2;
+//               ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//   ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get one() → core::int
+    return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+  invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+  C c = C();
+        ^".call();
+  dynamic result = c.one.+(c.two);
+  exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/extension_methods.dart.outline.expect b/pkg/front_end/testcases/extension_methods.dart.outline.expect
new file mode 100644
index 0000000..ccb8e3f
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.outline.expect
@@ -0,0 +1,43 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+//                ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+//                ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Warning: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Warning: Type 'on' not found.
+// extension E on C {
+//             ^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  get one() → core::int
+    ;
+}
+static field invalid-type E;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/extension_methods.dart.strong.expect b/pkg/front_end/testcases/extension_methods.dart.strong.expect
new file mode 100644
index 0000000..b3845b4
--- /dev/null
+++ b/pkg/front_end/testcases/extension_methods.dart.strong.expect
@@ -0,0 +1,71 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: This requires the 'extension-methods' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// extension E on C {
+//                ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:16: Error: 'C' is already declared in this scope.
+// extension E on C {
+//                ^
+// pkg/front_end/testcases/extension_methods.dart:9:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: Type 'extension' not found.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:13: Error: Type 'on' not found.
+// extension E on C {
+//             ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:13:1: Error: 'extension' isn't a type.
+// extension E on C {
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:7: Error: Expected ';' after this.
+//   int get two => 2;
+//       ^^^
+//
+// pkg/front_end/testcases/extension_methods.dart:14:15: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+//   int get two => 2;
+//               ^^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:3: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//   ^
+//
+// pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+//   C c = C();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+import "package:expect/expect.dart";
+
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  get one() → core::int
+    return 1;
+}
+static field invalid-type E;
+static method main() → dynamic {
+  invalid-type c = invalid-expression "pkg/front_end/testcases/extension_methods.dart:18:9: Error: Can't use 'C' because it is declared more than once.
+  C c = C();
+        ^".call() as{TypeError} invalid-type;
+  dynamic result = c.one.+(c.two);
+  exp::Expect::equals(result, 3);
+}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart b/pkg/front_end/testcases/forwarding_stub_for_operator.dart
new file mode 100644
index 0000000..e604fe0
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, 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.
+
+//------------------------------------------------------------------------------
+
+class A {
+  dynamic operator+(covariant int a) => null;
+}
+
+class B {
+  dynamic operator+(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+//------------------------------------------------------------------------------
+
+class D {
+  dynamic operator+(dynamic d) => null;
+}
+
+class E extends D {
+  dynamic operator+(covariant int e);
+}
+
+//------------------------------------------------------------------------------
+
+main() {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
new file mode 100644
index 0000000..d5d1da9
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    C.A.+%B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    D.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    E.D.+%E.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator +(covariant core::int a) → dynamic
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator +(dynamic b) → dynamic
+    return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  operator +(dynamic d) → dynamic
+    return null;
+}
+class E extends self::D {
+  synthetic constructor •() → self::E
+    : super self::D::•()
+    ;
+  forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+    return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator +(covariant core::int a) → dynamic
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator +(dynamic b) → dynamic
+    return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  operator +(dynamic d) → dynamic
+    return null;
+}
+class E extends self::D {
+  synthetic constructor •() → self::E
+    : super self::D::•()
+    ;
+  forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+    return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
new file mode 100644
index 0000000..14a8eef
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  operator +(covariant core::int a) → dynamic
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  operator +(dynamic b) → dynamic
+    ;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::C
+    ;
+  abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+  synthetic constructor •() → self::D
+    ;
+  operator +(dynamic d) → dynamic
+    ;
+}
+class E extends self::D {
+  synthetic constructor •() → self::E
+    ;
+  forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+    return super.{self::D::+}(e);
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator +(covariant core::int a) → dynamic
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator +(dynamic b) → dynamic
+    return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  operator +(dynamic d) → dynamic
+    return null;
+}
+class E extends self::D {
+  synthetic constructor •() → self::E
+    : super self::D::•()
+    ;
+  forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+    return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator +(covariant core::int a) → dynamic
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator +(dynamic b) → dynamic
+    return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+  operator +(dynamic d) → dynamic
+    return null;
+}
+class E extends self::D {
+  synthetic constructor •() → self::E
+    : super self::D::•()
+    ;
+  forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+    return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart b/pkg/front_end/testcases/ignore_function.dart
new file mode 100644
index 0000000..83c33eb
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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 "dart:core" as core;
+
+class A implements core.Function {
+  // No error here: core.Function is ignored.
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  // Error here Object.== and Function.== disagree on the type of other.
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect b/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect
new file mode 100644
index 0000000..329fb74
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+  classSetters:
+
+Function:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Function.==
+  classSetters:
+
+B:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Function
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    B.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    B.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/ignore_function.dart.legacy.expect b/pkg/front_end/testcases/ignore_function.dart.legacy.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.legacy.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   operator ==(other) => false;
+//               ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(dynamic other) → core::bool
+    return false;
+}
+class B extends core::Object implements self::Function {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator ==(invalid-type other) → core::bool
+    return false;
+}
+class Function extends core::Object {
+  synthetic constructor •() → self::Function
+    : super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect b/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.legacy.transformed.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   operator ==(other) => false;
+//               ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(dynamic other) → core::bool
+    return false;
+}
+class B extends core::Object implements self::Function {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator ==(invalid-type other) → core::bool
+    return false;
+}
+class Function extends core::Object {
+  synthetic constructor •() → self::Function
+    : super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ignore_function.dart.outline.expect b/pkg/front_end/testcases/ignore_function.dart.outline.expect
new file mode 100644
index 0000000..a1585c3
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.outline.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   operator ==(other) => false;
+//               ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+  synthetic constructor •() → self::A
+    ;
+  operator ==(dynamic other) → core::bool
+    ;
+}
+class B extends core::Object implements self::Function {
+  synthetic constructor •() → self::B
+    ;
+  operator ==(invalid-type other) → core::bool
+    ;
+}
+class Function extends core::Object {
+  synthetic constructor •() → self::Function
+    ;
+  operator ==(core::Object other) → core::bool
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/ignore_function.dart.strong.expect b/pkg/front_end/testcases/ignore_function.dart.strong.expect
new file mode 100644
index 0000000..5b8a8d2
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ignore_function.dart:14:15: Error: Can't infer a type for 'other' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   operator ==(other) => false;
+//               ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "dart:core" as core;
+
+class A extends core::Object implements core::Function {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  operator ==(dynamic other) → core::bool
+    return false;
+}
+class B extends core::Object implements self::Function {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  operator ==(invalid-type other) → core::bool
+    return false;
+}
+class Function extends core::Object {
+  synthetic constructor •() → self::Function
+    : super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return false;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml
new file mode 100644
index 0000000..6e1730d
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/await_in_non_async.yaml
@@ -0,0 +1,33 @@
+# Copyright (c) 2019, 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.md file.
+
+type: newworld
+omitPlatform: false
+worlds:
+  - entry: main.dart
+    errors: false
+    warnings: false
+    sources:
+      main.dart: |
+        main() {
+          foo();
+        }
+        foo() {}
+    expectedLibraryCount: 1
+    expectsPlatform: true
+  - entry: main.dart
+    errors: true
+    warnings: false
+    expectInitializeFromDill: false
+    fromComponent: true
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        main() {
+          await foo();
+        }
+        foo() {}
+    expectedLibraryCount: 1
+    expectsPlatform: true
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
index 9b471de..f884677 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/calculated_bounds_no_strongmode.yaml
@@ -2,12 +2,11 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE.md file.
 
-# Test compiling in non-strong-mode from source and initializing from dill.
+# Test compiling from source and initializing from dill.
 # Make sure that any inference if done in the same way.
 
 type: basic
 entry: a.dart
-strong: false
 invalidate:
   - a.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
index ba6a85f..74d1d07 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules.yaml
@@ -6,7 +6,6 @@
 # Compile again with changing modules.
 
 type: newworld
-strong: true
 modules:
   example_0.1.0:
     example_0.1.0/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
index 4d0a193..f2a10a8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_2.yaml
@@ -6,7 +6,6 @@
 # Compile again with changing modules.
 
 type: newworld
-strong: true
 modules:
   example_1:
     example_1/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
index 7e64c8c..c009ea1 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_3.yaml
@@ -6,7 +6,6 @@
 # Compile again with changing modules.
 
 type: newworld
-strong: true
 modules:
   foo:
     foo/foo.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
index 08f0a4c..8c256a6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_non_package_unreferenced_libraries.yaml
@@ -7,7 +7,6 @@
 # also have been removed from the uri to sources.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
index ef7857f..adee8ad 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/cleans_up_uritosource_unreferenced_package_library.yaml
@@ -8,7 +8,6 @@
 # removed from the uri to sources.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
index 4b1c653..d8ddd8d 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/constant_set_literal.yaml
@@ -5,7 +5,6 @@
 # Test that constant set literals works as expected.
 
 type: newworld
-strong: true
 worlds:
   - entry: "main.dart"
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
index 7ea4cc0..a1d9f4b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/deferred_library.yaml
@@ -7,7 +7,6 @@
 
 type: basic
 entry: a.dart
-strong: false
 invalidate:
 sources:
   a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
index 2933c37..dea1937 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/deleting_file.yaml
@@ -7,7 +7,6 @@
 # we should keep getting an error.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
@@ -24,7 +23,6 @@
     expectedLibraryCount: 2
   - entry: main.dart
     errors: true
-    warnings: true
     invalidate:
       - b.dart
     sources:
@@ -37,7 +35,6 @@
     expectedLibraryCount: 1
   - entry: main.dart
     errors: true
-    warnings: true
     checkInvalidatedFiles: false
     worldType: updated
     invalidate:
@@ -52,7 +49,6 @@
     expectedLibraryCount: 1
   - entry: main.dart
     errors: true
-    warnings: true
     checkInvalidatedFiles: false
     worldType: updated
     invalidate:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
index a00341b..75a951b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_library.yaml
@@ -8,7 +8,6 @@
 # of the library list --- initializing from the dill with n libraries.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
index 9e236c1..4790a02 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/disappearing_package.yaml
@@ -8,7 +8,6 @@
 # but shouldn't cause trouble, nor be included in the output.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
index 5bd270e..f5ac43a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
@@ -7,7 +7,6 @@
 # should still be included in the output.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
index 2360641..828f103 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
@@ -7,7 +7,6 @@
 # should still be included in the output - even if there's errors in main.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
index 02a57de..fd5d0d5 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
@@ -7,7 +7,6 @@
 # should still be included in the output - even if there's no main.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
index b426a33..9baf55e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/expression_calculation_with_error.yaml
@@ -9,7 +9,6 @@
 # error.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
index 1a79746..1e22f39 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_mixin_failure_1.yaml
@@ -5,7 +5,6 @@
 # Regression test from flutter.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
index e45af03..2efee99 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_file_then_use_type.yaml
@@ -9,7 +9,6 @@
 # by the class hierarchy.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
index 85937b6..e34eff2 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/initialize_with_unused_package_then_use_type.yaml
@@ -10,7 +10,6 @@
 # hierarchy.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
index 07e5102..768fd3c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_export_of_main.yaml
@@ -6,7 +6,6 @@
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
   - a.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
index 1d8be7f..da20971 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part.yaml
@@ -6,7 +6,6 @@
 # URI.
 
 type: newworld
-strong: false
 worlds:
   - entry: "package:example/main.dart"
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
index eae0ae4..60327f4 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_file.yaml
@@ -6,7 +6,6 @@
 
 type: basic
 entry: "package:example/main.dart"
-strong: false
 invalidate:
   - pkg/example/b.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
index 19816ca..ccbe383 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_as_package.yaml
@@ -6,7 +6,6 @@
 
 type: basic
 entry: "package:example/main.dart"
-strong: false
 invalidate:
   - "package:example/b.dart"
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
index d5a757b..15d82ee 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_file.yaml
@@ -7,7 +7,6 @@
 
 type: basic
 entry: "package:example/main.dart"
-strong: false
 invalidate:
   - pkg/example/b.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
index 149b1ae..2bb9c88 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_package_part_from_package_url_as_package.yaml
@@ -7,7 +7,6 @@
 
 type: basic
 entry: "package:example/main.dart"
-strong: false
 invalidate:
   - "package:example/b.dart"
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
index 8ff940e..4b88157 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidate_part.yaml
@@ -6,7 +6,6 @@
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
   - b.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
index c627364..2313785 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/invalidation_across_compile_time_error.yaml
@@ -11,7 +11,6 @@
 # that it pulled in should be included.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
index 649545e..6b88d9a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
@@ -10,7 +10,6 @@
 # the parameter type 'dart.core::String'".
 
 type: newworld
-strong: true
 omitPlatform: false
 worlds:
   - entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
index 30d267a..51be325 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_from_sdk.yaml
@@ -8,7 +8,6 @@
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
   - a.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
index e571850..e760b10 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
@@ -6,7 +6,6 @@
 # and now swallowed somewhere when done in the incremental compiler.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
index 83c53a0..0577118 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/multiple_entriepoints.yaml
@@ -6,7 +6,6 @@
 # results in getting both libraries (aka that multiple entry points work).
 
 type: newworld
-strong: true
 worlds:
   - entry:
       - a.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
index d336e98..5f3ac3c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
@@ -7,7 +7,6 @@
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
 sources:
   a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
index e306e5a..8d884a3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_1.yaml
@@ -5,7 +5,6 @@
 # Compile a hello world program, check that omit platform works as expected.
 
 type: newworld
-strong: true
 omitPlatform: true
 worlds:
   - entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
index e1a42a8a..071eacd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_2.yaml
@@ -6,7 +6,6 @@
 # Omit platform is true by default in tests.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
index b649bbd..450377b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/omit_platform_works_3.yaml
@@ -7,7 +7,6 @@
 # component again etc.
 
 type: newworld
-strong: true
 omitPlatform: false
 worlds:
   - entry: main.dart
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
index 5bfb458..59a9e45 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only.yaml
@@ -5,7 +5,6 @@
 # Compile an application with the option of only getting an outline.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
index 0105f44..94b1a83 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/outline_only_2.yaml
@@ -6,7 +6,6 @@
 # This is a reproduction of http://dartbug.com/36498.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
index 5fd397a..b906cba 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/regress_35215.yaml
@@ -7,7 +7,6 @@
 # exist in the old library.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
index 0be7810..fb57969 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
@@ -7,7 +7,6 @@
 # we keep getting errors. Once we fix it, we no longer get errors.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
index 468566d..91ce7a3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
@@ -7,7 +7,6 @@
 # we keep getting errors. Once we fix it, we no longer get errors.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
index 5375fd6..1c74c07 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
@@ -7,7 +7,6 @@
 # we keep getting errors. Once we fix it, we no longer get errors.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
index 994f2c6..8342cbd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
@@ -7,7 +7,6 @@
 # we keep getting errors. Once we fix it, we no longer get errors.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
index c5164e2..65f2282 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_5.yaml
@@ -7,7 +7,6 @@
 # we keep getting errors. Once we fix it, we no longer get errors.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
index fb8b511..5965f18 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/remove_import_with_error.yaml
@@ -7,7 +7,6 @@
 # invalidating a. Compiling this should not result in any errors.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
index 1981950..f644133 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins.yaml
@@ -2,13 +2,12 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE.md file.
 
-# Compile in strong mode. Invalidate a file so type inferrer starts
+# Compile. Invalidate a file so type inferrer starts
 # on something compiled from source and (potentially) goes into
 # something loaded from dill.
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
   - a.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
index 61d783f..9238c66 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/strongmode_mixins_2.yaml
@@ -2,11 +2,10 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE.md file.
 
-# Compile in strong mode. Use mixins.
+# Compile. Use mixins.
 
 type: basic
 entry: a.dart
-strong: true
 invalidate:
   - a.dart
 sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
index a2c5739..e7182de 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/unused_file.yaml
@@ -8,7 +8,6 @@
 # but shouldn't cause trouble, nor be included in the output.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
index 7bb3ab1..0a24fa7 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_1.yaml
@@ -8,7 +8,6 @@
 # but shouldn't cause trouble, nor be included in the output.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
index 00cd03f..ad7756f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_2.yaml
@@ -8,7 +8,6 @@
 # but shouldn't cause trouble, nor be included in the output.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
index 1c79496..ed1f6ab 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_3.yaml
@@ -8,7 +8,6 @@
 # The output should not include the old package.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
index c7a7491..5cb7d9c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_4.yaml
@@ -7,7 +7,6 @@
 # This should be an error.
 
 type: newworld
-strong: false
 worlds:
   - entry: main.dart
     sources:
@@ -32,5 +31,4 @@
     sources:
       .packages:
     errors: true
-    warnings: true
     expectedLibraryCount: 1
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
index cf01000..f716e96 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/updated_package_uri.yaml
@@ -7,7 +7,6 @@
 # should now be relative to the new .packages file.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
index 14b0a58..9f3b66a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
@@ -7,7 +7,6 @@
 # Loading from such a dill is ok too.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
index bbcc110..50f16a6 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
@@ -7,7 +7,6 @@
 # Loading from such a dill is ok too.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
index 0402343..6d8eb3f 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
@@ -7,7 +7,6 @@
 # Loading from such a dill is ok too.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
index df8a598..1af29a8 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
@@ -8,7 +8,6 @@
 # Loading from such a dill is ok too.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
index bd55d81..9aa7ede 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
@@ -7,7 +7,6 @@
 # Loading from such a dill is ok too.
 
 type: newworld
-strong: true
 worlds:
   - entry: main.dart
     sources:
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
@@ -5,7 +5,7 @@
 /*@testedFeatures=inference*/
 library test;
 
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
 var y = /*@returnType=invalid-type*/ () => x;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
index 73adfd1..bd67e53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.expect
@@ -2,18 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-//     ^
-//
 // pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
 //     ^
 //
 import self as self;
 
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
index 73adfd1..bd67e53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
@@ -2,18 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-//     ^
-//
 // pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
 //     ^
 //
 import self as self;
 
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
@@ -5,7 +5,7 @@
 /*@testedFeatures=inference*/
 library test;
 
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
 var y = /*@returnType=invalid-type*/ () => x;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
index 4f81f83..88a970d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.expect
@@ -2,18 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-//     ^
-//
 // pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
 //     ^
 //
 import self as self;
 
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
index 4f81f83..88a970d 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
@@ -2,18 +2,13 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:9:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-//     ^
-//
 // pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => y;
+// var x = /*@returnType=() -> invalid-type*/ () => y;
 //     ^
 //
 import self as self;
 
-static field invalid-type x = (() → invalid-type => self::y) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
+static field invalid-type x = (() → () → invalid-type => self::y) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart b/pkg/front_end/testcases/inference/conflicting_fields.dart
index 72edc67..8dacd55 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart
@@ -17,6 +17,8 @@
 class B extends A implements I {
   get field1 => null;
   get field2 => null;
+  set field1(value) {}
+  set field2(value) {}
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
index 058c190..b2b061e 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.hierarchy.expect
@@ -79,8 +79,8 @@
     Object._simpleInstanceOfTrue
     Object.==
   classSetters:
-    A.field1
-    A.field2
+    B.field1
+    B.field2
   interfaceMembers:
     B.field1
     Object.toString
@@ -95,5 +95,5 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    A.field1
-    A.field2
+    B.field1
+    B.field2
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
index 67e1ae7..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.expect
@@ -1,4 +1,17 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field1(value) {}
+//              ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field2(value) {}
+//              ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -20,9 +33,11 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  get field1() → dynamic
+  get field1() → core::int
     return null;
-  get field2() → dynamic
+  get field2() → core::int
     return null;
+  set field1(invalid-type value) → void {}
+  set field2(invalid-type value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
index 67e1ae7..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.legacy.transformed.expect
@@ -1,4 +1,17 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field1(value) {}
+//              ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field2(value) {}
+//              ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -20,9 +33,11 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  get field1() → dynamic
+  get field1() → core::int
     return null;
-  get field2() → dynamic
+  get field2() → core::int
     return null;
+  set field1(invalid-type value) → void {}
+  set field2(invalid-type value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
index 6963ff2..57c1e7c 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.outline.expect
@@ -1,4 +1,17 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field1(value) {}
+//              ^^^^^
+//
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   set field2(value) {}
+//              ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -17,9 +30,13 @@
 class B extends self::A implements self::I {
   synthetic constructor •() → self::B
     ;
-  get field1() → dynamic
+  get field1() → core::int
     ;
-  get field2() → dynamic
+  get field2() → core::int
+    ;
+  set field1(invalid-type value) → void
+    ;
+  set field2(invalid-type value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect b/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
index 3f45ef6..0a84181 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart.strong.expect
@@ -2,42 +2,15 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/conflicting_fields.dart:18:7: Error: Can't infer a type for 'field1' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicting_fields.dart:20:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
 // Try adding an explicit type.
-//   get field1 => null;
-//       ^
+//   set field1(value) {}
+//              ^^^^^
 //
-// pkg/front_end/testcases/inference/conflicting_fields.dart:19:7: Error: Can't infer a type for 'field2' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicting_fields.dart:21:14: Error: Can't infer a type for 'value' as some of the inherited members have different types.
 // Try adding an explicit type.
-//   get field2 => null;
-//       ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:19:7: Error: The return type of the method 'B.field2' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.field2'.
-// Change to a subtype of 'int'.
-//   get field2 => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:9:7: Context: This is the overridden method ('field2').
-//   int field2;
-//       ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:18:7: Error: The return type of the method 'B.field1' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'I.field1'.
-// Change to a subtype of 'int'.
-//   get field1 => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:13:7: Context: This is the overridden method ('field1').
-//   int field1;
-//       ^
-//
-// pkg/front_end/testcases/inference/conflicting_fields.dart:8:11: Error: The return type of the method 'A.field1' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'I.field1'.
-// Change to a subtype of 'int'.
-//   dynamic field1;
-//           ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:13:7: Context: This is the overridden method ('field1').
-//   int field1;
-//       ^
-// pkg/front_end/testcases/inference/conflicting_fields.dart:17:7: Context: Both members are inherited by the non-abstract class 'B'.
-// class B extends A implements I {
-//       ^
+//   set field2(value) {}
+//              ^^^^^
 //
 import self as self;
 import "dart:core" as core;
@@ -60,10 +33,11 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  get field1() → dynamic
+  get field1() → core::int
     return null;
-  get field2() → dynamic
+  get field2() → core::int
     return null;
-  abstract forwarding-stub set field2(dynamic _) → void;
+  set field1(invalid-type value) → void {}
+  set field2(invalid-type value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
index ae8c8ce..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.expect
@@ -1,4 +1,17 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -30,14 +43,14 @@
   synthetic constructor •() → self::C1
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 class C2 extends core::Object implements self::B, self::A {
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
index ae8c8ce..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.legacy.transformed.expect
@@ -1,4 +1,17 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -30,14 +43,14 @@
   synthetic constructor •() → self::C1
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 class C2 extends core::Object implements self::B, self::A {
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
index 6e8c47d..3e2c41e 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
@@ -2,52 +2,16 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
 // Try adding an explicit type.
 //   get a => null;
 //       ^
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
 // Try adding an explicit type.
 //   get a => null;
 //       ^
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-//   final I1 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:7: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-//   final I2 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-//   final I2 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:30:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-//   final I1 a = null;
-//            ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -79,14 +43,14 @@
   synthetic constructor •() → self::C1
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 class C2 extends core::Object implements self::B, self::A {
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
index e3d2868..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -44,7 +52,7 @@
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
index e3d2868..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   get a => null;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -44,7 +52,7 @@
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
index 411506a..7883099 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
@@ -2,29 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a type for 'a' as some of the inherited members have different types.
+// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: Can't infer a return type for 'a' as some of the inherited members have different types.
 // Try adding an explicit type.
 //   get a => null;
 //       ^
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I1', of the overridden method, 'A.a'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I1'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:22:12: Context: This is the overridden method ('a').
-//   final I1 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:7: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type, 'I2', of the overridden method, 'B.a'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I2'.
-//   get a => null;
-//       ^
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:26:12: Context: This is the overridden method ('a').
-//   final I2 a = null;
-//            ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -70,7 +52,7 @@
   synthetic constructor •() → self::C2
     : super core::Object::•()
     ;
-  get a() → dynamic
+  get a() → invalid-type
     return null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
index 9a63601..ebc33e7 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.expect
@@ -9,7 +9,7 @@
   abstract get foo() → core::Iterable<core::String>;
 }
 class B extends core::Object implements self::A {
-  final field dynamic foo = const <dynamic>[];
+  final field core::Iterable<core::String> foo = const <dynamic>[];
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
index 9a63601..ebc33e7 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
   abstract get foo() → core::Iterable<core::String>;
 }
 class B extends core::Object implements self::A {
-  final field dynamic foo = const <dynamic>[];
+  final field core::Iterable<core::String> foo = const <dynamic>[];
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
index 65ee9d5..945a5e0 100644
--- a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.outline.expect
@@ -8,7 +8,7 @@
   abstract get foo() → core::Iterable<core::String>;
 }
 class B extends core::Object implements self::A {
-  final field dynamic foo;
+  final field core::Iterable<core::String> foo;
   synthetic constructor •() → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
index d1361ce..a97723a 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C extends core::Object implements self::B {
-  final field dynamic x;
+  final field core::int x;
   constructor •() → self::C
     : self::C::x = self::f<dynamic>(), super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
index d1361ce..a97723a 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C extends core::Object implements self::B {
-  final field dynamic x;
+  final field core::int x;
   constructor •() → self::C
     : self::C::x = self::f<dynamic>(), super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
index e84a002..eda87a3 100644
--- a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.outline.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C extends core::Object implements self::B {
-  final field dynamic x;
+  final field core::int x;
   constructor •() → self::C
     ;
 }
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
index 88b6639..7126780 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
index 4f440e2..0e46318 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
index a91d75e..c555879 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
index 6538f9e..63c4c5c 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
index 2a3484c..075602a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
index 346e77b8..895ce5a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
index c7d577e..8a393fd 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
index c90b143..98c8918 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
index 141e3e7..58d742b 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
index 33b2911..5d553da 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
index cc6a439..0cc6848 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
index 9ad93e8..6d284e6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
index 579d81d..d16fb57 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
index 1ae82f7..37a9eaf 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
index 3fbb4f7..b5e3e79 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
index 9b1db02..e3526c6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
index a38c5ae..dc6b8a1 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
index 364a78a..8031722 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
index 189b93e..ac112f8 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
index 4a5e294..0ebe142 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
index 8b21e2e..f359eff 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
index e5e7c73..d73e7d4 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
index d4392fe..6231476 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
index fecb72e..b10c087 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
index 985e5ba..211f9f3 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
index f3c12bb..a55a43b 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
index 18f6651..6c0b0d6 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
index c454264..c131aa9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
index c454264..c131aa9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
index e5a534c..68201b4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
index 4c532cc..b418fd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
index 4c532cc..b418fd7 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
index e5a534c..68201b4 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
index 86abe95..93fd95b 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
index 86abe95..93fd95b 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
index 9162c9b..a644d90 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(self::MyFuture::T x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
index aed7501..f9b1dde 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
index 7697712..24f847d 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
index e80eb43..3e05a12 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
index b3989b2..85cc477 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
index 8c463d9..7395c33 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
index e80eb43..3e05a12 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value(dynamic x) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
index c309ae6..3e9e23f 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
index 5fb66a8..86df2a1 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
index 263a94f..6fbd438 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
index a89b874..1f70652 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
index ec5724d..1afd6d8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
index 263a94f..6fbd438 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
index 9b07131..51e5fde 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
index a3884a8..ec3fde4 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
index da18d4d..2d1e70e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
index b27e6d9..ab6a0d3 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
index ca29563..7fc5179 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
     : super core::Object::•() {}
   constructor value([dynamic x = null]) → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     return null;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
     return null;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
index da18d4d..2d1e70e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
   constructor value([dynamic x]) → self::MyFuture<self::MyFuture::T>
     ;
-  method noSuchMethod(dynamic invocation) → dynamic
+  method noSuchMethod(core::Invocation invocation) → dynamic
     ;
   method then<S extends core::Object = dynamic>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
     ;
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
index 1f86d32..b9c4222 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+  method f<U extends core::Object = dynamic>(self::C::f::U x) → (self::C::f::U) → void {}
 }
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
index 1f86d32..b9c4222 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+  method f<U extends core::Object = dynamic>(self::C::f::U x) → (self::C::f::U) → void {}
 }
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
index 08648c6..c1d63d6 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic g) → dynamic
+  method f<U extends core::Object = dynamic>(() → core::List<self::C::f::U> g) → void
     return null;
 }
 abstract class D<T extends core::Object = dynamic> extends core::Object {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
index 08648c6..c1d63d6 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic g) → dynamic
+  method f<U extends core::Object = dynamic>(() → core::List<self::C::f::U> g) → void
     return null;
 }
 abstract class D<T extends core::Object = dynamic> extends core::Object {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
index 57033a4..c9c76f5 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+  method f<U extends core::Object = dynamic>(self::C::f::U x) → () → self::C::f::U {}
 }
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
index 57033a4..c9c76f5 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::C<self::C::T>
     : super self::D::•()
     ;
-  method f<U extends core::Object = dynamic>(dynamic x) → dynamic {}
+  method f<U extends core::Object = dynamic>(self::C::f::U x) → () → self::C::f::U {}
 }
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
index 29528fb..0500661 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method m<S extends core::Object = dynamic>(dynamic x) → dynamic
+  method m<S extends core::Object = dynamic>(self::D::m::S x) → self::D::m::S
     return x;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
index 29528fb..0500661 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method m<S extends core::Object = dynamic>(dynamic x) → dynamic
+  method m<S extends core::Object = dynamic>(self::D::m::S x) → self::D::m::S
     return x;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart b/pkg/front_end/testcases/inference/inconsistent_overrides.dart
new file mode 100644
index 0000000..9030aea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+library test;
+
+/*@testedFeatures=inference*/
+
+class A {
+  A f(A x, {A y}) {}
+  A g(A x, {A y}) {}
+  A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+  f(x, {y}) {}
+  g(x, {y}) {}
+  h(x, {y}) {}
+}
+
+class I {
+  I f(I x, {I y}) {}
+  A g(I x, {I y}) {}
+  A h(A x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect
new file mode 100644
index 0000000..ad5bb3a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.h
+    Object.hashCode
+    A.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    I.h
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces: I
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.h
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.h
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//   ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   h(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method f(self::A x, {self::A y = null}) → self::A {}
+  method g(self::A x, {self::A y = null}) → self::A {}
+  method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+  method g(invalid-type x, {invalid-type y = null}) → self::A {}
+  method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method f(self::I x, {self::I y = null}) → self::I {}
+  method g(self::I x, {self::I y = null}) → self::A {}
+  method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.legacy.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//   ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   h(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method f(self::A x, {self::A y = null}) → self::A {}
+  method g(self::A x, {self::A y = null}) → self::A {}
+  method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+  method g(invalid-type x, {invalid-type y = null}) → self::A {}
+  method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method f(self::I x, {self::I y = null}) → self::I {}
+  method g(self::I x, {self::I y = null}) → self::A {}
+  method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect
new file mode 100644
index 0000000..26eafa0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.outline.expect
@@ -0,0 +1,69 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//   ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   h(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method f(self::A x, {self::A y}) → self::A
+    ;
+  method g(self::A x, {self::A y}) → self::A
+    ;
+  method h(self::A x, {self::A y}) → self::A
+    ;
+}
+class B extends self::A implements self::I {
+  synthetic constructor •() → self::B
+    ;
+  method f(invalid-type x, {invalid-type y}) → invalid-type
+    ;
+  method g(invalid-type x, {invalid-type y}) → self::A
+    ;
+  method h(self::A x, {invalid-type y}) → self::A
+    ;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    ;
+  method f(self::I x, {self::I y}) → self::I
+    ;
+  method g(self::I x, {self::I y}) → self::A
+    ;
+  method h(self::A x, {self::I y}) → self::A
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect
new file mode 100644
index 0000000..d8b5742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart.strong.expect
@@ -0,0 +1,62 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:3: Error: Can't infer a return type for 'f' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//   ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:16:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   f(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:18:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   h(x, {y}) {}
+//         ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:5: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//     ^
+//
+// pkg/front_end/testcases/inference/inconsistent_overrides.dart:17:9: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   g(x, {y}) {}
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method f(self::A x, {self::A y = null}) → self::A {}
+  method g(self::A x, {self::A y = null}) → self::A {}
+  method h(self::A x, {self::A y = null}) → self::A {}
+}
+class B extends self::A implements self::I {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method f(invalid-type x, {invalid-type y = null}) → invalid-type {}
+  method g(invalid-type x, {invalid-type y = null}) → self::A {}
+  method h(self::A x, {invalid-type y = null}) → self::A {}
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method f(self::I x, {self::I y = null}) → self::I {}
+  method g(self::I x, {self::I y = null}) → self::A {}
+  method h(self::A x, {self::I y = null}) → self::A {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
index b9f3f55..ba7aef9 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  operator []=(dynamic index, dynamic value) → dynamic {}
+  operator []=(dynamic index, dynamic value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
index b9f3f55..ba7aef9 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  operator []=(dynamic index, dynamic value) → dynamic {}
+  operator []=(dynamic index, dynamic value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
index 431131a..ef008c4 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.outline.expect
@@ -17,7 +17,7 @@
 class D extends self::C implements self::I {
   synthetic constructor •() → self::D
     ;
-  operator []=(dynamic index, dynamic value) → dynamic
+  operator []=(dynamic index, dynamic value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
index 5ffc002..587faf3 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  operator []=(core::int index, dynamic value) → dynamic {}
+  operator []=(core::int index, dynamic value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
index 5ffc002..587faf3 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  operator []=(core::int index, dynamic value) → dynamic {}
+  operator []=(core::int index, dynamic value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
index e1dc0dc..68f38e5 100644
--- a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.outline.expect
@@ -17,7 +17,7 @@
 class D extends self::C implements self::I {
   synthetic constructor •() → self::D
     ;
-  operator []=(core::int index, dynamic value) → dynamic
+  operator []=(core::int index, dynamic value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
index 6657368..4b35f0e 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
index 6657368..4b35f0e 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
index 41317cd..b7b8fe3 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.outline.expect
@@ -3,14 +3,14 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::A
     ;
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
index 67fa407..94de153 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
index 67fa407..94de153 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.legacy.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
index 9de155a..25d6786 100644
--- a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.outline.expect
@@ -3,14 +3,14 @@
 import "dart:core" as core;
 
 class A extends core::Object implements self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::A
     ;
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
index 34995f9..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -27,25 +45,25 @@
   abstract get x() → core::double;
 }
 class E extends self::A implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super self::A::•()
     ;
 }
 class F extends self::A implements self::C {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::F
     : super self::A::•()
     ;
 }
 class G extends self::A implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::G
     : super self::A::•()
     ;
 }
 class H extends self::C implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::H
     : super self::C::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
index 34995f9..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.legacy.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -27,25 +45,25 @@
   abstract get x() → core::double;
 }
 class E extends self::A implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super self::A::•()
     ;
 }
 class F extends self::A implements self::C {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::F
     : super self::A::•()
     ;
 }
 class G extends self::A implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::G
     : super self::A::•()
     ;
 }
 class H extends self::C implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::H
     : super self::C::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
index c55fa65..ac7a863 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.outline.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -23,22 +41,22 @@
   abstract get x() → core::double;
 }
 class E extends self::A implements self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::E
     ;
 }
 class F extends self::A implements self::C {
-  field dynamic x;
+  field invalid-type x;
   synthetic constructor •() → self::F
     ;
 }
 class G extends self::A implements self::D {
-  field dynamic x;
+  field invalid-type x;
   synthetic constructor •() → self::G
     ;
 }
 class H extends self::C implements self::D {
-  field dynamic x;
+  field invalid-type x;
   synthetic constructor •() → self::H
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
index c24c0bb..b67d77f 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
@@ -17,54 +17,6 @@
 //   var x;
 //       ^
 //
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.x'.
-// Change to a subtype of 'int'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-//   int get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:7: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type, 'num', of the overridden method, 'C.x'.
-// Change to a subtype of 'num'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-//   num get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type, 'int', of the overridden method, 'A.x'.
-// Change to a subtype of 'int'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-//   int get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:7: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type, 'double', of the overridden method, 'D.x'.
-// Change to a subtype of 'double'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-//   double get x;
-//              ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type, 'num', of the overridden method, 'C.x'.
-// Change to a subtype of 'num'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-//   num get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:7: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type, 'double', of the overridden method, 'D.x'.
-// Change to a subtype of 'double'.
-//   var x;
-//       ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-//   double get x;
-//              ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -99,19 +51,19 @@
     ;
 }
 class F extends self::A implements self::C {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::F
     : super self::A::•()
     ;
 }
 class G extends self::A implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::G
     : super self::A::•()
     ;
 }
 class H extends self::C implements self::D {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::H
     : super self::C::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
index 651b972..f9b40cd 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.expect
@@ -15,7 +15,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
index 651b972..f9b40cd 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
index 07bf8f9..f76fc3b 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.outline.expect
@@ -13,7 +13,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::C
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
index 6e31b6d..c395f30 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.expect
@@ -11,9 +11,9 @@
   abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
 }
 class B extends self::A<core::int> {
-  field dynamic x = null;
-  field dynamic y = null;
-  field dynamic z = null;
+  field core::List<core::int> x = null;
+  generic-covariant-impl field core::List<core::int> y = null;
+  generic-covariant-impl field core::List<core::int> z = null;
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
index 6e31b6d..c395f30 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.legacy.transformed.expect
@@ -11,9 +11,9 @@
   abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
 }
 class B extends self::A<core::int> {
-  field dynamic x = null;
-  field dynamic y = null;
-  field dynamic z = null;
+  field core::List<core::int> x = null;
+  generic-covariant-impl field core::List<core::int> y = null;
+  generic-covariant-impl field core::List<core::int> z = null;
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
index 2fc6225..711058e 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.outline.expect
@@ -10,9 +10,9 @@
   abstract set y(generic-covariant-impl core::List<self::A::T> value) → void;
 }
 class B extends self::A<core::int> {
-  field dynamic x;
-  field dynamic y;
-  field dynamic z;
+  field core::List<core::int> x;
+  generic-covariant-impl field core::List<core::int> y;
+  generic-covariant-impl field core::List<core::int> z;
   synthetic constructor •() → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
index 72b90ee..9f9de47 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.expect
@@ -16,25 +16,25 @@
     return 0;
 }
 class C extends self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
 }
 class D extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::D
     : super self::B::•()
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::F
     : super core::Object::•()
     ;
@@ -45,7 +45,7 @@
     ;
 }
 class G extends self::_G&Object&B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::G
     : super self::_G&Object&B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
index 31c9fee..9f7817b 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.legacy.transformed.expect
@@ -16,25 +16,25 @@
     return 0;
 }
 class C extends self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
 }
 class D extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::D
     : super self::B::•()
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::F
     : super core::Object::•()
     ;
@@ -47,7 +47,7 @@
     return 0;
 }
 class G extends self::_G&Object&B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::G
     : super self::_G&Object&B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
index b627b29..99e2051 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.outline.expect
@@ -14,22 +14,22 @@
     ;
 }
 class C extends self::A {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::C
     ;
 }
 class D extends self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::D
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::E
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::F
     ;
 }
@@ -39,7 +39,7 @@
     ;
 }
 class G extends self::_G&Object&B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::G
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
index 8baaa28..3c16ce0 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.expect
@@ -15,25 +15,25 @@
   set x(core::int value) → void {}
 }
 class C extends self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
 }
 class D extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::D
     : super self::B::•()
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::F
     : super core::Object::•()
     ;
@@ -44,7 +44,7 @@
     ;
 }
 class G extends self::_G&Object&B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::G
     : super self::_G&Object&B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
index 1a36773..e3da27e 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.legacy.transformed.expect
@@ -15,25 +15,25 @@
   set x(core::int value) → void {}
 }
 class C extends self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
 }
 class D extends self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::D
     : super self::B::•()
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::F
     : super core::Object::•()
     ;
@@ -45,7 +45,7 @@
   set x(core::int value) → void {}
 }
 class G extends self::_G&Object&B {
-  field dynamic x = null;
+  field core::int x = null;
   synthetic constructor •() → self::G
     : super self::_G&Object&B::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
index 02e0c2b..0ce880d 100644
--- a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.outline.expect
@@ -14,22 +14,22 @@
     ;
 }
 class C extends self::A {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::C
     ;
 }
 class D extends self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::D
     ;
 }
 class E extends core::Object implements self::A {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::E
     ;
 }
 class F extends core::Object implements self::B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::F
     ;
 }
@@ -39,7 +39,7 @@
     ;
 }
 class G extends self::_G&Object&B {
-  field dynamic x;
+  field core::int x;
   synthetic constructor •() → self::G
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
index 18097da..e03bb9e 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.expect
@@ -10,7 +10,7 @@
   set x(core::double value) → void {}
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
index 18097da..e03bb9e 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.legacy.transformed.expect
@@ -10,7 +10,7 @@
   set x(core::double value) → void {}
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
index 96dbb50..4709de3 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
@@ -10,7 +10,7 @@
     ;
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
index 28bd84b..7dea358 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.expect
@@ -9,7 +9,7 @@
   abstract get x() → core::int;
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
index 28bd84b..7dea358 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
   abstract get x() → core::int;
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
index 11b26c0..5e18eaa 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.outline.expect
@@ -8,7 +8,7 @@
   abstract get x() → core::int;
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::int x;
   constructor •(dynamic x) → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
index d9bfe67..148028f 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.expect
@@ -9,7 +9,7 @@
   set x(core::double value) → void {}
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::double x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
index d9bfe67..148028f 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
   set x(core::double value) → void {}
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::double x;
   constructor •(dynamic x) → self::B
     : self::B::x = x, super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
index b2085f3..b0206ee 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
@@ -9,7 +9,7 @@
     ;
 }
 class B extends self::A {
-  final field dynamic x;
+  final field core::double x;
   constructor •(dynamic x) → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
index 3d410db..1bb410b 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::double;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
index 3d410db..1bb410b 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::double;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
index 35c511d..83d3f12 100644
--- a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.outline.expect
@@ -10,7 +10,7 @@
 abstract class B extends self::A {
   synthetic constructor •() → self::B
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::double;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
index 69eff1f1..62a80b3 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.expect
@@ -6,14 +6,14 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return self::f();
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
index 69eff1f1..62a80b3 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.legacy.transformed.expect
@@ -6,14 +6,14 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return self::f();
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
index a346b2f..64fa771 100644
--- a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.outline.expect
@@ -5,13 +5,13 @@
 class A extends core::Object implements self::B {
   synthetic constructor •() → self::A
     ;
-  get x() → dynamic
+  get x() → core::int
     ;
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     ;
-  abstract get x() → dynamic;
+  abstract get x() → core::int;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
index 5337a40..3c40a1e 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
@@ -1,14 +1,4 @@
 library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-//   f(x, y);
-//   ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-//   int f(int x);
-//       ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -32,8 +22,8 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  abstract method f(dynamic x, dynamic y) → dynamic;
-  abstract method g(dynamic x, [dynamic y = null]) → dynamic;
-  abstract method h(dynamic x, {dynamic y = null}) → dynamic;
+  abstract method f(core::int x, core::int y) → core::int;
+  abstract method g(core::int x, [core::int y = null]) → core::int;
+  abstract method h(core::int x, {core::int y = null}) → core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
index 5337a40..3c40a1e 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
@@ -1,14 +1,4 @@
 library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-//   f(x, y);
-//   ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-//   int f(int x);
-//       ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -32,8 +22,8 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  abstract method f(dynamic x, dynamic y) → dynamic;
-  abstract method g(dynamic x, [dynamic y = null]) → dynamic;
-  abstract method h(dynamic x, {dynamic y = null}) → dynamic;
+  abstract method f(core::int x, core::int y) → core::int;
+  abstract method g(core::int x, [core::int y = null]) → core::int;
+  abstract method h(core::int x, {core::int y = null}) → core::int;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
index 0ae3513..332234b 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
@@ -1,14 +1,4 @@
 library test;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:3: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-//   f(x, y);
-//   ^
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
-//   int f(int x);
-//       ^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -29,9 +19,9 @@
 abstract class C extends core::Object implements self::A, self::B {
   synthetic constructor •() → self::C
     ;
-  abstract method f(dynamic x, dynamic y) → dynamic;
-  abstract method g(dynamic x, [dynamic y]) → dynamic;
-  abstract method h(dynamic x, {dynamic y}) → dynamic;
+  abstract method f(core::int x, core::int y) → core::int;
+  abstract method g(core::int x, [core::int y]) → core::int;
+  abstract method h(core::int x, {core::int y}) → core::int;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
index b4be5c0..1b88745 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super self::D::•()
     ;
-  set foo(dynamic x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 class D extends core::Object {
   field core::int foo = null;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
index b4be5c0..1b88745 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super self::D::•()
     ;
-  set foo(dynamic x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 class D extends core::Object {
   field core::int foo = null;
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
index 6288aaf..688faaf 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.expect
@@ -6,12 +6,12 @@
   synthetic constructor •() → self::C
     : super self::D::•()
     ;
-  set foo(dynamic x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
-  set foo(core::int x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
index 6288aaf..688faaf 100644
--- a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.legacy.transformed.expect
@@ -6,12 +6,12 @@
   synthetic constructor •() → self::C
     : super self::D::•()
     ;
-  set foo(dynamic x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
-  set foo(core::int x) → dynamic {}
+  set foo(core::int x) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
index 24beb1d..6f68db4 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  static set foo(core::int x) → dynamic {}
+  static set foo(core::int x) → void {}
 }
-static set bar(core::int x) → dynamic {}
+static set bar(core::int x) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
index 24beb1d..6f68db4 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  static set foo(core::int x) → dynamic {}
+  static set foo(core::int x) → void {}
 }
-static set bar(core::int x) → dynamic {}
+static set bar(core::int x) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
index e12c95b..42e1a1a 100644
--- a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.outline.expect
@@ -5,10 +5,10 @@
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
-  static set foo(core::int x) → dynamic
+  static set foo(core::int x) → void
     ;
 }
-static set bar(core::int x) → dynamic
+static set bar(core::int x) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
index db7fb96..849953f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::double value) → void;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
index db7fb96..849953f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::double value) → void;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
index e80537c..1d8285f 100644
--- a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.outline.expect
@@ -10,7 +10,7 @@
 abstract class B extends self::A {
   synthetic constructor •() → self::B
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::double value) → void;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
index 0c5bffd..d58802b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.expect
@@ -6,13 +6,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set x(dynamic value) → void {}
+  set x(core::int value) → void {}
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
index 0c5bffd..d58802b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.legacy.transformed.expect
@@ -6,13 +6,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set x(dynamic value) → void {}
+  set x(core::int value) → void {}
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
index 47cd14e..462e7c5 100644
--- a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.outline.expect
@@ -5,13 +5,13 @@
 class A extends core::Object implements self::B {
   synthetic constructor •() → self::A
     ;
-  set x(dynamic value) → void
+  set x(core::int value) → void
     ;
 }
 abstract class B extends core::Object implements self::C {
   synthetic constructor •() → self::B
     ;
-  abstract set x(dynamic value) → void;
+  abstract set x(core::int value) → void;
 }
 abstract class C extends core::Object {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
index a8e04fb..670abbd 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  set x(core::Object o) → dynamic {}
+  set x(core::Object o) → void {}
 }
 static method main() → dynamic {
   new self::B::•().x = "hello";
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
index a8e04fb..670abbd 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  set x(core::Object o) → dynamic {}
+  set x(core::Object o) → void {}
 }
 static method main() → dynamic {
   new self::B::•().x = "hello";
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
index 4afa24f..2f2f40b 100644
--- a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.outline.expect
@@ -11,7 +11,7 @@
 class B extends self::A {
   synthetic constructor •() → self::B
     ;
-  set x(core::Object o) → dynamic
+  set x(core::Object o) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
index 26d089c..2f5e471 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
index 26d089c..2f5e471 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
index 1159f05..922bf72 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
index 1159f05..922bf72 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
index 707d09d..601e9bb 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
@@ -9,7 +9,7 @@
   synthetic constructor •() → self::C
     : super inf::B::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return null;
 }
 class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
index 707d09d..601e9bb 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
@@ -9,7 +9,7 @@
   synthetic constructor •() → self::C
     : super inf::B::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return null;
 }
 class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
index f32c8d5..0b1b2b0 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
@@ -22,7 +22,7 @@
   synthetic constructor •() → test::C
     : super self::B::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return null;
 }
 class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
index f32c8d5..0b1b2b0 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
@@ -22,7 +22,7 @@
   synthetic constructor •() → test::C
     : super self::B::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return null;
 }
 class A extends core::Object {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
index 927f51d..0360763 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.expect
@@ -13,9 +13,9 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
-  get w() → dynamic
+  get w() → core::int
     return "hello";
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
index 927f51d..0360763 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.legacy.transformed.expect
@@ -13,9 +13,9 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  get x() → dynamic
+  get x() → core::int
     return 3;
-  get w() → dynamic
+  get w() → core::int
     return "hello";
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
index 3c624e6..4f44d59 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::B<self::B::E>
     : super self::A::•()
     ;
-  get x() → dynamic
+  get x() → self::B::E
     return this.{self::B::y};
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
index 3c624e6..4f44d59 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::B<self::B::E>
     : super self::A::•()
     ;
-  get x() → dynamic
+  get x() → self::B::E
     return this.{self::B::y};
 }
 static method foo() → dynamic {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
index 23fb83d..2a0386f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.expect
@@ -26,7 +26,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → core::String {}
 }
 static method foo() → dynamic {
   core::int y = new self::B::•<dynamic>().m(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
index 23fb83d..2a0386f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → core::String {}
 }
 static method foo() → dynamic {
   core::int y = new self::B::•<dynamic>().m(null, null);
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
index ecee2c6..be1a80f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
@@ -23,7 +23,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → self::A<self::B::E> {}
 }
 static method foo() → dynamic {
   core::int y = new self::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
index ecee2c6..be1a80f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
@@ -23,7 +23,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → self::A<self::B::E> {}
 }
 static method foo() → dynamic {
   core::int y = new self::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
index 54ed9fa..c669cd7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
@@ -38,7 +38,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
 }
 static method foo() → dynamic {
   core::int y = new test::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
index 54ed9fa..c669cd7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
@@ -38,7 +38,7 @@
     ;
   get y() → core::int
     return 0;
-  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
 }
 static method foo() → dynamic {
   core::int y = new test::B::•<core::String>().m(null, null).value;
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
new file mode 100644
index 0000000..ebc84b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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.
+
+class A<X> {
+  final foo = "bar";
+}
+
+class B<Y> extends A<Y> {
+  final foo;
+
+  B(this.foo);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..6bb747c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<Y>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
new file mode 100644
index 0000000..d00064e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
new file mode 100644
index 0000000..0a5257b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field dynamic foo;
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field dynamic foo;
+  constructor •(dynamic foo) → self::B<self::B::Y>
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field core::String foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field core::String foo;
+  constructor •(core::String foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..faa19da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_depends_on_field_inference.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  final field core::String foo = "bar";
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+}
+class B<Y extends core::Object = dynamic> extends self::A<self::B::Y> {
+  final field core::String foo;
+  constructor •(core::String foo) → self::B<self::B::Y>
+    : self::B::foo = foo, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart
new file mode 100644
index 0000000..f905aee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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.
+
+abstract class A<X> {
+  void foo({Iterable<X> x});
+}
+
+class B<Y> implements A<Y> {
+  void foo({x}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect
new file mode 100644
index 0000000..c985c1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.hierarchy.expect
@@ -0,0 +1,69 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: A<Y>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+  method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+  method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect
new file mode 100644
index 0000000..986c56b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+  abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+  synthetic constructor •() → self::B<self::B::Y>
+    ;
+  method foo({generic-covariant-impl core::Iterable<self::B::Y> x}) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+  method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect
new file mode 100644
index 0000000..a036a98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_inference_with_type_parameters.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  abstract method foo({generic-covariant-impl core::Iterable<self::A::X> x = null}) → void;
+}
+class B<Y extends core::Object = dynamic> extends core::Object implements self::A<self::B::Y> {
+  synthetic constructor •() → self::B<self::B::Y>
+    : super core::Object::•()
+    ;
+  method foo({generic-covariant-impl core::Iterable<self::B::Y> x = null}) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
index e0cd00f..7e9ace6 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x(dynamic value) → dynamic {}
+  set x(core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
index e0cd00f..7e9ace6 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x(dynamic value) → dynamic {}
+  set x(core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
index 5052808..1ae8232 100644
--- a/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.outline.expect
@@ -17,7 +17,7 @@
 class D extends self::C implements self::I {
   synthetic constructor •() → self::D
     ;
-  set x(dynamic value) → dynamic
+  set x(core::int value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
index b1c6c5f..8793d9b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
@@ -15,7 +15,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  operator []=(core::Object x, core::Object y) → void {}
+  operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void {}
   method h() → void {
     super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
   }
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
index b1c6c5f..8793d9b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  operator []=(core::Object x, core::Object y) → void {}
+  operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void {}
   method h() → void {
     super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
   }
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
index 80fd653..adfd796 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
@@ -14,7 +14,7 @@
 class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
   synthetic constructor •() → self::C<self::C::U>
     ;
-  operator []=(core::Object x, core::Object y) → void
+  operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void
     ;
   method h() → void
     ;
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
index 20df3bc..219fa54 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
@@ -26,7 +26,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  method g(core::Object x) → self::E<asy::Future<self::C::U>>
+  method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     return null;
   method h() → void {
     dynamic x = super.{self::B::g}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
index 20df3bc..219fa54 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  method g(core::Object x) → self::E<asy::Future<self::C::U>>
+  method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     return null;
   method h() → void {
     dynamic x = super.{self::B::g}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
index f2b99a5..07019f3 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
@@ -22,7 +22,7 @@
 class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
   synthetic constructor •() → self::C<self::C::U>
     ;
-  method g(core::Object x) → self::E<asy::Future<self::C::U>>
+  method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     ;
   method h() → void
     ;
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
index fd035f1..87b866d 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
@@ -27,7 +27,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     return null;
-  set x(core::Object x) → void {}
+  set x(generic-covariant-impl core::Object x) → void {}
   method g() → void {
     dynamic y = super.{self::B::x};
   }
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
index fd035f1..87b866d 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     return null;
-  set x(core::Object x) → void {}
+  set x(generic-covariant-impl core::Object x) → void {}
   method g() → void {
     dynamic y = super.{self::B::x};
   }
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
index caa88dc..941b8de 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
@@ -23,7 +23,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     ;
-  set x(core::Object x) → void
+  set x(generic-covariant-impl core::Object x) → void
     ;
   method g() → void
     ;
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
index ae129dc..fec3618 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
@@ -27,7 +27,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     return null;
-  set x(core::Object x) → void {}
+  set x(generic-covariant-impl core::Object x) → void {}
   method g() → void {
     super.{self::B::x} = self::f<dynamic>();
   }
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
index ae129dc..fec3618 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     return null;
-  set x(core::Object x) → void {}
+  set x(generic-covariant-impl core::Object x) → void {}
   method g() → void {
     super.{self::B::x} = self::f<dynamic>();
   }
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
index 1fa178c..cf71077 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
@@ -23,7 +23,7 @@
     ;
   get x() → self::E<asy::Future<self::C::U>>
     ;
-  set x(core::Object x) → void
+  set x(generic-covariant-impl core::Object x) → void
     ;
   method g() → void
     ;
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
index 148400f..3a8a7d9 100644
--- a/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
@@ -58,7 +58,7 @@
     Object
   interfaces:
   classMembers:
-    Object.toString
+    StackTrace.Object.toString%StackTrace.toString
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -77,7 +77,7 @@
       -> StackTrace
   interfaces:
   classMembers:
-    Object.toString
+    StackTrace.Object.toString%StackTrace.toString
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
index 5d9af14..cf441f7 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
@@ -15,8 +15,8 @@
 // There's a circularity between b and c because a.f is generic, so the type of
 // c is required to infer b, and vice versa.
 
-var b = /*@returnType=invalid-type*/ () =>
-    a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(c);
+var b = /*@returnType=() -> invalid-type*/ () =>
+    a. /*@typeArgs=() -> invalid-type*/ /*@target=A::f*/ f(c);
 var c = /*@returnType=invalid-type*/ () =>
     a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(b);
 
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
index 1681eb9..2e9f7aa 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.expect
@@ -2,14 +2,9 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:5: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var c = /*@returnType=invalid-type*/ () =>
-//     ^
-//
 // pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:5: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () =>
+// var b = /*@returnType=() -> invalid-type*/ () =>
 //     ^
 //
 import self as self;
@@ -25,8 +20,8 @@
     return 0;
 }
 static field self::A a = new self::A::•();
-static field invalid-type b = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::c)) as{TypeError} invalid-type;
-static field invalid-type c = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::b)) as{TypeError} invalid-type;
+static field invalid-type b = (() → () → invalid-type => self::a.{self::A::f}<() → invalid-type>(self::c)) as{TypeError} invalid-type;
+static field () → invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
 static field () → () → core::int d = () → () → core::int => self::a.{self::A::f}<() → core::int>(self::e);
 static field () → core::int e = () → core::int => self::a.{self::A::g}(self::d);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
index 1681eb9..2e9f7aa 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
@@ -2,14 +2,9 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:5: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var c = /*@returnType=invalid-type*/ () =>
-//     ^
-//
 // pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:5: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
-// var b = /*@returnType=invalid-type*/ () =>
+// var b = /*@returnType=() -> invalid-type*/ () =>
 //     ^
 //
 import self as self;
@@ -25,8 +20,8 @@
     return 0;
 }
 static field self::A a = new self::A::•();
-static field invalid-type b = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::c)) as{TypeError} invalid-type;
-static field invalid-type c = (() → invalid-type => self::a.{self::A::f}<invalid-type>(self::b)) as{TypeError} invalid-type;
+static field invalid-type b = (() → () → invalid-type => self::a.{self::A::f}<() → invalid-type>(self::c)) as{TypeError} invalid-type;
+static field () → invalid-type c = () → invalid-type => self::a.{self::A::f}<invalid-type>(self::b);
 static field () → () → core::int d = () → () → core::int => self::a.{self::A::f}<() → core::int>(self::e);
 static field () → core::int e = () → core::int => self::a.{self::A::g}(self::d);
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
index f2657ee..88b2f85 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.expect
@@ -2,11 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:16:5: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var b = a();
-//     ^
-//
 // pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:5: Error: Can't infer the type of 'a': circularity found during type inference.
 // Specify the type explicitly.
 // var a = /*@returnType=num*/ () => intValue /*@target=num::+*/ + b;
@@ -19,7 +14,7 @@
 static field core::num numValue = 0;
 static field core::double doubleValue = 0.0;
 static field invalid-type a = (() → core::num => self::intValue.{core::num::+}(self::b as{TypeError} core::num)) as{TypeError} invalid-type;
-static field invalid-type b = self::a.call() as{TypeError} invalid-type;
+static field dynamic b = self::a.call();
 static field () → core::num c = () → core::num => self::numValue.{core::num::+}(self::d);
 static field core::num d = self::c.call();
 static field () → core::double e = () → core::double => self::doubleValue.{core::double::+}(self::f);
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
index e436c4f..4f2a4c9 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.expect
@@ -7,11 +7,6 @@
 //   var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
 //       ^
 //
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:17:7: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var x;
-//       ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
index e436c4f..4f2a4c9 100644
--- a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
@@ -7,11 +7,6 @@
 //   var x = /*@returnType=invalid-type*/ () => new B(). /*@target=B::x*/ x;
 //       ^
 //
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:17:7: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var x;
-//       ^
-//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
index 7848afa..cf2893f 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
@@ -56,3 +56,460 @@
     Object.==
   classSetters:
     B.x
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+double:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    double.~/
+    double.minPositive
+    num.<=
+    num._equalToInteger
+    double.maxFinite
+    num.isInfinite
+    num.<
+    double._tryParseDouble
+    double.Object.toString%double.toString
+    double.+
+    double.negativeInfinity
+    num.clamp
+    num.toDouble
+    double._nativeParse
+    double.ceil
+    double.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    double./
+    double.abs
+    double.nan
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    double.remainder
+    double.infinity
+    num.isFinite
+    num.toInt
+    double.%
+    double.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    double.floorToDouble
+    Object._identityHashCode
+    num.>
+    double.roundToDouble
+    double.round
+    double.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    double.truncate
+    double.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    double.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    double.truncateToDouble
+    double.parse
+    double.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    double._parse
+    double.*
+  classSetters:
+  interfaceMembers:
+    double.~/
+    double.minPositive
+    num.<=
+    num._equalToInteger
+    double.maxFinite
+    num.isInfinite
+    num.<
+    double._tryParseDouble
+    double.Object.toString%double.toString
+    double.+
+    double.negativeInfinity
+    num.clamp
+    num.toDouble
+    double._nativeParse
+    double.ceil
+    double.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    double./
+    double.abs
+    double.nan
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    double.remainder
+    double.infinity
+    num.isFinite
+    num.toInt
+    double.%
+    double.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    double.floorToDouble
+    Object._identityHashCode
+    num.>
+    double.roundToDouble
+    double.round
+    double.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    double.truncate
+    double.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    double.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    double.truncateToDouble
+    double.parse
+    double.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    double._parse
+    double.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
index 30f357c..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,7 +18,7 @@
   abstract set x(core::double value) → void;
 }
 class B extends self::A {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
index 30f357c..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,7 +18,7 @@
   abstract set x(core::double value) → void;
 }
 class B extends self::A {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
index 5006f0f..faa675a 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.outline.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -9,7 +17,7 @@
   abstract set x(core::double value) → void;
 }
 class B extends self::A {
-  field dynamic x;
+  field invalid-type x;
   synthetic constructor •() → self::B
     ;
 }
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
index 9a78098..86fb4dd 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
@@ -2,13 +2,10 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: The return type of the method 'B.x' is 'int', which does not match the return type, 'double', of the overridden method, 'A.x'.
-// Change to a subtype of 'double'.
+// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
 //   var x;
 //       ^
-// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:10:12: Context: This is the overridden method ('x').
-//   void set x(double value);
-//            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -21,7 +18,7 @@
   abstract set x(core::double value) → void;
 }
 class B extends self::A {
-  field core::int x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart
new file mode 100644
index 0000000..d6f3096
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+abstract class A {
+  A get x;
+  void set x(B value);
+
+  B get y;
+  void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect
new file mode 100644
index 0000000..b7417eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var y;
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract get x() → self::A;
+  abstract set x(self::B value) → void;
+  abstract get y() → self::B;
+  abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  field self::A x = null;
+  field invalid-type y = null;
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.legacy.transformed.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var y;
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract get x() → self::A;
+  abstract set x(self::B value) → void;
+  abstract get y() → self::B;
+  abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  field self::A x = null;
+  field invalid-type y = null;
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect
new file mode 100644
index 0000000..b6f7118
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.outline.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var y;
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  abstract get x() → self::A;
+  abstract set x(self::B value) → void;
+  abstract get y() → self::B;
+  abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends self::B {
+  field self::A x;
+  field invalid-type y;
+  synthetic constructor •() → self::C
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect
new file mode 100644
index 0000000..0517fd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart.strong.expect
@@ -0,0 +1,34 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart:17:7: Error: Can't infer a type for 'y' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var y;
+//       ^
+//
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  abstract get x() → self::A;
+  abstract set x(self::B value) → void;
+  abstract get y() → self::B;
+  abstract set y(self::A value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  field self::A x = null;
+  field invalid-type y = null;
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
index 167e1f9..b0e92da 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
@@ -76,3 +76,327 @@
     Object.==
   classSetters:
     C.x
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
index d397440..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -15,7 +23,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
index d397440..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -15,7 +23,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
index c425d73..42cca77 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.outline.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
+//   var x;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -13,7 +21,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field dynamic x;
+  field invalid-type x;
   synthetic constructor •() → self::C
     ;
 }
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
index 83026ec..d21c794 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
@@ -2,13 +2,10 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: The return type of the method 'C.x' is 'int', which does not match the return type, 'num', of the overridden method, 'A.x'.
-// Change to a subtype of 'num'.
+// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:7: Error: Can't infer a type for 'x' as some of the inherited members have different types.
+// Try adding an explicit type.
 //   var x;
 //       ^
-// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:9:12: Context: This is the overridden method ('x').
-//   void set x(num value);
-//            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -26,7 +23,7 @@
   abstract get x() → core::int;
 }
 class C extends self::B {
-  field core::int x = null;
+  field invalid-type x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
index 3dbfb21..6c951d9 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
@@ -76,3 +76,327 @@
     Object.==
   classSetters:
     C.x
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
index 24c6ed9..eec7015 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.expect
@@ -15,7 +15,7 @@
   abstract set x(core::int value) → void;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field core::num x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
index 24c6ed9..eec7015 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
   abstract set x(core::int value) → void;
 }
 class C extends self::B {
-  field dynamic x = null;
+  field core::num x = null;
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
index 2d2fda0..ef2b978 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.outline.expect
@@ -13,7 +13,7 @@
   abstract set x(core::int value) → void;
 }
 class C extends self::B {
-  field dynamic x;
+  field core::num x;
   synthetic constructor •() → self::C
     ;
 }
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
index 9ffd8ea..f24c3f1 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
@@ -8,12 +8,12 @@
 // In the code below, there is a circularity between A.b and x.
 
 class A {
-  var b = /*@returnType=invalid-type*/ () => x;
-  var c = /*@returnType=invalid-type*/ () => x;
+  var b = /*@returnType=() -> invalid-type*/ () => x;
+  var c = /*@returnType=() -> invalid-type*/ () => x;
 }
 
 var a = new A();
 var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-var y = /*@returnType=() -> invalid-type*/ () => a. /*@target=A::c*/ c;
+var y = /*@returnType=() -> () -> invalid-type*/ () => a. /*@target=A::c*/ c;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
index 46baf2b..73a2dd9 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.expect
@@ -4,25 +4,20 @@
 //
 // pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:7: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
-//   var b = /*@returnType=invalid-type*/ () => x;
+//   var b = /*@returnType=() -> invalid-type*/ () => x;
 //       ^
 //
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:16:5: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-//     ^
-//
 import self as self;
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type b = (() → invalid-type => self::x) as{TypeError} invalid-type;
-  field () → invalid-type c = () → invalid-type => self::x;
+  field invalid-type b = (() → () → invalid-type => self::x) as{TypeError} invalid-type;
+  field () → () → invalid-type c = () → () → invalid-type => self::x;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
 }
 static field self::A a = new self::A::•();
-static field invalid-type x = (() → invalid-type => self::a.{self::A::b}) as{TypeError} invalid-type;
-static field () → () → invalid-type y = () → () → invalid-type => self::a.{self::A::c};
+static field () → invalid-type x = () → invalid-type => self::a.{self::A::b};
+static field () → () → () → invalid-type y = () → () → () → invalid-type => self::a.{self::A::c};
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
index 46baf2b..73a2dd9 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
@@ -4,25 +4,20 @@
 //
 // pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:7: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
-//   var b = /*@returnType=invalid-type*/ () => x;
+//   var b = /*@returnType=() -> invalid-type*/ () => x;
 //       ^
 //
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:16:5: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-//     ^
-//
 import self as self;
 import "dart:core" as core;
 
 class A extends core::Object {
-  field invalid-type b = (() → invalid-type => self::x) as{TypeError} invalid-type;
-  field () → invalid-type c = () → invalid-type => self::x;
+  field invalid-type b = (() → () → invalid-type => self::x) as{TypeError} invalid-type;
+  field () → () → invalid-type c = () → () → invalid-type => self::x;
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
 }
 static field self::A a = new self::A::•();
-static field invalid-type x = (() → invalid-type => self::a.{self::A::b}) as{TypeError} invalid-type;
-static field () → () → invalid-type y = () → () → invalid-type => self::a.{self::A::c};
+static field () → invalid-type x = () → invalid-type => self::a.{self::A::b};
+static field () → () → () → invalid-type y = () → () → () → invalid-type => self::a.{self::A::c};
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
index f8f9e8f..3493bd8 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
-  method f() → dynamic {}
+  method f() → void {}
 }
 static field dynamic x = new self::C::•().f();
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
index f8f9e8f..3493bd8 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
-  method f() → dynamic {}
+  method f() → void {}
 }
 static field dynamic x = new self::C::•().f();
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
index ac467ff..fbaac00 100644
--- a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.outline.expect
@@ -11,7 +11,7 @@
 class C extends self::B {
   synthetic constructor •() → self::C
     ;
-  method f() → dynamic
+  method f() → void
     ;
 }
 static field dynamic x;
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
index f92d773..5a9daa5 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
@@ -72,7 +72,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    I1.f
+    C.I1.f%I2.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -136,7 +136,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    I2.f
+    E.I2.f%I1.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -181,3 +181,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
index 525f04b..e52d854 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.expect
@@ -18,6 +18,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
+  abstract forwarding-stub method f(core::Object o) → void;
 }
 class D extends self::C {
   synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
index 525f04b..e52d854 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.legacy.transformed.expect
@@ -18,6 +18,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
+  abstract forwarding-stub method f(core::Object o) → void;
 }
 class D extends self::C {
   synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
index cbba19d..68748a3 100644
--- a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.outline.expect
@@ -15,6 +15,7 @@
 abstract class C extends core::Object implements self::I1, self::I2 {
   synthetic constructor •() → self::C
     ;
+  abstract forwarding-stub method f(core::Object o) → void;
 }
 class D extends self::C {
   synthetic constructor •() → self::D
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
index 788e92f..d378992 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
@@ -14,7 +14,7 @@
 // circularity, and for error recovery their type is set to `dynamic`.
 // Thereafter, z infers without problems.
 
-var x = /*@returnType=invalid-type*/ () => f() ? y : z;
+var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
 var y = /*@returnType=invalid-type*/ () => x;
 var z = /*@returnType=invalid-type*/ () => x;
 
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
index 88bfdb0..b228e01 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
@@ -2,22 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:18:5: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var y = /*@returnType=invalid-type*/ () => x;
-//     ^
-//
 // pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var x = /*@returnType=invalid-type*/ () => f() ? y : z;
+// var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
 //     ^
 //
 import self as self;
 import "dart:core" as core;
 
-static field invalid-type x = (() → invalid-type => self::f() ?{invalid-type} self::y : self::z) as{TypeError} invalid-type;
-static field invalid-type y = (() → invalid-type => self::x) as{TypeError} invalid-type;
-static field () → dynamic z = () → invalid-type => self::x;
+static field invalid-type x = (() → () → invalid-type => self::f() ?{() → invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
+static field () → invalid-type z = () → invalid-type => self::x;
 static method f() → core::bool
   return null;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
index 9a54331..b228e01 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
@@ -2,22 +2,17 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
+// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:5: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
-// var  /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var  /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
+// var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
+//     ^
 //
 import self as self;
 import "dart:core" as core;
 
-static field dynamic x = () → dynamic => self::f() ?{dynamic} self::y : self::z;
-static field dynamic y = () → dynamic => self::x;
-static field () → dynamic z = () → dynamic => self::x;
+static field invalid-type x = (() → () → invalid-type => self::f() ?{() → invalid-type} self::y : self::z) as{TypeError} invalid-type;
+static field () → invalid-type y = () → invalid-type => self::x;
+static field () → invalid-type z = () → invalid-type => self::x;
 static method f() → core::bool
   return null;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
index 0f54c8d..bae8810 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
@@ -26,7 +26,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+  operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     return null;
   method h() → void {
     dynamic x = super.{self::B::[]}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
index 0f54c8d..bae8810 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
@@ -26,7 +26,7 @@
   synthetic constructor •() → self::C<self::C::U>
     : super self::B::•()
     ;
-  operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+  operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     return null;
   method h() → void {
     dynamic x = super.{self::B::[]}(self::f<dynamic>());
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
index 12ca495..482f685 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
@@ -22,7 +22,7 @@
 class C<U extends core::Object = dynamic> extends self::B<asy::Future<self::C::U>> {
   synthetic constructor •() → self::C<self::C::U>
     ;
-  operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+  operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
     ;
   method h() → void
     ;
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
index 00d3da3..59b9ccc 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
@@ -148,7 +148,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    D.foo
+    G.D.foo%E.foo%F.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
index cef6169..869fb78 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.expect
@@ -39,6 +39,7 @@
   synthetic constructor •() → self::G
     : super core::Object::•()
     ;
+  abstract forwarding-stub method foo() → self::B;
 }
 class H extends self::G {
   synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
index cef6169..869fb78 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.legacy.transformed.expect
@@ -39,6 +39,7 @@
   synthetic constructor •() → self::G
     : super core::Object::•()
     ;
+  abstract forwarding-stub method foo() → self::B;
 }
 class H extends self::G {
   synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
index 8801b74..b028b33 100644
--- a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.outline.expect
@@ -32,6 +32,7 @@
 abstract class G extends core::Object implements self::D, self::E, self::F {
   synthetic constructor •() → self::G
     ;
+  abstract forwarding-stub method foo() → self::B;
 }
 class H extends self::G {
   synthetic constructor •() → self::H
diff --git a/pkg/front_end/testcases/issue129167943.dart b/pkg/front_end/testcases/issue129167943.dart
new file mode 100644
index 0000000..c7560ea
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2019, 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.
+
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect b/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect
new file mode 100644
index 0000000..a8b24514
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.hierarchy.expect
@@ -0,0 +1,778 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D1:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, C, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D2:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, C, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D2.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D2.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D3:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, C, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D3.C.foo%B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D4:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, C, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D4.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D4.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D5:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, C, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D5.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D5.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.foo
+
+G:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: E
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    G.foo
+
+H1:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, E, G
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    H1.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H1.foo
+
+H2:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, E, G
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    H2.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H2.foo
+
+H3:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, E, G
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H3.E.foo=%G.foo=
+
+H4:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, E, G
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    H4.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H4.foo
+
+H5:
+  Longest path to Object: 3
+  superclasses:
+    Object
+  interfaces: A, E, G
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    H5.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H5.foo
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/issue129167943.dart.legacy.expect b/pkg/front_end/testcases/issue129167943.dart.legacy.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.legacy.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D4
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D5
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H1
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H2
+    : super core::Object::•()
+    ;
+  set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H4
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H5
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.legacy.transformed.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D4
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D5
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H1
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H2
+    : super core::Object::•()
+    ;
+  set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H4
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H5
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.outline.expect b/pkg/front_end/testcases/issue129167943.dart.outline.expect
new file mode 100644
index 0000000..f6d1af6
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.outline.expect
@@ -0,0 +1,82 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D1
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D2
+    ;
+  method foo(covariant core::int x) → void
+    ;
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D3
+    ;
+  abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D4
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D5
+    ;
+  abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → self::E
+    ;
+  abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+  synthetic constructor •() → self::G
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H1
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H2
+    ;
+  set foo(covariant core::int x) → void
+    ;
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H3
+    ;
+  abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H4
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H5
+    ;
+  abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/issue129167943.dart.strong.expect b/pkg/front_end/testcases/issue129167943.dart.strong.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.strong.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D4
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D5
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H1
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H2
+    : super core::Object::•()
+    ;
+  set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H4
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H5
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect b/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e60b76
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  abstract method foo(core::num x) → void;
+}
+abstract class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D1 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D1
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+class D2 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D2
+    : super core::Object::•()
+    ;
+  method foo(covariant core::int x) → void {}
+}
+abstract class D3 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method foo(covariant core::num x) → void;
+}
+abstract class D4 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D4
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::int x) → void;
+}
+abstract class D5 extends core::Object implements self::A, self::C, self::B {
+  synthetic constructor •() → self::D5
+    : super core::Object::•()
+    ;
+  abstract method foo(covariant core::num x) → void;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  abstract set foo(core::num x) → void;
+}
+abstract class G extends core::Object implements self::E {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H1 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H1
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+class H2 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H2
+    : super core::Object::•()
+    ;
+  set foo(covariant core::int x) → void {}
+}
+abstract class H3 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H3
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub set foo(covariant core::num x) → void;
+}
+abstract class H4 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H4
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::int x) → void;
+}
+abstract class H5 extends core::Object implements self::A, self::E, self::G {
+  synthetic constructor •() → self::H5
+    : super core::Object::•()
+    ;
+  abstract set foo(covariant core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue37381.dart b/pkg/front_end/testcases/issue37381.dart
new file mode 100644
index 0000000..9424045
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// This test checks that the bug reported at http://dartbug.com/37381 is fixed.
+
+class A<X> {
+  R f<R>(R Function<X>(A<X>) f) => f<X>(this);
+}
+
+main() {
+  A<num> a = A<int>();
+  a.f(<X>(_) => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.hierarchy.expect b/pkg/front_end/testcases/issue37381.dart.hierarchy.expect
new file mode 100644
index 0000000..8f0eb34
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/issue37381.dart.legacy.expect b/pkg/front_end/testcases/issue37381.dart.legacy.expect
new file mode 100644
index 0000000..13d9878
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.legacy.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+    return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+  self::A<core::num> a = new self::A::•<core::int>();
+  a.f(<X extends core::Object = dynamic>(dynamic _) → dynamic => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect
new file mode 100644
index 0000000..13d9878
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.legacy.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+    return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+  self::A<core::num> a = new self::A::•<core::int>();
+  a.f(<X extends core::Object = dynamic>(dynamic _) → dynamic => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.outline.expect b/pkg/front_end/testcases/issue37381.dart.outline.expect
new file mode 100644
index 0000000..74b9165
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    ;
+  method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/issue37381.dart.strong.expect b/pkg/front_end/testcases/issue37381.dart.strong.expect
new file mode 100644
index 0000000..4aa8cae
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.strong.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+    return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+  self::A<core::num> a = new self::A::•<core::int>();
+  a.{self::A::f}<core::int>(<X extends core::Object = dynamic>(self::A<X> _) → core::int => 42);
+}
diff --git a/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect b/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect
new file mode 100644
index 0000000..4aa8cae
--- /dev/null
+++ b/pkg/front_end/testcases/issue37381.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X>
+    : super core::Object::•()
+    ;
+  method f<R extends core::Object = dynamic>(<X extends core::Object = dynamic>(self::A<X>) → self::A::f::R f) → self::A::f::R
+    return f.call<self::A::X>(this);
+}
+static method main() → dynamic {
+  self::A<core::num> a = new self::A::•<core::int>();
+  a.{self::A::f}<core::int>(<X extends core::Object = dynamic>(self::A<X> _) → core::int => 42);
+}
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index b1b1917..45b13a3 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -7,12 +7,14 @@
 
 DeltaBlue: Fail # Fasta and dartk disagree on static initializers
 ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
+await_in_non_async: RuntimeError # Expected.
 bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
 call: Fail # Test can't run.
 constructor_const_inference: RuntimeError # Test exercises strong mode semantics.  See also Issue #33813.
 constructor_initializer_invalid: RuntimeError # Fails execution after recovery
 control_flow_collection: RuntimeError
 duplicated_field_initializer: RuntimeError
+extension_methods: RuntimeError
 external_import: RuntimeError # Expected -- test uses import which doesn't exist.
 fallthrough: Fail # Missing FallThroughError.
 function_type_recovery: Fail
@@ -37,6 +39,7 @@
 micro: Fail # External method marked abstract.
 minimum_int: Crash # Min int literal not supported in non-strong mode.
 named_parameters: Fail # Missing types and unnecessary default values.
+nnbd/nullable_param: RuntimeError
 operator_method_not_found: RuntimeError # Expected
 optional: Fail # Unnecessary default values.
 rasta/abstract_constructor: Fail
@@ -118,6 +121,7 @@
 regress/issue_36647: RuntimeError # Expected
 regress/issue_36647_2: RuntimeError # Expected
 regress/issue_36669: RuntimeError
+regress/issue_37285: RuntimeError
 reject_generic_function_types_in_bounds: RuntimeError # Expected
 runtime_checks/implicit_downcast_constructor_initializer: RuntimeError # Test exercises strong mode semantics
 runtime_checks/implicit_downcast_do: RuntimeError # Test exercises strong mode semantics
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
index 8351797..2d41275 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
@@ -115,7 +115,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A0.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -128,7 +128,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A0.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -180,7 +180,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A1.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -193,7 +193,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A1.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -279,7 +279,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A2.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -292,7 +292,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    A2.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -311,7 +311,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -324,7 +324,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -344,7 +344,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -357,7 +357,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -409,7 +409,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -422,7 +422,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -443,7 +443,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -456,7 +456,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -542,7 +542,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -555,7 +555,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -577,7 +577,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -590,7 +590,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _A2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -609,7 +609,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -622,7 +622,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -642,7 +642,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -655,7 +655,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -707,7 +707,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -720,7 +720,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -741,7 +741,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -754,7 +754,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -840,7 +840,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -853,7 +853,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -875,7 +875,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -888,7 +888,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -907,7 +907,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -920,7 +920,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -940,7 +940,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -953,7 +953,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -974,7 +974,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -987,7 +987,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    S with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1039,7 +1039,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1052,7 +1052,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1073,7 +1073,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1086,7 +1086,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1108,7 +1108,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1121,7 +1121,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B1X&S&M1 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1207,7 +1207,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1220,7 +1220,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1242,7 +1242,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1255,7 +1255,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1278,7 +1278,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -1291,7 +1291,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    M.foo
+    _B2X&S&M1&M2 with M.M.foo%S.foo
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
index b5c4a61..6856ac8 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
@@ -156,6 +156,7 @@
   synthetic constructor •() → self::A0
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A1&S&M1 = self::S with self::M1 {
   synthetic constructor •() → self::_A1&S&M1
@@ -166,6 +167,7 @@
   synthetic constructor •() → self::A1
     : super self::_A1&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A2&S&M1 = self::S with self::M1 {
   synthetic constructor •() → self::_A2&S&M1
@@ -181,11 +183,13 @@
   synthetic constructor •() → self::A2
     : super self::_A2&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A0X&S&M = self::S with self::M {
   synthetic constructor •() → self::_A0X&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A0X = self::_A0X&S&M with self::MX {
   synthetic constructor •() → self::A0X
@@ -201,6 +205,7 @@
   synthetic constructor •() → self::_A1X&S&M1&M
     : super self::_A1X&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A1X = self::_A1X&S&M1&M with self::MX {
   synthetic constructor •() → self::A1X
@@ -221,6 +226,7 @@
   synthetic constructor •() → self::_A2X&S&M1&M2&M
     : super self::_A2X&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A2X = self::_A2X&S&M1&M2&M with self::MX {
   synthetic constructor •() → self::A2X
@@ -231,6 +237,7 @@
   synthetic constructor •() → self::_B0&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B0 extends self::_B0&S&M {
   synthetic constructor •() → self::B0
@@ -246,6 +253,7 @@
   synthetic constructor •() → self::_B1&S&M1&M
     : super self::_B1&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B1 extends self::_B1&S&M1&M {
   synthetic constructor •() → self::B1
@@ -266,6 +274,7 @@
   synthetic constructor •() → self::_B2&S&M1&M2&M
     : super self::_B2&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B2 extends self::_B2&S&M1&M2&M {
   synthetic constructor •() → self::B2
@@ -276,6 +285,7 @@
   synthetic constructor •() → self::_B0X&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B0X&S&M&MX = self::_B0X&S&M with self::MX {
   synthetic constructor •() → self::_B0X&S&M&MX
@@ -296,6 +306,7 @@
   synthetic constructor •() → self::_B1X&S&M1&M
     : super self::_B1X&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B1X&S&M1&M&MX = self::_B1X&S&M1&M with self::MX {
   synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -321,6 +332,7 @@
   synthetic constructor •() → self::_B2X&S&M1&M2&M
     : super self::_B2X&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B2X&S&M1&M2&M&MX = self::_B2X&S&M1&M2&M with self::MX {
   synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
index c5a8827..f59920c 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
@@ -156,7 +156,7 @@
   synthetic constructor •() → self::A0
     : super self::S::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A1&S&M1 extends self::S implements self::M1 {
   synthetic constructor •() → self::_A1&S&M1
@@ -167,7 +167,7 @@
   synthetic constructor •() → self::A1
     : super self::_A1&S&M1::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A2&S&M1 extends self::S implements self::M1 {
   synthetic constructor •() → self::_A2&S&M1
@@ -183,13 +183,13 @@
   synthetic constructor •() → self::A2
     : super self::_A2&S&M1&M2::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _A0X&S&M extends self::S implements self::M {
   synthetic constructor •() → self::_A0X&S&M
     : super self::S::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A0X extends self::_A0X&S&M implements self::MX {
   synthetic constructor •() → self::A0X
@@ -205,7 +205,7 @@
   synthetic constructor •() → self::_A1X&S&M1&M
     : super self::_A1X&S&M1::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A1X extends self::_A1X&S&M1&M implements self::MX {
   synthetic constructor •() → self::A1X
@@ -226,7 +226,7 @@
   synthetic constructor •() → self::_A2X&S&M1&M2&M
     : super self::_A2X&S&M1&M2::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class A2X extends self::_A2X&S&M1&M2&M implements self::MX {
   synthetic constructor •() → self::A2X
@@ -237,7 +237,7 @@
   synthetic constructor •() → self::_B0&S&M
     : super self::S::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B0 extends self::_B0&S&M {
   synthetic constructor •() → self::B0
@@ -253,7 +253,7 @@
   synthetic constructor •() → self::_B1&S&M1&M
     : super self::_B1&S&M1::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B1 extends self::_B1&S&M1&M {
   synthetic constructor •() → self::B1
@@ -274,7 +274,7 @@
   synthetic constructor •() → self::_B2&S&M1&M2&M
     : super self::_B2&S&M1&M2::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 class B2 extends self::_B2&S&M1&M2&M {
   synthetic constructor •() → self::B2
@@ -285,7 +285,7 @@
   synthetic constructor •() → self::_B0X&S&M
     : super self::S::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B0X&S&M&MX extends self::_B0X&S&M implements self::MX {
   synthetic constructor •() → self::_B0X&S&M&MX
@@ -306,7 +306,7 @@
   synthetic constructor •() → self::_B1X&S&M1&M
     : super self::_B1X&S&M1::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B1X&S&M1&M&MX extends self::_B1X&S&M1&M implements self::MX {
   synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -332,7 +332,7 @@
   synthetic constructor •() → self::_B2X&S&M1&M2&M
     : super self::_B2X&S&M1&M2::•()
     ;
-  method foo() → dynamic {}
+  abstract forwarding-stub method foo([dynamic x = null]) → dynamic;
 }
 abstract class _B2X&S&M1&M2&M&MX extends self::_B2X&S&M1&M2&M implements self::MX {
   synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
index 9983cfb..a241bd6 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
@@ -153,6 +153,7 @@
   synthetic constructor •() → self::A0
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _A1&S&M1 = self::S with self::M1 {
   synthetic constructor •() → self::_A1&S&M1
@@ -163,6 +164,7 @@
   synthetic constructor •() → self::A1
     : super self::_A1&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _A2&S&M1 = self::S with self::M1 {
   synthetic constructor •() → self::_A2&S&M1
@@ -178,11 +180,13 @@
   synthetic constructor •() → self::A2
     : super self::_A2&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _A0X&S&M = self::S with self::M {
   synthetic constructor •() → self::_A0X&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class A0X = self::_A0X&S&M with self::MX {
   synthetic constructor •() → self::A0X
@@ -198,6 +202,7 @@
   synthetic constructor •() → self::_A1X&S&M1&M
     : super self::_A1X&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class A1X = self::_A1X&S&M1&M with self::MX {
   synthetic constructor •() → self::A1X
@@ -218,6 +223,7 @@
   synthetic constructor •() → self::_A2X&S&M1&M2&M
     : super self::_A2X&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class A2X = self::_A2X&S&M1&M2&M with self::MX {
   synthetic constructor •() → self::A2X
@@ -228,6 +234,7 @@
   synthetic constructor •() → self::_B0&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class B0 extends self::_B0&S&M {
   synthetic constructor •() → self::B0
@@ -242,6 +249,7 @@
   synthetic constructor •() → self::_B1&S&M1&M
     : super self::_B1&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class B1 extends self::_B1&S&M1&M {
   synthetic constructor •() → self::B1
@@ -261,6 +269,7 @@
   synthetic constructor •() → self::_B2&S&M1&M2&M
     : super self::_B2&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 class B2 extends self::_B2&S&M1&M2&M {
   synthetic constructor •() → self::B2
@@ -270,6 +279,7 @@
   synthetic constructor •() → self::_B0X&S&M
     : super self::S::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _B0X&S&M&MX = self::_B0X&S&M with self::MX {
   synthetic constructor •() → self::_B0X&S&M&MX
@@ -289,6 +299,7 @@
   synthetic constructor •() → self::_B1X&S&M1&M
     : super self::_B1X&S&M1::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _B1X&S&M1&M&MX = self::_B1X&S&M1&M with self::MX {
   synthetic constructor •() → self::_B1X&S&M1&M&MX
@@ -313,6 +324,7 @@
   synthetic constructor •() → self::_B2X&S&M1&M2&M
     : super self::_B2X&S&M1&M2::•()
     ;
+  abstract forwarding-stub method foo([dynamic x]) → dynamic;
 }
 abstract class _B2X&S&M1&M2&M&MX = self::_B2X&S&M1&M2&M with self::MX {
   synthetic constructor •() → self::_B2X&S&M1&M2&M&MX
diff --git a/pkg/front_end/testcases/native_as_name.dart.legacy.expect b/pkg/front_end/testcases/native_as_name.dart.legacy.expect
index 52a151a..b2691b8 100644
--- a/pkg/front_end/testcases/native_as_name.dart.legacy.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.legacy.expect
@@ -34,7 +34,7 @@
   synthetic constructor •() → self::Z
     : super core::Object::•()
     ;
-  set native(core::String s) → dynamic
+  set native(core::String s) → void
     return this.{self::Z::f} = s;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
index 52a151a..b2691b8 100644
--- a/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.legacy.transformed.expect
@@ -34,7 +34,7 @@
   synthetic constructor •() → self::Z
     : super core::Object::•()
     ;
-  set native(core::String s) → dynamic
+  set native(core::String s) → void
     return this.{self::Z::f} = s;
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/native_as_name.dart.outline.expect b/pkg/front_end/testcases/native_as_name.dart.outline.expect
index b78f8ae..c2df01d 100644
--- a/pkg/front_end/testcases/native_as_name.dart.outline.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.outline.expect
@@ -29,7 +29,7 @@
   field core::String f;
   synthetic constructor •() → self::Z
     ;
-  set native(core::String s) → dynamic
+  set native(core::String s) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart b/pkg/front_end/testcases/nnbd/nullable_param.dart
new file mode 100644
index 0000000..5de460c
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+class Foo {
+  int? field;
+  int? bar(int? x);
+}
+
+main() {
+  Foo foo = new Foo();
+  foo.field = 5;
+  foo.bar(6);
+
+  test_nullable_function_type_formal_param(f: () => 2);
+}
+
+int test_nullable_function_type_formal_param({int f()? : null}) {
+  return f() ?? -1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect
new file mode 100644
index 0000000..2d561e3
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.field
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect
new file mode 100644
index 0000000..f852bba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? field;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//               ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+//  - Foo.bar
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+//       ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+//   int? bar(int? x);
+//        ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.field = 5;
+  foo.bar(6);
+  self::test_nullable_function_type_formal_param(f: () → dynamic => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+  return let final dynamic #t1 = f.call() in #t1.==(null) ? 1.unary-() : #t1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f852bba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.legacy.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? field;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//               ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+//  - Foo.bar
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+//       ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+//   int? bar(int? x);
+//        ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.field = 5;
+  foo.bar(6);
+  self::test_nullable_function_type_formal_param(f: () → dynamic => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+  return let final dynamic #t1 = f.call() in #t1.==(null) ? 1.unary-() : #t1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
new file mode 100644
index 0000000..f909c50
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect
@@ -0,0 +1,51 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? field;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//               ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+//  - Foo.bar
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+//       ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+//   int? bar(int? x);
+//        ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field;
+  synthetic constructor •() → self::Foo
+    ;
+  abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic
+  ;
+static method test_nullable_function_type_formal_param({() → core::int f}) → core::int
+  ;
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
new file mode 100644
index 0000000..81c9259
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? field;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//               ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+//  - Foo.bar
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+//       ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+//   int? bar(int? x);
+//        ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.{self::Foo::field} = 5;
+  foo.{self::Foo::bar}(6);
+  self::test_nullable_function_type_formal_param(f: () → core::int => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+  return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int} 1.{core::int::unary-}() : #t1;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..81c9259
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:5:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? field;
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:6: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:15: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+//   int? bar(int? x);
+//               ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:17:54: Error: This requires the 'non-nullable' experiment to be enabled.
+// Try enabling this experiment by adding it to the command line when compiling and running.
+// int test_nullable_function_type_formal_param({int f()? : null}) {
+//                                                      ^
+//
+// pkg/front_end/testcases/nnbd/nullable_param.dart:4:7: Error: The non-abstract class 'Foo' is missing implementations for these members:
+//  - Foo.bar
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class Foo {
+//       ^^^
+// pkg/front_end/testcases/nnbd/nullable_param.dart:6:8: Context: 'Foo.bar' is defined here.
+//   int? bar(int? x);
+//        ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  abstract method bar(core::int x) → core::int;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.{self::Foo::field} = 5;
+  foo.{self::Foo::bar}(6);
+  self::test_nullable_function_type_formal_param(f: () → core::int => 2);
+}
+static method test_nullable_function_type_formal_param({() → core::int f = null}) → core::int {
+  return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int} 1.{core::int::unary-}() : #t1;
+}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
index 11c8d48..d420935 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
   no-such-method-forwarder get foo() → core::int
     return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
index 11c8d48..d420935 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
   no-such-method-forwarder get foo() → core::int
     return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
index 1756340..e7230a4 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.outline.expect
@@ -10,7 +10,7 @@
 class A extends core::Object implements self::I {
   synthetic constructor •() → self::A
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
   no-such-method-forwarder get foo() → core::int
     return this.{self::A::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
index 2e65c41..8387d6d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.expect
@@ -34,6 +34,6 @@
 }
 static method main() → dynamic {
   self::A a = new self::A::•();
-  self::expectTypeError(() → core::int => a.{self::A::foo});
+  self::expectTypeError(() → core::int => a.{self::I::foo});
   self::expectTypeError(() → core::String => (a as dynamic).foo = "bar");
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
index 2e65c41..8387d6d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.strong.transformed.expect
@@ -34,6 +34,6 @@
 }
 static method main() → dynamic {
   self::A a = new self::A::•();
-  self::expectTypeError(() → core::int => a.{self::A::foo});
+  self::expectTypeError(() → core::int => a.{self::I::foo});
   self::expectTypeError(() → core::String => (a as dynamic).foo = "bar");
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
index 0e0e756..fa7bf1f 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     self::count = self::count.+(1);
     return null;
   }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
index e0f993c..dae5f70 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     self::count = self::count.+(1);
     return null;
   }
@@ -25,7 +25,7 @@
   const synthetic constructor •() → self::_C&Object&B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     self::count = self::count.+(1);
     return null;
   }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
index d92df10..11ba2e6 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.outline.expect
@@ -10,7 +10,7 @@
 class B extends core::Object implements self::A {
   synthetic constructor •() → self::B
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
   no-such-method-forwarder get foo() → core::int
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
index c7fedd2..b172437 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.expect
@@ -14,7 +14,7 @@
     ;
   get foo() → core::int
     return 42;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
 }
 class C extends self::B {
@@ -29,7 +29,7 @@
     : super core::Object::•()
     ;
   set foo(core::int value) → void {}
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
index c7fedd2..b172437 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.legacy.transformed.expect
@@ -14,7 +14,7 @@
     ;
   get foo() → core::int
     return 42;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
 }
 class C extends self::B {
@@ -29,7 +29,7 @@
     : super core::Object::•()
     ;
   set foo(core::int value) → void {}
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return "bar";
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
index 523367d..ed38e84 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.outline.expect
@@ -12,7 +12,7 @@
     ;
   get foo() → core::int
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
 }
 class C extends self::B {
@@ -26,7 +26,7 @@
     ;
   set foo(core::int value) → void
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
index cb4a71e..7417039 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.expect
@@ -51,5 +51,5 @@
   self::C c = new self::C::•();
   self::expectTypeError(() → core::String => (c as dynamic).foo = "bar");
   self::E e = new self::E::•();
-  self::expectTypeError(() → core::int => e.{self::E::foo});
+  self::expectTypeError(() → core::int => e.{self::A::foo});
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
index cb4a71e..7417039 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.strong.transformed.expect
@@ -51,5 +51,5 @@
   self::C c = new self::C::•();
   self::expectTypeError(() → core::String => (c as dynamic).foo = "bar");
   self::E e = new self::E::•();
-  self::expectTypeError(() → core::int => e.{self::E::foo});
+  self::expectTypeError(() → core::int => e.{self::A::foo});
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
index ed949f6..3daf444 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return <dynamic>[];
   no-such-method-forwarder get foo() → core::List<core::int>
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
index ed949f6..3daf444 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return <dynamic>[];
   no-such-method-forwarder get foo() → core::List<core::int>
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
index 9679fbf..0cdcb88 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.outline.expect
@@ -10,7 +10,7 @@
 class B extends core::Object implements self::A<core::int> {
   synthetic constructor •() → self::B
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
   no-such-method-forwarder get foo() → core::List<core::int>
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 1, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} core::List<core::int>;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
index 0b0b415..a705020 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.expect
@@ -29,6 +29,6 @@
 }
 static method main() → dynamic {
   self::B b = new self::B::•();
-  self::expectTypeError(() → core::List<core::int> => b.{self::B::foo});
+  self::expectTypeError(() → core::List<core::int> => b.{self::A::foo});
   self::expectTypeError(() → core::List<dynamic> => (b as dynamic).foo = <dynamic>[]);
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
index 0b0b415..a705020 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.strong.transformed.expect
@@ -29,6 +29,6 @@
 }
 static method main() → dynamic {
   self::B b = new self::B::•();
-  self::expectTypeError(() → core::List<core::int> => b.{self::B::foo});
+  self::expectTypeError(() → core::List<core::int> => b.{self::A::foo});
   self::expectTypeError(() → core::List<dynamic> => (b as dynamic).foo = <dynamic>[]);
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
index 521bedd..b71a516 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.expect
@@ -18,7 +18,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return null;
   no-such-method-forwarder method foo() → dynamic
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
index 528ca88..7cd29a7 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return null;
   no-such-method-forwarder method foo() → dynamic
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::_C&A&B
     : super self::A::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return null;
 }
 class C extends self::_C&A&B {
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
index 8007c45..f04505e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.outline.expect
@@ -16,7 +16,7 @@
 class B extends core::Object implements self::I {
   synthetic constructor •() → self::B
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     ;
   no-such-method-forwarder method foo() → dynamic
     return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
index 5f6f35b..075405d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.expect
@@ -31,10 +31,10 @@
 static method main() → dynamic {
   self::B b = new self::B::•();
   dynamic value;
-  if(!(value = b.{self::B::foo}()).{core::String::==}("baz")) {
+  if(!(value = b.{self::A::foo}()).{core::String::==}("baz")) {
     throw "Unexpected value: '${value}'; expected 'baz'.";
   }
-  if(!(value = b.{self::B::hest}()).{core::num::==}(42)) {
+  if(!(value = b.{self::A::hest}()).{core::num::==}(42)) {
     throw "Unexpected value: '${value}'; expected '42'.";
   }
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
index 5f6f35b..075405d 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.strong.transformed.expect
@@ -31,10 +31,10 @@
 static method main() → dynamic {
   self::B b = new self::B::•();
   dynamic value;
-  if(!(value = b.{self::B::foo}()).{core::String::==}("baz")) {
+  if(!(value = b.{self::A::foo}()).{core::String::==}("baz")) {
     throw "Unexpected value: '${value}'; expected 'baz'.";
   }
-  if(!(value = b.{self::B::hest}()).{core::num::==}(42)) {
+  if(!(value = b.{self::A::hest}()).{core::num::==}(42)) {
     throw "Unexpected value: '${value}'; expected '42'.";
   }
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
index f0470a5..f405f12 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return null;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
index f0470a5..f405f12 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return null;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
index 32e8f80..e5f2ba8 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.outline.expect
@@ -5,7 +5,7 @@
 abstract class A extends core::Object {
   synthetic constructor •() → self::A
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
index bf620af..05f2839 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return null;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
index bf620af..05f2839 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     return null;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
index e72d0cf..df83640 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.outline.expect
@@ -5,7 +5,7 @@
 abstract class A extends core::Object {
   synthetic constructor •() → self::A
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
   abstract method foo() → void;
 }
diff --git a/pkg/front_end/testcases/operators.dart.legacy.expect b/pkg/front_end/testcases/operators.dart.legacy.expect
index 9760fe2..639223b 100644
--- a/pkg/front_end/testcases/operators.dart.legacy.expect
+++ b/pkg/front_end/testcases/operators.dart.legacy.expect
@@ -18,7 +18,7 @@
     return null;
   operator /(dynamic other) → dynamic
     return null;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return null;
   operator >(dynamic other) → dynamic
     return null;
diff --git a/pkg/front_end/testcases/operators.dart.legacy.transformed.expect b/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
index 9760fe2..639223b 100644
--- a/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/operators.dart.legacy.transformed.expect
@@ -18,7 +18,7 @@
     return null;
   operator /(dynamic other) → dynamic
     return null;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return null;
   operator >(dynamic other) → dynamic
     return null;
diff --git a/pkg/front_end/testcases/operators.dart.outline.expect b/pkg/front_end/testcases/operators.dart.outline.expect
index 22aa8c4..68ed1ff 100644
--- a/pkg/front_end/testcases/operators.dart.outline.expect
+++ b/pkg/front_end/testcases/operators.dart.outline.expect
@@ -17,7 +17,7 @@
     ;
   operator /(dynamic other) → dynamic
     ;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     ;
   operator >(dynamic other) → dynamic
     ;
diff --git a/pkg/front_end/testcases/optional.dart.outline.expect b/pkg/front_end/testcases/optional.dart.outline.expect
index 0f681fd..03d2b6e 100644
--- a/pkg/front_end/testcases/optional.dart.outline.expect
+++ b/pkg/front_end/testcases/optional.dart.outline.expect
@@ -22,13 +22,13 @@
 class TestListener extends self::Listener {
   synthetic constructor •() → self::TestListener
     ;
-  method event(dynamic input, [dynamic x, dynamic y]) → void
+  method event(core::String input, [core::int x, core::int y]) → void
     ;
 }
 class ExtendedListener extends self::Listener {
   synthetic constructor •() → self::ExtendedListener
     ;
-  method event(dynamic input, [dynamic x, dynamic y, dynamic z]) → void
+  method event(core::String input, [core::int x, core::int y, dynamic z]) → void
     ;
 }
 class InvalidListener extends core::Object {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
index cf84a61..b8259ec 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.expect
@@ -24,8 +24,8 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x(dynamic value) → void {}
-  get y() → dynamic
+  set x(self::A value) → void {}
+  get y() → self::B
     return null;
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
index cf84a61..b8259ec 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.legacy.transformed.expect
@@ -24,8 +24,8 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x(dynamic value) → void {}
-  get y() → dynamic
+  set x(self::A value) → void {}
+  get y() → self::B
     return null;
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
index 98a1f1b..f6baaa1 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.outline.expect
@@ -21,9 +21,9 @@
 class D extends self::C {
   synthetic constructor •() → self::D
     ;
-  set x(dynamic value) → void
+  set x(self::A value) → void
     ;
-  get y() → dynamic
+  get y() → self::B
     ;
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
index 7a03141..ec9f575 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x1(self::B value) → void {}
+  set x1(covariant self::B value) → void {}
   set x2(covariant self::B value) → void {}
   set x3(covariant self::B value) → void {}
   set x4(self::B value) → void {}
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
index 7a03141..ec9f575 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  set x1(self::B value) → void {}
+  set x1(covariant self::B value) → void {}
   set x2(covariant self::B value) → void {}
   set x3(covariant self::B value) → void {}
   set x4(self::B value) → void {}
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
index f5ae95c..eb8c429 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.outline.expect
@@ -29,7 +29,7 @@
 class D extends self::C {
   synthetic constructor •() → self::D
     ;
-  set x1(self::B value) → void
+  set x1(covariant self::B value) → void
     ;
   set x2(covariant self::B value) → void
     ;
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
index deaf420..adf56f6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.expect
@@ -22,7 +22,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f(dynamic x) → void {}
+  method f(self::A x) → void {}
 }
 class E extends self::D {
   synthetic constructor •() → self::E
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
index deaf420..adf56f6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.legacy.transformed.expect
@@ -22,7 +22,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f(dynamic x) → void {}
+  method f(self::A x) → void {}
 }
 class E extends self::D {
   synthetic constructor •() → self::E
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect b/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
index 82c9ce4..6f3f1e6 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.outline.expect
@@ -19,7 +19,7 @@
 class D extends self::C {
   synthetic constructor •() → self::D
     ;
-  method f(dynamic x) → void
+  method f(self::A x) → void
     ;
 }
 class E extends self::D {
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
index dd0c4d5..05d92ea 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void {}
+  method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
index dd0c4d5..05d92ea 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.legacy.transformed.expect
@@ -12,6 +12,6 @@
   synthetic constructor •() → self::B
     : super self::A::•()
     ;
-  method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void {}
+  method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
index e836ac4..713595c 100644
--- a/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.outline.expect
@@ -11,7 +11,7 @@
 class B extends self::A<core::String> {
   synthetic constructor •() → self::B
     ;
-  method f<V extends core::Object = dynamic>(core::Map<core::String, self::B::f::V> m) → void
+  method f<V extends core::Object = dynamic>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
index bd8f94e..30f268c 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f1(self::B x) → void {}
+  method f1(covariant self::B x) → void {}
   method f2(covariant self::B x) → void {}
   method f3(covariant self::B x) → void {}
   method f4(self::B x) → void {}
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
index bd8f94e..30f268c 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.legacy.transformed.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f1(self::B x) → void {}
+  method f1(covariant self::B x) → void {}
   method f2(covariant self::B x) → void {}
   method f3(covariant self::B x) → void {}
   method f4(self::B x) → void {}
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
index 2d4aa32..5ff196d 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.outline.expect
@@ -29,7 +29,7 @@
 class D extends self::C {
   synthetic constructor •() → self::D
     ;
-  method f1(self::B x) → void
+  method f1(covariant self::B x) → void
     ;
   method f2(covariant self::B x) → void
     ;
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart b/pkg/front_end/testcases/override_inference_for_setters.dart
new file mode 100644
index 0000000..0da2cf9
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+class B {
+  num get foo => null;
+  set foo(dynamic newFoo) {}
+}
+
+class A extends B {
+  set foo(newFoo) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect
new file mode 100644
index 0000000..b1e3c8a
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.foo
+
+A:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  get foo() → core::num
+    return null;
+  set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+  synthetic constructor •() → self::A
+    : super self::B::•()
+    ;
+  set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.legacy.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  get foo() → core::num
+    return null;
+  set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+  synthetic constructor •() → self::A
+    : super self::B::•()
+    ;
+  set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect
new file mode 100644
index 0000000..1c22d1f
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+  get foo() → core::num
+    ;
+  set foo(dynamic newFoo) → void
+    ;
+}
+class A extends self::B {
+  synthetic constructor •() → self::A
+    ;
+  set foo(dynamic newFoo) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  get foo() → core::num
+    return null;
+  set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+  synthetic constructor •() → self::A
+    : super self::B::•()
+    ;
+  set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect
new file mode 100644
index 0000000..fd832da
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_for_setters.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+  get foo() → core::num
+    return null;
+  set foo(dynamic newFoo) → void {}
+}
+class A extends self::B {
+  synthetic constructor •() → self::A
+    : super self::B::•()
+    ;
+  set foo(dynamic newFoo) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart
new file mode 100644
index 0000000..d5210c1
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+// The test checks that override-based inference for named parameters isn't
+// affected by the name-based ordering of the parameters.
+
+class A {
+  foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+  foo({c = true, bool a}) {}
+}
+
+class C extends B {
+  foo({bool c = true, bool a}) {}
+}
+
+// A1, B1, and C1 are similar to A, B, and C, only they have the names of the
+// named parameters swapped, to test that the alternative ordering works.
+
+class A1 {
+  foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+  foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+  foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
new file mode 100644
index 0000000..9fb9b41
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
@@ -0,0 +1,133 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B1:
+  superclasses:
+    Object
+      -> A1
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+      -> A1
+        -> B1
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+  synthetic constructor •() → self::B1
+    : super self::A1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+  synthetic constructor •() → self::C1
+    : super self::B1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+  synthetic constructor •() → self::B1
+    : super self::A1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+  synthetic constructor •() → self::C1
+    : super self::B1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
new file mode 100644
index 0000000..7a732b2
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+  method foo({core::bool c, core::bool a}) → dynamic
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  method foo({core::bool c, core::bool a}) → dynamic
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    ;
+  method foo({core::bool c, core::bool a}) → dynamic
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    ;
+  method foo({core::bool a, core::bool c}) → dynamic
+    ;
+}
+class B1 extends self::A1 {
+  synthetic constructor •() → self::B1
+    ;
+  method foo({core::bool a, core::bool c}) → dynamic
+    ;
+}
+class C1 extends self::B1 {
+  synthetic constructor •() → self::C1
+    ;
+  method foo({core::bool a, core::bool c}) → dynamic
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+  synthetic constructor •() → self::B1
+    : super self::A1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+  synthetic constructor •() → self::C1
+    : super self::B1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+  method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+  synthetic constructor •() → self::B1
+    : super self::A1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+  synthetic constructor •() → self::C1
+    : super self::B1::•()
+    ;
+  method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
index 5a47079..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
@@ -15,7 +15,7 @@
   C() : field = null;
         ^^^^^"
     ;
-  set field(dynamic value) → dynamic {}
+  set field(dynamic value) → void {}
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
index 5a47079..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
   C() : field = null;
         ^^^^^"
     ;
-  set field(dynamic value) → dynamic {}
+  set field(dynamic value) → void {}
 }
 static method main() → dynamic {
   new self::C::•();
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
index 97d6cdd..1f58e29 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.outline.expect
@@ -5,7 +5,7 @@
 class C extends core::Object {
   constructor •() → self::C
     ;
-  set field(dynamic value) → dynamic
+  set field(dynamic value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
index 5fabc15..3be7ccc 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.expect
@@ -4,7 +4,7 @@
 
 static get x() → dynamic
   return 42;
-static set x(dynamic val) → dynamic {}
+static set x(dynamic val) → void {}
 static method main() → dynamic {
   core::print(self::x);
   core::print(self::x = 87);
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
index 5fabc15..3be7ccc 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.legacy.transformed.expect
@@ -4,7 +4,7 @@
 
 static get x() → dynamic
   return 42;
-static set x(dynamic val) → dynamic {}
+static set x(dynamic val) → void {}
 static method main() → dynamic {
   core::print(self::x);
   core::print(self::x = 87);
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
index aab1950..8ee979d 100644
--- a/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.outline.expect
@@ -3,7 +3,7 @@
 
 static get x() → dynamic
   ;
-static set x(dynamic val) → dynamic
+static set x(dynamic val) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
index 6fe92fb..953dad2 100644
--- a/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
@@ -67,7 +67,7 @@
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
-    M1.v2
+    C.M1.v2%A.v2
     Object._instanceOf
     Object.noSuchMethod
     Object._identityHashCode
@@ -77,13 +77,13 @@
     Object._simpleInstanceOfTrue
     Object.==
   classSetters:
-    M1.v2
+    C.M1.v2%A.v2
     A.v1
   interfaceMembers:
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
-    M1.v2
+    C.M1.v2%A.v2
     Object._instanceOf
     Object.noSuchMethod
     Object._identityHashCode
@@ -93,5 +93,5 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    M1.v2
+    C.M1.v2%A.v2
     A.v1
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
index 230c10b..4dbd973 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return throw "x";
   method test() → dynamic {
     super.{core::Object::==}(null);
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
index 230c10b..4dbd973 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return throw "x";
   method test() → dynamic {
     super.{core::Object::==}(null);
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
index bc032b0..f3f1fd5 100644
--- a/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.outline.expect
@@ -5,7 +5,7 @@
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     ;
   method test() → dynamic
     ;
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
index cb7bd6b..b12559d 100644
--- a/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.outline.expect
@@ -11,7 +11,7 @@
   field core::int _hashCode;
   synthetic constructor •() → self::Sub
     ;
-  get hashCode() → dynamic
+  get hashCode() → core::int
     ;
   method foo() → dynamic
     ;
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
index a7ea25b..fc3831b 100644
--- a/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.outline.expect
@@ -5,7 +5,7 @@
 class Bar extends core::Object {
   get x() → self::Bar
     ;
-  set x(self::Bar value) → dynamic
+  set x(self::Bar value) → void
     ;
   method f() → dynamic
     ;
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
index 70d0f8c..b9c1b3e 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
@@ -150,7 +150,7 @@
   static method staticFunction() → dynamic {}
   static get staticGetter() → dynamic
     return null;
-  static set staticSetter(dynamic _) → dynamic {}
+  static set staticSetter(dynamic _) → void {}
 }
 static method use(dynamic x) → dynamic {
   if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
index 70d0f8c..b9c1b3e 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
@@ -150,7 +150,7 @@
   static method staticFunction() → dynamic {}
   static get staticGetter() → dynamic
     return null;
-  static set staticSetter(dynamic _) → dynamic {}
+  static set staticSetter(dynamic _) → void {}
 }
 static method use(dynamic x) → dynamic {
   if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
diff --git a/pkg/front_end/testcases/rasta/static.dart.outline.expect b/pkg/front_end/testcases/rasta/static.dart.outline.expect
index f9b177a..2e9d362 100644
--- a/pkg/front_end/testcases/rasta/static.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.outline.expect
@@ -11,7 +11,7 @@
     ;
   static get staticGetter() → dynamic
     ;
-  static set staticSetter(dynamic _) → dynamic
+  static set staticSetter(dynamic _) → void
     ;
 }
 static method use(dynamic x) → dynamic
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
index 55dfd57..dbd7908 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
@@ -253,24 +253,24 @@
     ;
   get e() → dynamic
     return null;
-  set g(dynamic _) → dynamic {}
+  set g(dynamic _) → void {}
   get h() → dynamic
     return null;
-  set h(dynamic _) → dynamic {}
+  set h(dynamic _) → void {}
   get i() → dynamic
     return null;
   operator [](dynamic _) → dynamic
     return null;
-  operator []=(dynamic a, dynamic b) → dynamic {}
+  operator []=(dynamic a, dynamic b) → void {}
   operator ~() → dynamic
     return 117;
   operator unary-() → dynamic
     return 117;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return true;
   method m() → void {}
   method n() → void {}
-  set n(dynamic _) → dynamic {}
+  set n(dynamic _) → void {}
 }
 class B extends self::A {
   final field dynamic d = null;
@@ -279,8 +279,8 @@
     ;
   get b() → dynamic
     return null;
-  set c(dynamic x) → dynamic {}
-  set i(dynamic x) → dynamic {}
+  set c(dynamic x) → void {}
+  set i(dynamic x) → void {}
 }
 class C extends self::B {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
index 55dfd57..dbd7908 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
@@ -253,24 +253,24 @@
     ;
   get e() → dynamic
     return null;
-  set g(dynamic _) → dynamic {}
+  set g(dynamic _) → void {}
   get h() → dynamic
     return null;
-  set h(dynamic _) → dynamic {}
+  set h(dynamic _) → void {}
   get i() → dynamic
     return null;
   operator [](dynamic _) → dynamic
     return null;
-  operator []=(dynamic a, dynamic b) → dynamic {}
+  operator []=(dynamic a, dynamic b) → void {}
   operator ~() → dynamic
     return 117;
   operator unary-() → dynamic
     return 117;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     return true;
   method m() → void {}
   method n() → void {}
-  set n(dynamic _) → dynamic {}
+  set n(dynamic _) → void {}
 }
 class B extends self::A {
   final field dynamic d = null;
@@ -279,8 +279,8 @@
     ;
   get b() → dynamic
     return null;
-  set c(dynamic x) → dynamic {}
-  set i(dynamic x) → dynamic {}
+  set c(dynamic x) → void {}
+  set i(dynamic x) → void {}
 }
 class C extends self::B {
   synthetic constructor •() → self::C
diff --git a/pkg/front_end/testcases/rasta/super.dart.outline.expect b/pkg/front_end/testcases/rasta/super.dart.outline.expect
index d668783..9b0da41 100644
--- a/pkg/front_end/testcases/rasta/super.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.outline.expect
@@ -22,29 +22,29 @@
     ;
   get e() → dynamic
     ;
-  set g(dynamic _) → dynamic
+  set g(dynamic _) → void
     ;
   get h() → dynamic
     ;
-  set h(dynamic _) → dynamic
+  set h(dynamic _) → void
     ;
   get i() → dynamic
     ;
   operator [](dynamic _) → dynamic
     ;
-  operator []=(dynamic a, dynamic b) → dynamic
+  operator []=(dynamic a, dynamic b) → void
     ;
   operator ~() → dynamic
     ;
   operator unary-() → dynamic
     ;
-  operator ==(dynamic other) → dynamic
+  operator ==(dynamic other) → core::bool
     ;
   method m() → void
     ;
   method n() → void
     ;
-  set n(dynamic _) → dynamic
+  set n(dynamic _) → void
     ;
 }
 class B extends self::A {
@@ -53,9 +53,9 @@
     ;
   get b() → dynamic
     ;
-  set c(dynamic x) → dynamic
+  set c(dynamic x) → void
     ;
-  set i(dynamic x) → dynamic
+  set i(dynamic x) → void
     ;
 }
 class C extends self::B {
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect b/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
index d0ecc4d..01e59ad 100644
--- a/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.outline.expect
@@ -9,7 +9,7 @@
     ;
   operator [](dynamic i) → dynamic
     ;
-  operator []=(dynamic i, dynamic val) → dynamic
+  operator []=(dynamic i, dynamic val) → void
     ;
 }
 class B extends self::A {
@@ -19,7 +19,7 @@
     ;
   operator [](dynamic i) → dynamic
     ;
-  operator []=(dynamic i, dynamic val) → dynamic
+  operator []=(dynamic i, dynamic val) → void
     ;
 }
 class Autobianchi extends core::Object {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
index bba4f23..32a5b17 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
@@ -25,7 +25,7 @@
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     : super self::B::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::C::V},${self::C::S},${self::C::R}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
index bba4f23..32a5b17 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
@@ -25,7 +25,7 @@
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     : super self::B::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::C::V},${self::C::S},${self::C::R}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
index 3b0ee19..d4a0e63 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
@@ -21,7 +21,7 @@
 class C<V extends core::Object = dynamic, S extends core::Object = dynamic, R extends core::Object = dynamic> extends self::B<self::C::V, self::C::S> {
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     ;
-  method toString() → dynamic
+  method toString() → core::String
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
index cee4e10..09e1d27 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
@@ -25,7 +25,7 @@
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     : super self::B::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::C::V},${self::C::S},${self::C::R}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
index cee4e10..09e1d27 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
@@ -25,7 +25,7 @@
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     : super self::B::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::C::V},${self::C::S},${self::C::R}";
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
index 2b481ac..f9db296 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
@@ -21,7 +21,7 @@
 class C<V extends core::Object = dynamic, S extends core::Object = dynamic, R extends core::Object = dynamic> extends self::B<self::C::V, self::C::S> {
   constructor •() → self::C<self::C::V, self::C::S, self::C::R>
     ;
-  method toString() → dynamic
+  method toString() → core::String
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
index 2fff34d..0dc1e9e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
@@ -17,7 +17,7 @@
   const constructor •() → self::B<self::B::T>
     : super self::A::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::B::T}";
 }
 static method main() → void {
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
index 2fff34d..0dc1e9e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
@@ -17,7 +17,7 @@
   const constructor •() → self::B<self::B::T>
     : super self::A::empty()
     ;
-  method toString() → dynamic
+  method toString() → core::String
     return "${self::B::T}";
 }
 static method main() → void {
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
index 4e65df8..0fcea3e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
@@ -14,7 +14,7 @@
 class B<T extends core::Object = dynamic> extends self::A {
   const constructor •() → self::B<self::B::T>
     ;
-  method toString() → dynamic
+  method toString() → core::String
     ;
 }
 static method main() → void
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
index d90c580..2f3e686 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set A(dynamic v) → dynamic {}
+  set A(dynamic v) → void {}
 }
 static method main() → dynamic {
   dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
index d90c580..2f3e686 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  set A(dynamic v) → dynamic {}
+  set A(dynamic v) → void {}
 }
 static method main() → dynamic {
   dynamic a = new self::A::•();
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
index b7a0c48..f48580b 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
@@ -12,7 +12,7 @@
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
-  set A(dynamic v) → dynamic
+  set A(dynamic v) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
index 5c7b6fa..3cbcc36 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
@@ -77,7 +77,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    A.foo
+    C.A.foo%B.foo
     C.noSuchMethod
     Object._identityHashCode
     Object.hashCode
@@ -114,7 +114,7 @@
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
-    D.foo
+    E.D.foo%E.foo
     E.noSuchMethod
     Object._identityHashCode
     Object.hashCode
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
index 46f8dc2..e4d64d6 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y});
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -20,10 +43,11 @@
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     core::print("No such method!");
     return 42;
   }
+  abstract forwarding-stub method foo(core::int x, {core::int y = null}) → dynamic;
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
@@ -37,7 +61,7 @@
     : super self::D::•()
     ;
   abstract method foo(core::int x, {core::int y = null}) → dynamic;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     core::print(i.namedArguments);
     return 42;
   }
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
index 46f8dc2..e4d64d6 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.legacy.transformed.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y});
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -20,10 +43,11 @@
   synthetic constructor •() → self::C
     : super self::A::•()
     ;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     core::print("No such method!");
     return 42;
   }
+  abstract forwarding-stub method foo(core::int x, {core::int y = null}) → dynamic;
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
@@ -37,7 +61,7 @@
     : super self::D::•()
     ;
   abstract method foo(core::int x, {core::int y = null}) → dynamic;
-  method noSuchMethod(dynamic i) → dynamic {
+  method noSuchMethod(core::Invocation i) → dynamic {
     core::print(i.namedArguments);
     return 42;
   }
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
index 9dc571a..7b9f48b 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Warning: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y});
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Warning: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -17,8 +40,9 @@
 class C extends self::A implements self::B {
   synthetic constructor •() → self::C
     ;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
+  abstract forwarding-stub method foo(core::int x, {core::int y}) → dynamic;
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
@@ -30,7 +54,7 @@
   synthetic constructor •() → self::E
     ;
   abstract method foo(core::int x, {core::int y}) → dynamic;
-  method noSuchMethod(dynamic i) → dynamic
+  method noSuchMethod(core::Invocation i) → dynamic
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
index 910fc65..73b1b6a 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
@@ -2,16 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
-//   foo(int x) => x;
-//   ^
-// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
-//   foo(int x, {int y}) => y;
-//   ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-//       ^
-//
 // pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
 //   foo(int x) => x;
 //   ^
@@ -22,6 +12,16 @@
 // class E extends D {
 //       ^
 //
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
index 910fc65..73b1b6a 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
@@ -2,16 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
-//   foo(int x) => x;
-//   ^
-// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
-//   foo(int x, {int y}) => y;
-//   ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-//       ^
-//
 // pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
 //   foo(int x) => x;
 //   ^
@@ -22,6 +12,16 @@
 // class E extends D {
 //       ^
 //
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+//   foo(int x) => x;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
index 24e8a2a..1b764c6 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
@@ -17,13 +17,13 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  static set C(dynamic v) → dynamic {}
+  static set C(dynamic v) → void {}
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
-  set D(dynamic v) → dynamic {}
+  set D(dynamic v) → void {}
 }
 static method main() → dynamic {
   dynamic c = new self::C::•();
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
index 24e8a2a..1b764c6 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
@@ -17,13 +17,13 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  static set C(dynamic v) → dynamic {}
+  static set C(dynamic v) → void {}
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
-  set D(dynamic v) → dynamic {}
+  set D(dynamic v) → void {}
 }
 static method main() → dynamic {
   dynamic c = new self::C::•();
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
index 4582fae..5cfdb48 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
@@ -16,13 +16,13 @@
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
-  static set C(dynamic v) → dynamic
+  static set C(dynamic v) → void
     ;
 }
 class D extends core::Object {
   synthetic constructor •() → self::D
     ;
-  set D(dynamic v) → dynamic
+  set D(dynamic v) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart b/pkg/front_end/testcases/regress/issue_37285.dart
new file mode 100644
index 0000000..6b5857d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, 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.
+
+class C {
+  C() : super()[];
+}
+
+main () {
+  new C();
+}
+
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+//   C() : super()[];
+//                 ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C() : super()[];
+//         ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   C() : super()[];
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+  C() : super()[];
+               ^"
+    ;
+}
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+//   C() : super()[];
+//                 ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C() : super()[];
+//         ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   C() : super()[];
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+  C() : super()[];
+               ^"
+    ;
+}
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect b/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect
new file mode 100644
index 0000000..2437d0c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+//   C() : super()[];
+//                 ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect b/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.strong.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+//   C() : super()[];
+//                 ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C() : super()[];
+//         ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   C() : super()[];
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+  C() : super()[];
+               ^"
+    ;
+}
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect
new file mode 100644
index 0000000..f7de288
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_37285.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:17: Error: Expected an identifier, but got ']'.
+//   C() : super()[];
+//                 ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:9: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   C() : super()[];
+//         ^
+//
+// pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   C() : super()[];
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •() → self::C
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_37285.dart:6:16: Error: Not a valid initializer.
+To initialize a field, use the syntax 'name = value'.
+  C() : super()[];
+               ^"
+    ;
+}
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
index 96700b1..2092b43 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.expect
@@ -13,15 +13,15 @@
   synthetic constructor •() → self::C<self::C::U>
     : super core::Object::•()
     ;
-  method f1(core::int x) → void {}
-  method f2(core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
 }
 class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
   synthetic constructor •() → self::D<self::D::U>
     : super self::C::•()
     ;
-  method f1(core::int x) → void {}
-  method f2(core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
 }
 static method g1(self::C<core::num> c) → void {
   c.f1(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
index 96700b1..2092b43 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.legacy.transformed.expect
@@ -13,15 +13,15 @@
   synthetic constructor •() → self::C<self::C::U>
     : super core::Object::•()
     ;
-  method f1(core::int x) → void {}
-  method f2(core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y = null]) → void {}
 }
 class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
   synthetic constructor •() → self::D<self::D::U>
     : super self::C::•()
     ;
-  method f1(core::int x) → void {}
-  method f2(core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y = null]) → void {}
 }
 static method g1(self::C<core::num> c) → void {
   c.f1(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
index fe2f698..9779f69 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.outline.expect
@@ -11,17 +11,17 @@
 class C<U extends core::Object = dynamic> extends core::Object implements self::I<core::int> {
   synthetic constructor •() → self::C<self::C::U>
     ;
-  method f1(core::int x) → void
+  method f1(generic-covariant-impl core::int x) → void
     ;
-  method f2(core::int x, [generic-covariant-impl self::C::U y]) → void
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::C::U y]) → void
     ;
 }
 class D<U extends core::Object = dynamic> extends self::C<self::D::U> {
   synthetic constructor •() → self::D<self::D::U>
     ;
-  method f1(core::int x) → void
+  method f1(generic-covariant-impl core::int x) → void
     ;
-  method f2(core::int x, [generic-covariant-impl self::D::U y]) → void
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl self::D::U y]) → void
     ;
 }
 static method g1(self::C<core::num> c) → void
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
index 6ad21c9..eee2991 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
@@ -91,7 +91,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    M.f
+    C.M.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
index 144807a..226d14a 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.expect
@@ -24,6 +24,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
index 20d3a2e..9af26fa 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.legacy.transformed.expect
@@ -24,7 +24,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
-  method f(core::int x) → void {}
+  method f(generic-covariant-impl core::int x) → void {}
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
index 10f6ea9..db72bce 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.outline.expect
@@ -23,6 +23,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
index c6a5468..66e9deb 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
index ca44867..dd05793 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.expect
@@ -18,6 +18,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
index ca44867..dd05793 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.legacy.transformed.expect
@@ -18,6 +18,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
index ee14e2c..bd1c5ab 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.outline.expect
@@ -16,6 +16,8 @@
 class C extends self::B implements self::I<core::int> {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
index 3b034c6..63ed69c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
@@ -90,7 +90,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
index 45abbbf..b31bd2e 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.expect
@@ -23,6 +23,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
index 0e61a92..1fb19f0 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.legacy.transformed.expect
@@ -23,6 +23,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void {
   c.f(1);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
index 926b281..97f802d 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.outline.expect
@@ -21,6 +21,8 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
 }
 static method g1(self::C c) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
index 31aa1f7..9faa7e3 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.expect
@@ -19,7 +19,7 @@
   synthetic constructor •() → self::E
     : super self::D::•()
     ;
-  method f(core::int x) → void {}
+  method f(covariant core::int x) → void {}
 }
 static method g1(self::C c) → void {
   c.f(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
index 31aa1f7..9faa7e3 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.legacy.transformed.expect
@@ -19,7 +19,7 @@
   synthetic constructor •() → self::E
     : super self::D::•()
     ;
-  method f(core::int x) → void {}
+  method f(covariant core::int x) → void {}
 }
 static method g1(self::C c) → void {
   c.f(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
index 3303a29..dd2a7ad 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
@@ -18,7 +18,7 @@
 class E extends self::D {
   synthetic constructor •() → self::E
     ;
-  method f(core::int x) → void
+  method f(covariant core::int x) → void
     ;
 }
 static method g1(self::C c) → void
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
index 306dd42..1f3710c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.expect
@@ -15,7 +15,7 @@
     ;
 }
 class E extends core::Object implements self::D {
-  field core::int x = null;
+  covariant field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
index 306dd42..1f3710c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
     ;
 }
 class E extends core::Object implements self::D {
-  field core::int x = null;
+  covariant field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
index 643c93c..063eafe 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.outline.expect
@@ -13,7 +13,7 @@
     ;
 }
 class E extends core::Object implements self::D {
-  field core::int x;
+  covariant field core::int x;
   synthetic constructor •() → self::E
     ;
 }
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
index 4e1a3ad..760a9dc 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.expect
@@ -20,6 +20,6 @@
     ;
   get x() → core::int
     return 0;
-  set x(core::int value) → void {}
+  set x(covariant core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
index 4e1a3ad..760a9dc 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.legacy.transformed.expect
@@ -20,6 +20,6 @@
     ;
   get x() → core::int
     return 0;
-  set x(core::int value) → void {}
+  set x(covariant core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
index 358009c..0bc780e 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.outline.expect
@@ -17,7 +17,7 @@
     ;
   get x() → core::int
     ;
-  set x(core::int value) → void
+  set x(covariant core::int value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
index d5f7a72..cc9e3d7 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::E
     : super self::D::•()
     ;
-  set x(core::int value) → void {}
+  set x(covariant core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
index d5f7a72..cc9e3d7 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.legacy.transformed.expect
@@ -18,6 +18,6 @@
   synthetic constructor •() → self::E
     : super self::D::•()
     ;
-  set x(core::int value) → void {}
+  set x(covariant core::int value) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
index 8f94f9e..840f751 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.outline.expect
@@ -17,7 +17,7 @@
 class E extends self::D {
   synthetic constructor •() → self::E
     ;
-  set x(core::int value) → void
+  set x(covariant core::int value) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
index 79a95bb..492c9a2 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.expect
@@ -15,7 +15,7 @@
   set x(covariant core::int value) → void {}
 }
 class E extends core::Object implements self::D {
-  field core::int x = null;
+  covariant field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
index 79a95bb..492c9a2 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.legacy.transformed.expect
@@ -15,7 +15,7 @@
   set x(covariant core::int value) → void {}
 }
 class E extends core::Object implements self::D {
-  field core::int x = null;
+  covariant field core::int x = null;
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
index 97331e8..809ec55 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.outline.expect
@@ -15,7 +15,7 @@
     ;
 }
 class E extends core::Object implements self::D {
-  field core::int x;
+  covariant field core::int x;
   synthetic constructor •() → self::E
     ;
 }
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
index 2efc919..a6d4f4c 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f1(covariant core::int x) → void {}
+  method f1(covariant generic-covariant-impl core::int x) → void {}
 }
 static method g1(dynamic d) → void {
   d.f1(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
index 2efc919..a6d4f4c 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.legacy.transformed.expect
@@ -13,7 +13,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method f1(covariant core::int x) → void {}
+  method f1(covariant generic-covariant-impl core::int x) → void {}
 }
 static method g1(dynamic d) → void {
   d.f1(1.5);
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
index 87b6f89..6d8aa4a 100644
--- a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.outline.expect
@@ -13,7 +13,7 @@
 class D extends self::C<core::num> {
   synthetic constructor •() → self::D
     ;
-  method f1(covariant core::int x) → void
+  method f1(covariant generic-covariant-impl core::int x) → void
     ;
 }
 static method g1(dynamic d) → void
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
index 1153bca..7869c3b 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
@@ -77,7 +77,7 @@
     C.x
   interfaceMembers:
     Object.toString
-    C.x
+    D.C.x%B.x
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -88,4 +88,4 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    C.x
+    D.C.x%B.x
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
index 084024b..4a50297 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
+  forwarding-stub set x(generic-covariant-impl core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
index 084024b..4a50297 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
+  forwarding-stub set x(generic-covariant-impl core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
index d696974..8bf7b77 100644
--- a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.outline.expect
@@ -15,6 +15,8 @@
 class D extends self::C implements self::B<core::num> {
   synthetic constructor •() → self::D
     ;
+  forwarding-stub set x(generic-covariant-impl core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
index 389c831..8993132 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
@@ -82,7 +82,7 @@
   classSetters:
     B._x
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     B._x
     Object.runtimeType
@@ -91,7 +91,7 @@
     Object.noSuchMethod
     Object._identityHashCode
     Object.hashCode
-    B.g
+    C.B.g%I.g
     B.check
     Object._simpleInstanceOfFalse
     Object._simpleInstanceOfTrue
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
index 82a32ab..339d3dc 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.expect
@@ -30,6 +30,10 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
+    return super.{self::B::f}(x);
+  forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
+    return super.{self::B::g}(x: x);
 }
 static method main() → dynamic {
   self::C c = new self::C::•();
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
index 82a32ab..339d3dc 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.legacy.transformed.expect
@@ -30,6 +30,10 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
+    return super.{self::B::f}(x);
+  forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
+    return super.{self::B::g}(x: x);
 }
 static method main() → dynamic {
   self::C c = new self::C::•();
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
index 5998e7f..d95ebff 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.outline.expect
@@ -22,6 +22,10 @@
 class C extends self::B implements self::I<core::num> {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f([generic-covariant-impl core::num x]) → void
+    return super.{self::B::f}(x);
+  forwarding-stub method g({generic-covariant-impl core::num x}) → void
+    return super.{self::B::g}(x: x);
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
index c6a5468..66e9deb 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
index 5486a15..760fd0e 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
index 5486a15..760fd0e 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
index a0b2b04..32a8732 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.outline.expect
@@ -16,6 +16,8 @@
 class C extends self::B implements self::I<core::int> {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
index 121a90b..add41b9 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.expect
@@ -10,8 +10,8 @@
   set x(generic-covariant-impl self::C::T t) → void {}
 }
 class D extends core::Object implements self::C<core::num> {
-  field core::num x = null;
-  field core::num y = null;
+  generic-covariant-impl field core::num x = null;
+  generic-covariant-impl field core::num y = null;
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
@@ -20,9 +20,9 @@
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
-  set x(core::num t) → void {}
+  set x(generic-covariant-impl core::num t) → void {}
   get y() → core::num
     return null;
-  set y(core::num t) → void {}
+  set y(generic-covariant-impl core::num t) → void {}
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
index 121a90b..add41b9 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.legacy.transformed.expect
@@ -10,8 +10,8 @@
   set x(generic-covariant-impl self::C::T t) → void {}
 }
 class D extends core::Object implements self::C<core::num> {
-  field core::num x = null;
-  field core::num y = null;
+  generic-covariant-impl field core::num x = null;
+  generic-covariant-impl field core::num y = null;
   synthetic constructor •() → self::D
     : super core::Object::•()
     ;
@@ -20,9 +20,9 @@
   synthetic constructor •() → self::E
     : super core::Object::•()
     ;
-  set x(core::num t) → void {}
+  set x(generic-covariant-impl core::num t) → void {}
   get y() → core::num
     return null;
-  set y(core::num t) → void {}
+  set y(generic-covariant-impl core::num t) → void {}
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
index bf98c8f..53b0ab7 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.outline.expect
@@ -10,19 +10,19 @@
     ;
 }
 class D extends core::Object implements self::C<core::num> {
-  field core::num x;
-  field core::num y;
+  generic-covariant-impl field core::num x;
+  generic-covariant-impl field core::num y;
   synthetic constructor •() → self::D
     ;
 }
 class E extends core::Object implements self::C<core::num> {
   synthetic constructor •() → self::E
     ;
-  set x(core::num t) → void
+  set x(generic-covariant-impl core::num t) → void
     ;
   get y() → core::num
     ;
-  set y(core::num t) → void
+  set y(generic-covariant-impl core::num t) → void
     ;
 }
 static method main() → void
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
index fc559f4..d50d07e 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.expect
@@ -9,17 +9,17 @@
   abstract set x(covariant core::Object value) → void;
 }
 class B extends core::Object implements self::A {
-  field core::Object x = null;
+  covariant field core::Object x = null;
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
   method f(covariant core::Object x) → void {}
 }
 class C<T extends core::Object = dynamic> extends core::Object implements self::B {
-  generic-covariant-impl field self::C::T x = null;
+  covariant generic-covariant-impl field self::C::T x = null;
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
     ;
-  method f(generic-covariant-impl self::C::T x) → void {}
+  method f(covariant generic-covariant-impl self::C::T x) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
index fc559f4..d50d07e 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.legacy.transformed.expect
@@ -9,17 +9,17 @@
   abstract set x(covariant core::Object value) → void;
 }
 class B extends core::Object implements self::A {
-  field core::Object x = null;
+  covariant field core::Object x = null;
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
   method f(covariant core::Object x) → void {}
 }
 class C<T extends core::Object = dynamic> extends core::Object implements self::B {
-  generic-covariant-impl field self::C::T x = null;
+  covariant generic-covariant-impl field self::C::T x = null;
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
     ;
-  method f(generic-covariant-impl self::C::T x) → void {}
+  method f(covariant generic-covariant-impl self::C::T x) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
index 4ed0cca..037ffa8 100644
--- a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.outline.expect
@@ -8,17 +8,17 @@
   abstract set x(covariant core::Object value) → void;
 }
 class B extends core::Object implements self::A {
-  field core::Object x;
+  covariant field core::Object x;
   synthetic constructor •() → self::B
     ;
   method f(covariant core::Object x) → void
     ;
 }
 class C<T extends core::Object = dynamic> extends core::Object implements self::B {
-  generic-covariant-impl field self::C::T x;
+  covariant generic-covariant-impl field self::C::T x;
   synthetic constructor •() → self::C<self::C::T>
     ;
-  method f(generic-covariant-impl self::C::T x) → void
+  method f(covariant generic-covariant-impl self::C::T x) → void
     ;
 }
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
index 4b4ea07..47824ee 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
@@ -14,7 +14,7 @@
 }
 
 class C extends B implements I<num> {
-  void /*@forwardingStub=semi-stub*/ f(num x);
+  void f(num x);
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
index c844506..0bd7033 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
@@ -60,7 +60,7 @@
       -> B
   interfaces: I<num>
   classMembers:
-    B.f
+    C.B.f%C.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%C.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
index 95fdf8b..5862850 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.expect
@@ -18,6 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
-  abstract method f(core::num x) → void;
+  forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+    return super.{self::B::f}(x);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
index 95fdf8b..5862850 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.legacy.transformed.expect
@@ -18,6 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
-  abstract method f(core::num x) → void;
+  forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+    return super.{self::B::f}(x);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
index 8b7ff11..c8141fe 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.outline.expect
@@ -16,7 +16,8 @@
 class C extends self::B implements self::I<core::num> {
   synthetic constructor •() → self::C
     ;
-  abstract method f(core::num x) → void;
+  forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+    return super.{self::B::f}(x);
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
index f9eaac1..2a7623e 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.expect
@@ -29,7 +29,7 @@
   synthetic constructor •() → self::E
     : super self::C::•()
     ;
-  method f(covariant core::int x) → void {}
+  method f(covariant generic-covariant-impl core::int x) → void {}
 }
 static method test() → dynamic {
   dynamic x = new self::D::•().g4() as (core::Object) → dynamic;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
index f9eaac1..2a7623e 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.legacy.transformed.expect
@@ -29,7 +29,7 @@
   synthetic constructor •() → self::E
     : super self::C::•()
     ;
-  method f(covariant core::int x) → void {}
+  method f(covariant generic-covariant-impl core::int x) → void {}
 }
 static method test() → dynamic {
   dynamic x = new self::D::•().g4() as (core::Object) → dynamic;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
index 0c9d1ca..1f6aacf 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
@@ -24,7 +24,7 @@
 class E extends self::C<core::num> {
   synthetic constructor •() → self::E
     ;
-  method f(covariant core::int x) → void
+  method f(covariant generic-covariant-impl core::int x) → void
     ;
 }
 static method test() → dynamic
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
index d6381e8..54bc8ea 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
@@ -77,7 +77,7 @@
     C.x
   interfaceMembers:
     Object.toString
-    C.x
+    D.C.x%B.x
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -88,4 +88,328 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    C.x
+    D.C.x%B.x
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
index 3f2338c..eea0f36 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
+  forwarding-stub set x(covariant core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
index 3f2338c..eea0f36 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
+  forwarding-stub set x(covariant core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
index 64163de..d8da134 100644
--- a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.outline.expect
@@ -15,6 +15,8 @@
 class D extends self::C implements self::B {
   synthetic constructor •() → self::D
     ;
+  forwarding-stub set x(covariant core::num _) → void
+    return super.{self::C::x} = _;
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
index a959413..f6be89d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.expect
@@ -10,19 +10,19 @@
     ;
 }
 abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
-  field dynamic x = null;
+  generic-covariant-impl field core::num x = null;
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → core::num;
+  abstract set y(generic-covariant-impl core::num value) → void;
 }
 abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
-  field dynamic x = null;
+  generic-covariant-impl field self::D::T x = null;
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → self::D::T;
+  abstract set y(generic-covariant-impl self::D::T value) → void;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
index a959413..f6be89d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.legacy.transformed.expect
@@ -10,19 +10,19 @@
     ;
 }
 abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
-  field dynamic x = null;
+  generic-covariant-impl field core::num x = null;
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → core::num;
+  abstract set y(generic-covariant-impl core::num value) → void;
 }
 abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
-  field dynamic x = null;
+  generic-covariant-impl field self::D::T x = null;
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → self::D::T;
+  abstract set y(generic-covariant-impl self::D::T value) → void;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
index 60525b9..2696bf4 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
@@ -9,18 +9,18 @@
     ;
 }
 abstract class C<T extends core::Object = dynamic> extends core::Object implements self::B<core::num> {
-  field dynamic x;
+  generic-covariant-impl field core::num x;
   synthetic constructor •() → self::C<self::C::T>
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → core::num;
+  abstract set y(generic-covariant-impl core::num value) → void;
 }
 abstract class D<T extends core::Object = dynamic> extends core::Object implements self::B<self::D::T> {
-  field dynamic x;
+  generic-covariant-impl field self::D::T x;
   synthetic constructor •() → self::D<self::D::T>
     ;
-  abstract get y() → dynamic;
-  abstract set y(dynamic value) → dynamic;
+  abstract get y() → self::D::T;
+  abstract set y(generic-covariant-impl self::D::T value) → void;
 }
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
index 94c8b5c..9a9e066 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
@@ -87,9 +87,9 @@
       -> B
   interfaces: M, I<int>
   classMembers:
-    M.y
+    C.M.y%B.y%I.y
     Object.toString
-    M.x
+    C.M.x%B.x%I.x
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -100,12 +100,12 @@
     Object._simpleInstanceOfTrue
     Object.==
   classSetters:
-    M.y
-    M.x
+    C.M.y%B.y=%I.y=
+    C.M.x%B.x=%I.x=
   interfaceMembers:
-    M.y
+    C.M.y%B.y%I.y
     Object.toString
-    M.x
+    C.M.x%B.x%I.x
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -116,5 +116,329 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    M.y
-    M.x
+    C.M.y%B.y=%I.y=
+    C.M.x%B.x=%I.x=
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
index 4978034..b99aea3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
@@ -32,6 +32,10 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub set y(covariant core::Object value) → void
+    return super.{self::B::y} = value;
+  forwarding-stub set x(generic-covariant-impl core::int _) → void
+    return super.{self::B::x} = _;
 }
 static method expectTypeError(() → void callback) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
index 94c8b5c..e23589d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
@@ -103,9 +103,9 @@
     M.y
     M.x
   interfaceMembers:
-    M.y
+    C.M.y%I.y
     Object.toString
-    M.x
+    C.M.x%I.x
     Object.runtimeType
     Object._simpleInstanceOf
     Object._instanceOf
@@ -116,5 +116,329 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
-    M.y
-    M.x
+    C.M.y=%I.y=
+    C.M.x=%I.x=
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
index 4b6371a..782ccf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
@@ -38,6 +38,10 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub set y(covariant core::Object value) → void
+    return super.{self::B::y} = value;
+  forwarding-stub set x(generic-covariant-impl core::int value) → void
+    return super.{self::B::x} = value;
 }
 static method expectTypeError(() → void callback) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -85,3 +85,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
index 4e4266a..91a76ee 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.outline.expect
@@ -16,6 +16,8 @@
 class C extends self::B implements self::I {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f(covariant core::Object x) → core::int
+    return super.{self::B::f}(x);
 }
 static method expectTypeError(() → void callback) → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
index c6a5468..f7b0451 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -85,3 +85,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
index 3334045..082a15f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
index 3334045..082a15f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
index 205776d..5890db1 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.outline.expect
@@ -16,6 +16,8 @@
 abstract class C extends self::B implements self::I<core::int> {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
index 2defd9d..578a89f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -85,3 +85,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
index 3038f0e..04bbcf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.expect
@@ -18,5 +18,6 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
index 3038f0e..04bbcf3 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.legacy.transformed.expect
@@ -18,5 +18,6 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
index 9e7de41..5c37f4b 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.outline.expect
@@ -16,6 +16,7 @@
 abstract class C extends self::B<core::int> implements self::I {
   synthetic constructor •() → self::C
     ;
+  abstract forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void;
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -85,3 +85,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
index 22a66005..ed5aa28 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(covariant core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
index 22a66005..ed5aa28 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.legacy.transformed.expect
@@ -18,5 +18,7 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  forwarding-stub method f(covariant core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
index 91a90a9..ac22acd 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.outline.expect
@@ -16,6 +16,8 @@
 abstract class C extends self::B implements self::I {
   synthetic constructor •() → self::C
     ;
+  forwarding-stub method f(covariant core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
index 5459bc4..dbd4f79 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
@@ -73,7 +73,7 @@
     Object.==
   classSetters:
   interfaceMembers:
-    B.f
+    C.B.f%I.f
     Object.toString
     Object.runtimeType
     Object._simpleInstanceOf
@@ -85,3 +85,327 @@
     Object._simpleInstanceOfTrue
     Object.==
   interfaceSetters:
+
+Comparable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Comparable.compareTo
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Comparable.compare
+  classSetters:
+
+num:
+  Longest path to Object: 2
+  superclasses:
+    Object
+  interfaces: Comparable<num>
+  classMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  classSetters:
+  interfaceMembers:
+    num.~/
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    num._returnDoubleNull
+    num.Object.toString%num.toString
+    num._returnIntNull
+    num.+
+    num.clamp
+    num.toDouble
+    num.ceil
+    num.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    num.toStringAsExponential
+    num./
+    num.abs
+    num._moduloFromInteger
+    num._subFromInteger
+    num._addFromInteger
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    num.sign
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    num.floorToDouble
+    Object._identityHashCode
+    num.>
+    num.roundToDouble
+    num.round
+    num.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    num.truncate
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    num.ceilToDouble
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    num.truncateToDouble
+    num.parse
+    num.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    num.*
+  interfaceSetters:
+
+int:
+  Longest path to Object: 3
+  superclasses:
+    Object
+      -> num
+  interfaces: Comparable<num>
+  classMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  classSetters:
+  interfaceMembers:
+    int._minInt64
+    num.~/
+    int.toSigned
+    int._shrFromInteger
+    int._throwFormatException
+    int._parseBlock
+    num.<=
+    num._equalToInteger
+    num.isInfinite
+    num.<
+    int._int64OverflowLimits
+    int._parseRadix
+    int.Object.toString%int.toString
+    int._PARSE_LIMITS
+    int._kNull
+    num.+
+    num.clamp
+    num.toDouble
+    int.ceil
+    int.unary-
+    num._mulFromInteger
+    num.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    num.isNegative
+    num.isNaN
+    int._initInt64OverflowLimits
+    int.isEven
+    num.toStringAsExponential
+    num./
+    int.abs
+    int._bitAndFromSmi
+    int.|
+    num._moduloFromInteger
+    int.gcd
+    int._int64UnsignedOverflowLimits
+    int.<<
+    num._subFromInteger
+    num._addFromInteger
+    int.toUnsigned
+    int.toRadixString
+    int._int64UnsignedSmiOverflowLimits
+    Object._instanceOf
+    num.remainder
+    num.isFinite
+    num.toInt
+    num.%
+    int._tryParseSmi
+    int.sign
+    int.>>
+    Object.noSuchMethod
+    num.toStringAsPrecision
+    int.modInverse
+    int.floorToDouble
+    Object._identityHashCode
+    num.>
+    int.roundToDouble
+    int.round
+    int._maxInt64
+    int.floor
+    num.compareTo
+    num.Object.hashCode%num.hashCode
+    num._truncDivFromInteger
+    int.truncate
+    int.^
+    int._shlFromInteger
+    int.&
+    num.-
+    Object._simpleInstanceOfFalse
+    num._greaterThanFromInteger
+    int.bitLength
+    int.ceilToDouble
+    int.modPow
+    int.isOdd
+    int._bitAndFromInteger
+    Object._simpleInstanceOfTrue
+    num.Object.==%num.==
+    int._bitOrFromInteger
+    int.truncateToDouble
+    int._bitXorFromInteger
+    int.parse
+    int.tryParse
+    num.toStringAsFixed
+    num._remainderFromInteger
+    int._parse
+    num.*
+    int.~
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
index cf870cc..1ce982c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.expect
@@ -18,5 +18,6 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
index cf870cc..1ce982c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.legacy.transformed.expect
@@ -18,5 +18,6 @@
   synthetic constructor •() → self::C
     : super self::B::•()
     ;
+  abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
 }
 static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
index d4b0825..9c7aa8f 100644
--- a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.outline.expect
@@ -16,6 +16,7 @@
 abstract class C extends self::B implements self::I {
   synthetic constructor •() → self::C
     ;
+  abstract forwarding-stub method f(covariant core::int x, core::Object y) → void;
 }
 static method main() → void
   ;
diff --git a/pkg/front_end/testcases/static_setter.dart.legacy.expect b/pkg/front_end/testcases/static_setter.dart.legacy.expect
index 05125e5..055ed11 100644
--- a/pkg/front_end/testcases/static_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/static_setter.dart.legacy.expect
@@ -7,7 +7,7 @@
     : super core::Object::•()
     ;
 }
-static set foo(dynamic x) → dynamic {}
+static set foo(dynamic x) → void {}
 static method main() → dynamic {
   self::foo = new self::Foo::•();
 }
diff --git a/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
index 05125e5..055ed11 100644
--- a/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/static_setter.dart.legacy.transformed.expect
@@ -7,7 +7,7 @@
     : super core::Object::•()
     ;
 }
-static set foo(dynamic x) → dynamic {}
+static set foo(dynamic x) → void {}
 static method main() → dynamic {
   self::foo = new self::Foo::•();
 }
diff --git a/pkg/front_end/testcases/static_setter.dart.outline.expect b/pkg/front_end/testcases/static_setter.dart.outline.expect
index 13eaefe..0c46d4c 100644
--- a/pkg/front_end/testcases/static_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/static_setter.dart.outline.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::Foo
     ;
 }
-static set foo(dynamic x) → dynamic
+static set foo(dynamic x) → void
   ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 79ac736..45003af 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -10,6 +10,7 @@
 accessors: RuntimeError
 ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
 argument_mismatch: InstrumentationMismatch # Test assumes Dart 1.0 semantics
+await_in_non_async: RuntimeError # Expected.
 bug21938: TypeCheckError
 bug30695: TypeCheckError
 bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
@@ -22,13 +23,15 @@
 duplicated_field_initializer: RuntimeError
 dynamic_and_void: InstrumentationMismatch # Test assumes Dart 1.0 semantics
 expressions: RuntimeError
+extension_methods: TypeCheckError
 external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
 fallthrough: ExpectationFileMismatch
+ignore_function: TypeCheckError
 incomplete_field_formal_parameter: RuntimeError
 inference/abstract_class_instantiation: InstrumentationMismatch # Issue #30040
 inference/conflicting_fields: TypeCheckError
-inference/conflicts_can_happen: TypeCheckError
 inference/conflicts_can_happen2: TypeCheckError
+inference/conflicts_can_happen: TypeCheckError
 inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
 inference/constructors_too_many_positional_arguments: InstrumentationMismatch # Issue #30040
 inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
@@ -44,8 +47,10 @@
 inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
 inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
 inference/generic_methods_infer_js_builtin: InstrumentationMismatch # Issue #30029
+inference/inconsistent_overrides: TypeCheckError
 inference/infer_field_override_multiple: TypeCheckError
 inference/infer_from_complex_expressions_if_outer_most_value_is_precise: TypeCheckError # Issue #35630
+inference/infer_method_missing_params: ExpectationFileMismatch # Not supposed to be able to infer types if supertypes disagree on number of parameters. An error may be missing as C.f and B.f are not compatible at all.
 inference/infer_method_missing_params: TypeCheckError
 inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
 inference/infer_types_on_generic_instantiations_4: RuntimeError
@@ -66,16 +71,18 @@
 inference_new/infer_assign_to_index_upwards: TypeCheckError
 inference_new/infer_assign_to_property_custom: TypeCheckError
 inference_new/infer_field_getter_setter_mismatch: TypeCheckError
+inference_new/infer_field_override_accessors: TypeCheckError
 inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
 inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
-inference_new/strongly_connected_component: TypeCheckError
 instantiate_to_bound/non_simple_class_parametrized_typedef_cycle: RuntimeError # Expected
 instantiate_to_bound/non_simple_generic_function_in_bound_regress: RuntimeError # Expected
 invalid_type: TypeCheckError
 invocations: RuntimeError
 issue34899: TypeCheckError
 micro: RuntimeError
+mixin_application_override: ExpectationFileMismatch # Too many errors.
 mixin_application_override: TypeCheckError
+nnbd/nullable_param: RuntimeError
 operator_method_not_found: RuntimeError # Expected
 optional: TypeCheckError
 override_check_accessor_after_inference: TypeCheckError # Issue #31620
@@ -146,6 +153,7 @@
 regress/issue_36647: RuntimeError # Expected
 regress/issue_36647_2: RuntimeError # Expected
 regress/issue_36669: RuntimeError
+regress/issue_37285: RuntimeError
 reject_generic_function_types_in_bounds: RuntimeError # Expected
 runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
diff --git a/pkg/front_end/testcases/super_nsm.dart.legacy.expect b/pkg/front_end/testcases/super_nsm.dart.legacy.expect
index a0c7a8c..eb7ebeb 100644
--- a/pkg/front_end/testcases/super_nsm.dart.legacy.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.legacy.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return "C";
   no-such-method-forwarder method interfaceMethod() → dynamic
     return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -21,7 +21,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return "D";
   method dMethod() → dynamic
     return super.{self::C::interfaceMethod}();
diff --git a/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect b/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
index a0c7a8c..eb7ebeb 100644
--- a/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.legacy.transformed.expect
@@ -12,7 +12,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return "C";
   no-such-method-forwarder method interfaceMethod() → dynamic
     return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -21,7 +21,7 @@
   synthetic constructor •() → self::D
     : super self::C::•()
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     return "D";
   method dMethod() → dynamic
     return super.{self::C::interfaceMethod}();
diff --git a/pkg/front_end/testcases/super_nsm.dart.outline.expect b/pkg/front_end/testcases/super_nsm.dart.outline.expect
index de7c531..6ec8595 100644
--- a/pkg/front_end/testcases/super_nsm.dart.outline.expect
+++ b/pkg/front_end/testcases/super_nsm.dart.outline.expect
@@ -10,7 +10,7 @@
 class C extends core::Object implements self::I {
   synthetic constructor •() → self::C
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     ;
   no-such-method-forwarder method interfaceMethod() → dynamic
     return this.{self::C::noSuchMethod}(new core::_InvocationMirror::_withType(#interfaceMethod, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) as{TypeError} dynamic;
@@ -18,7 +18,7 @@
 class D extends self::C {
   synthetic constructor •() → self::D
     ;
-  method noSuchMethod(dynamic _) → dynamic
+  method noSuchMethod(core::Invocation _) → dynamic
     ;
   method dMethod() → dynamic
     ;
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 8508fee..74c01f5 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,6 +8,7 @@
 
 DeltaBlue: TextSerializationFailure # Was: Pass
 abstract_members: TypeCheckError
+abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
 accessors: TextSerializationFailure # Was: RuntimeError
 ambiguous_exports: TextSerializationFailure # Was: RuntimeError # Expected, this file exports two main methods.
 annotation_eof: TextSerializationFailure # Was: Pass
@@ -23,6 +24,7 @@
 async_function: TextSerializationFailure # Was: Pass
 async_nested: TextSerializationFailure # Was: Pass
 await: TextSerializationFailure # Was: Pass
+await_in_non_async: TextSerializationFailure
 bad_setter_abstract: TextSerializationFailure # Was: Pass
 bad_store: TextSerializationFailure # Was: Pass
 bad_type_variable_uses_in_supertypes: TextSerializationFailure
@@ -71,6 +73,7 @@
 control_flow_collection: TextSerializationFailure
 control_flow_collection_inference: TextSerializationFailure
 covariant_generic: TextSerializationFailure # Was: RuntimeError
+covariant_parameter_in_superclass_of_mixin_application: TextSerializationFailure
 cycles: TextSerializationFailure # Was: Pass
 default_values: TextSerializationFailure # Was: Pass
 deferred_lib: TextSerializationFailure # Was: Pass
@@ -90,12 +93,14 @@
 expression/eval: TextSerializationFailure # Was: Pass
 expression/main: TextSerializationFailure # Was: Pass
 expressions: TextSerializationFailure # Was: RuntimeError
+extension_methods: TypeCheckError
 external: TextSerializationFailure # Was: Pass
 external_import: TextSerializationFailure # Was: RuntimeError # The native extension to import doesn't exist. This is ok.
 fallthrough: ExpectationFileMismatch
 fibonacci: TextSerializationFailure # Was: Pass
 for_in_scope: TextSerializationFailure # Was: Pass
 for_in_without_declaration: TextSerializationFailure
+forwarding_stub_for_operator: TextSerializationFailure
 function_in_field: TextSerializationFailure # Was: Pass
 function_type_assignments: TextSerializationFailure # Was: Pass
 function_type_default_value: TextSerializationFailure
@@ -103,9 +108,10 @@
 function_type_recovery: TextSerializationFailure # Was: Pass
 functions: TextSerializationFailure # Was: Pass
 future_or_test: TextSerializationFailure # Was: Pass
-hello: TextSerializationFailure # Was: Pass
 having_part_with_part_and_annotation: TextSerializationFailure
 having_part_with_parts_and_annotation: TextSerializationFailure
+hello: TextSerializationFailure # Was: Pass
+ignore_function: TypeCheckError
 illegal_named_function_expression: TextSerializationFailure # Was: Pass
 illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
 implicit_const_with_static_fields: TextSerializationFailure # Was: Pass
@@ -162,6 +168,7 @@
 inference/complex_predecrement: TextSerializationFailure # Was: Pass
 inference/conditional_lub: TextSerializationFailure # Was: Pass
 inference/conditional_upwards_inference: TextSerializationFailure # Was: Pass
+inference/conflicting_fields: ExpectationFileMismatch
 inference/conflicting_fields: TypeCheckError
 inference/conflicts_can_happen2: TypeCheckError
 inference/conflicts_can_happen: TypeCheckError
@@ -277,6 +284,7 @@
 inference/generic_methods_nested_generic_instantiation: TextSerializationFailure # Was: Pass
 inference/generic_methods_uses_greatest_lower_bound: TextSerializationFailure # Was: Pass
 inference/greatest_closure_multiple_params: TextSerializationFailure # Was: Pass
+inference/inconsistent_overrides: TypeCheckError
 inference/index_assign_operator_return_type: TextSerializationFailure # Was: Pass
 inference/index_assign_operator_return_type_2: TextSerializationFailure # Was: Pass
 inference/infer_accessor_from_later_inferred_field: TextSerializationFailure # Was: Pass
@@ -340,6 +348,7 @@
 inference/infer_local_function_referenced_before_declaration: TextSerializationFailure # Was: Pass
 inference/infer_local_function_return_type: TextSerializationFailure # Was: Pass
 inference/infer_method_function_typed: TextSerializationFailure # Was: Pass
+inference/infer_method_missing_params: ExpectationFileMismatch
 inference/infer_method_missing_params: TypeCheckError
 inference/infer_parameter_type_setter_from_field: TextSerializationFailure # Was: Pass
 inference/infer_parameter_type_setter_from_setter: TextSerializationFailure # Was: Pass
@@ -467,6 +476,8 @@
 inference/null_literal_should_not_infer_as_bottom: TextSerializationFailure # Was: Pass
 inference/overloaded_int_operators: TextSerializationFailure # Was: Pass
 inference/override_equals: TextSerializationFailure # Was: RuntimeError
+inference/override_inference_depends_on_field_inference: TextSerializationFailure
+inference/override_inference_with_type_parameters: TextSerializationFailure
 inference/parameter_defaults_downwards: TextSerializationFailure # Was: Pass
 inference/parameter_defaults_upwards: TextSerializationFailure # Was: Pass
 inference/promote_bounds: TextSerializationFailure # Was: Pass
@@ -586,6 +597,7 @@
 inference_new/infer_assign_to_static: TextSerializationFailure # Was: Pass
 inference_new/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
 inference_new/infer_field_getter_setter_mismatch: TypeCheckError
+inference_new/infer_field_override_accessors: TypeCheckError
 inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
 inference_new/infer_field_override_setter_overrides_getter: TextSerializationFailure # Was: Pass
 inference_new/infer_instance_accessor_ref: TextSerializationFailure # Was: Pass
@@ -605,6 +617,7 @@
 inference_new/super_index_get: TextSerializationFailure # Was: Pass
 inference_new/super_index_get_substitution: TextSerializationFailure # Was: Pass
 inference_new/switch: TextSerializationFailure # Was: Pass
+inference_new/top_level_field_depends_on_multiple_inheritance: ExpectationFileMismatch
 inference_new/top_level_field_depends_on_multiple_inheritance: TextSerializationFailure # Was: Pass
 inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure # Was: Pass
 inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure # Was: Pass
@@ -680,10 +693,12 @@
 invalid_cast: TextSerializationFailure # Was: Pass
 invalid_type: TypeCheckError
 invocations: TextSerializationFailure # Was: RuntimeError
+issue129167943: TextSerializationFailure
 issue34515: TextSerializationFailure
 issue34899: TypeCheckError
 issue35875: TextSerializationFailure
 issue37027: TextSerializationFailure
+issue37381: TextSerializationFailure
 literals: TextSerializationFailure # Was: Pass
 local_generic_function: TextSerializationFailure # Was: Pass
 magic_const: TextSerializationFailure # Was: Pass
@@ -695,6 +710,7 @@
 minimum_int: TextSerializationFailure # Was: Pass
 missing_constructor: TextSerializationFailure # Was: Pass
 mixin: TextSerializationFailure # Was: Pass
+mixin_application_override: ExpectationFileMismatch
 mixin_application_override: TypeCheckError
 mixin_conflicts: TextSerializationFailure
 mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
@@ -706,6 +722,7 @@
 native_as_name: TextSerializationFailure # Was: Pass
 nested_implicit_const_with_env_var: TextSerializationFailure # Was: Pass
 new_const_insertion/simple: TextSerializationFailure # Was: Pass
+nnbd/nullable_param: TextSerializationFailure
 no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
 no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
 no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
@@ -742,6 +759,8 @@
 override_check_generic_method_f_bounded: TextSerializationFailure # Was: Pass
 override_check_two_substitutions: TextSerializationFailure # Was: Pass
 override_check_with_covariant_modifier: TypeCheckError # Issue #31620
+override_inference_for_setters: TextSerializationFailure
+override_inference_named_parameters_ordering: TextSerializationFailure
 part_as_entry_point: TextSerializationFailure # Was: Pass
 part_as_entry_point_lib: TextSerializationFailure # Was: Pass
 part_not_part_of: TextSerializationFailure
@@ -932,6 +951,7 @@
 regress/issue_36647_2: TextSerializationFailure
 regress/issue_36669: TextSerializationFailure
 regress/issue_36793: TextSerializationFailure
+regress/issue_37285: TextSerializationFailure
 reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
 return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
 runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
@@ -964,6 +984,7 @@
 runtime_checks/dynamic_invocation: TextSerializationFailure # Was: Pass
 runtime_checks/dynamic_invocation_generic: TextSerializationFailure # Was: Pass
 runtime_checks/dynamic_invocation_of_getter: TextSerializationFailure # Was: Pass
+runtime_checks/field_forwarding_stub_generic_covariant: ExpectationFileMismatch
 runtime_checks/field_forwarding_stub_generic_covariant: TextSerializationFailure # Was: Pass
 runtime_checks/forwarding_stub_with_default_values: TextSerializationFailure # Was: Pass
 runtime_checks/forwarding_stub_with_non_covariant_param: TextSerializationFailure # Was: Pass
@@ -977,6 +998,7 @@
 runtime_checks/implicit_downcast_if: TextSerializationFailure # Was: Pass
 runtime_checks/implicit_downcast_not: TextSerializationFailure # Was: Pass
 runtime_checks/implicit_downcast_while: TextSerializationFailure # Was: Pass
+runtime_checks_new/abstract_override_becomes_forwarding_stub: ExpectationFileMismatch
 runtime_checks_new/abstract_override_becomes_forwarding_stub: TextSerializationFailure # Was: Pass
 runtime_checks_new/call_through_this: TextSerializationFailure # Was: Pass
 runtime_checks_new/contravariant_combiner: TextSerializationFailure # Was: Pass
@@ -986,12 +1008,15 @@
 runtime_checks_new/contravariant_index_get: TextSerializationFailure # Was: Pass
 runtime_checks_new/derived_class_typed: TextSerializationFailure # Was: Pass
 runtime_checks_new/field_forwarding_stub_abstract_generic_covariant: TextSerializationFailure # Was: Pass
+runtime_checks_new/field_forwarding_stub_explicit_covariant: ExpectationFileMismatch
 runtime_checks_new/field_forwarding_stub_explicit_covariant: TextSerializationFailure # Was: Pass
 runtime_checks_new/for_in_call_kinds: TextSerializationFailure # Was: Pass
 runtime_checks_new/generic_covariance_based_on_inference: TextSerializationFailure # Was: Pass
 runtime_checks_new/implicit_downcast_field: TextSerializationFailure # Was: Pass
+runtime_checks_new/mixin_forwarding_stub_field: ExpectationFileMismatch
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
+runtime_checks_new/mixin_forwarding_stub_setter: ExpectationFileMismatch
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
 runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
 runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
diff --git a/pkg/front_end/testcases/void_methods.dart.outline.expect b/pkg/front_end/testcases/void_methods.dart.outline.expect
index b73833b..881f4a6 100644
--- a/pkg/front_end/testcases/void_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/void_methods.dart.outline.expect
@@ -6,9 +6,9 @@
   field core::List<dynamic> list;
   synthetic constructor •() → self::Foo
     ;
-  set first(dynamic x) → dynamic
+  set first(dynamic x) → void
     ;
-  operator []=(dynamic x, dynamic y) → dynamic
+  operator []=(dynamic x, dynamic y) → void
     ;
   method clear() → void
     ;
diff --git a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
index 355836a..82918cf 100644
--- a/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
+++ b/pkg/front_end/tool/_fasta/generate_experimental_flags.dart
@@ -51,33 +51,53 @@
 enum ExperimentalFlag {
 ''');
   for (var key in keys) {
+    var expired = (yaml[key] as YamlMap)['expired'];
+    if (expired == true) continue;
     sb.writeln('  ${keyToIdentifier(key)},');
   }
-  sb.writeln('}');
-
   sb.write('''
 
+  // A placeholder representing an "expired" flag which has been removed
+  // from the codebase but still needs to be gracefully ignored
+  // when specified on the command line.
+  expiredFlag,
+}
+
 ExperimentalFlag parseExperimentalFlag(String flag) {
   switch (flag) {
 ''');
+  var expiredKeys = <String>[];
   for (var key in keys) {
+    var expired = (yaml[key] as YamlMap)['expired'];
+    if (expired == true) {
+      expiredKeys.add(key);
+      continue;
+    }
     sb.writeln('    case "$key":');
     sb.writeln('     return ExperimentalFlag.${keyToIdentifier(key)};');
   }
+  if (expiredKeys.isNotEmpty) {
+    sb.write('''
+
+    // Expired flags
+''');
+    for (var key in expiredKeys) {
+      sb.writeln('    case "$key":');
+      sb.writeln('     return ExperimentalFlag.expiredFlag;');
+    }
+  }
   sb.write('''  }
   return null;
 }
-''');
-
-  sb.write('''
 
 const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
 ''');
   for (var key in keys) {
+    var expired = (yaml[key] as YamlMap)['expired'];
+    if (expired == true) continue;
     bool shipped = (yaml[key] as YamlMap)['enabledIn'] != null;
     sb.writeln('  ExperimentalFlag.${keyToIdentifier(key)}: ${shipped},');
     if (shipped) {
-      var expired = (yaml[key] as YamlMap)['expired'];
       if (expired == false) {
         throw 'Cannot mark shipped feature as "expired: false"';
       }
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index f95564c..31aee1b 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -31,7 +31,7 @@
 }
 
 collectLog(DateTime time, HttpRequest request) async {
-  String json = await request.transform(utf8.decoder).join();
+  String json = await request.cast<List<int>>().transform(utf8.decoder).join();
   var data;
   try {
     data = jsonDecode(json);
diff --git a/pkg/front_end/tool/fasta.dart b/pkg/front_end/tool/fasta.dart
new file mode 100644
index 0000000..77f1115
--- /dev/null
+++ b/pkg/front_end/tool/fasta.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2019, 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 'dart:io';
+
+final String repoDir = _computeRepoDir();
+
+final String toolDir = '$repoDir/pkg/front_end/tool/_fasta';
+
+final String kernelBin = '$repoDir/pkg/kernel/bin';
+
+String get dartVm =>
+    Platform.isWindows ? '$repoDir/sdk/bin/dart.bat' : '$repoDir/sdk/bin/dart';
+
+main(List<String> args) async {
+  List<String> extraVmArguments = [];
+  String script;
+  List<String> scriptArguments = [];
+
+  int index = 0;
+  for (; index < args.length; index++) {
+    String arg = args[index];
+    if (arg.startsWith('-')) {
+      extraVmArguments.add(arg);
+    } else {
+      break;
+    }
+  }
+  if (args.length == index) {
+    stop("No command provided.");
+  }
+  String command = args[index++];
+  List<String> remainingArguments = args.skip(index).toList();
+
+  switch (command) {
+    case 'abcompile':
+      script = '${toolDir}/abcompile.dart';
+      break;
+    case 'compile':
+      script = '${toolDir}/compile.dart';
+      break;
+    case 'compile-platform':
+      script = '${toolDir}/compile_platform.dart';
+      break;
+    case 'log':
+      script = '${toolDir}/log_analyzer.dart';
+      break;
+    case 'logd':
+      script = '${toolDir}/log_collector.dart';
+      break;
+    case 'outline':
+      script = '${toolDir}/outline.dart';
+      break;
+    case 'parser':
+      script = '${toolDir}/parser.dart';
+      break;
+    case 'scanner':
+      script = '${toolDir}/scanner.dart';
+      break;
+    case 'dump-partial':
+      script = '${toolDir}/dump_partial.dart';
+      break;
+    case 'dump-ir':
+      script = '${kernelBin}/dump.dart';
+      if (remainingArguments.isEmpty || remainingArguments.length > 2) {
+        stop("Usage: $command dillfile [output]");
+      }
+      break;
+    case 'testing':
+      script = '${repoDir}/pkg/testing/bin/testing.dart';
+      scriptArguments.add('--config=${repoDir}/pkg/front_end/testing.json');
+      break;
+    case 'generate-messages':
+      script = '${toolDir}/generate_messages.dart';
+      break;
+    case 'generate-experimental-flags':
+      script = '${toolDir}/generate_experimental_flags.dart';
+      break;
+    default:
+      stop("'$command' isn't a valid subcommand.");
+  }
+
+  List<String> arguments = [];
+  arguments.addAll(extraVmArguments);
+  arguments.add('--enable-asserts');
+  arguments.add(script);
+  arguments.addAll(remainingArguments);
+  arguments.addAll(scriptArguments);
+
+  print('Running: ${dartVm} ${arguments.join(' ')}');
+  Process process = await Process.start(dartVm, arguments,
+      mode: ProcessStartMode.inheritStdio);
+  exitCode = await process.exitCode;
+}
+
+String _computeRepoDir() {
+  ProcessResult result = Process.runSync(
+      'git', ['rev-parse', '--show-toplevel'],
+      runInShell: true,
+      workingDirectory: new File.fromUri(Platform.script).parent.path);
+  return (result.stdout as String).trim();
+}
+
+void stop(String message) {
+  stderr.write(message);
+  exit(2);
+}
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 0ba6da6..9bb4e6e 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -8,6 +8,7 @@
 import 'dart:async';
 import 'dart:io';
 
+import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/fasta/ast_builder.dart';
 import 'package:args/args.dart';
 
@@ -213,7 +214,8 @@
 // Note: AstBuilder doesn't build compilation-units or classes, only method
 // bodies. So this listener is not feature complete.
 class _PartialAstBuilder extends AstBuilder {
-  _PartialAstBuilder(Uri uri) : super(null, null, true, uri);
+  _PartialAstBuilder(Uri uri)
+      : super(null, null, true, FeatureSet.fromEnableFlags([]), uri);
 
   // Note: this method converts the body to kernel, so we skip that here.
   @override
diff --git a/pkg/front_end/tool/incremental_perf_test.dart b/pkg/front_end/tool/incremental_perf_test.dart
index 5a97ad8..73e0893 100644
--- a/pkg/front_end/tool/incremental_perf_test.dart
+++ b/pkg/front_end/tool/incremental_perf_test.dart
@@ -12,7 +12,7 @@
 main() async {
   var sdkOutline = computePlatformBinariesLocation(forceBuildDir: true).resolve(
       // TODO(sigmund): switch to `vm_outline.dill` (issue #29881).
-      "vm_platform.dill");
+      "vm_platform_strong.dill");
 
   final ikgBenchmarks = Platform.script.resolve('../benchmarks/ikg/');
   final helloEntry = ikgBenchmarks.resolve('hello.dart');
@@ -28,7 +28,6 @@
     '--no-loop',
     '--sdk-summary',
     '$sdkOutline',
-    '--mode=legacy',
     '$helloEntry',
     '$helloEdits'
   ]);
@@ -54,7 +53,6 @@
     '--no-loop',
     '--sdk-summary',
     '$sdkOutline',
-    '--mode=legacy',
     '--implementation=default',
     '$dart2jsEntry',
     '$dart2jsEdits'
@@ -63,7 +61,6 @@
     '--no-loop',
     '--sdk-summary',
     '$sdkOutline',
-    '--mode=legacy',
     '--implementation=minimal',
     '$dart2jsEntry',
     '$dart2jsEdits'
diff --git a/pkg/js/CHANGELOG.md b/pkg/js/CHANGELOG.md
index a839eb6..800418a 100644
--- a/pkg/js/CHANGELOG.md
+++ b/pkg/js/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.2
+
+* Improved documentation.
+
 ## 0.6.1+1
 
 * Support Dart 2 final release.
diff --git a/pkg/js/README.md b/pkg/js/README.md
index e95e03e..1aec699 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -1,18 +1,5 @@
 Methods and annotations to specify interoperability with JavaScript APIs.
 
-*This packages requires Dart SDK 1.13.0.*
-
-*This is beta software. Please files [issues].*
-
-### Adding the dependency
-
-Add the following to your `pubspec.yaml`:
-
-```yaml
-dependencies:
-  js: ^0.6.0
-```
-
 ### Example
 
 See the [Chart.js Dart API](https://github.com/google/chartjs.dart/) for an
@@ -20,12 +7,20 @@
 
 ### Usage
 
+All Dart code interacting with JavaScript should use the utilities provided with
+`package:js`. Developers should avoid importing `dart:js` directly.
+
 #### Calling methods
 
 ```dart
+@JS()
+library stringify;
+
+import 'package:js/js.dart';
+
 // Calls invoke JavaScript `JSON.stringify(obj)`.
-@JS("JSON.stringify")
-external String stringify(obj);
+@JS('JSON.stringify')
+external String stringify(Object obj);
 ```
 
 #### Classes and Namespaces
@@ -34,24 +29,24 @@
 @JS('google.maps')
 library maps;
 
-import "package:js/js.dart";
+import 'package:js/js.dart';
 
 // Invokes the JavaScript getter `google.maps.map`.
 external Map get map;
 
-// `new Map` invokes JavaScript `new google.maps.Map(location)`
+// The `Map` constructor invokes JavaScript `new google.maps.Map(location)`
 @JS()
 class Map {
   external Map(Location location);
   external Location getLocation();
 }
 
-// `new Location(...)` invokes JavaScript `new google.maps.LatLng(...)`
+// The `Location` constructor invokes JavaScript `new google.maps.LatLng(...)`
 //
 // We recommend against using custom JavaScript names whenever
 // possible. It is easier for users if the JavaScript names and Dart names
 // are consistent.
-@JS("LatLng")
+@JS('LatLng')
 class Location {
   external Location(num lat, num lng);
 }
@@ -65,17 +60,19 @@
 printOptions({responsive: true});
 ```
 
-If you want to use `printOptions` from Dart, you cannot simply pass a Dart `Map`
-object – they are "opaque" in JavaScript.
+If you want to use `printOptions` from Dart a `Map<String, dynamic>` would be
+"opaque" in JavaScript.
 
-
-Instead, create a Dart class with both the `@JS()` and
-`@anonymous` annotations.
+Instead, create a Dart class with both the `@JS()` and `@anonymous` annotations.
 
 ```dart
-// Dart
+@JS()
+library print_options;
+
+import 'package:js/js.dart';
+
 void main() {
-  printOptions(new Options(responsive: true));
+  printOptions(Options(responsive: true));
 }
 
 @JS()
@@ -86,26 +83,131 @@
 class Options {
   external bool get responsive;
 
+  // Must have an unnamed factory constructor with named arguments.
   external factory Options({bool responsive});
 }
 ```
 
-NB: This _anonymous_ class must have an unnamed _factory constructor_.
+#### Passing functions to JavaScript
 
-#### Passing functions to JavaScript.
+If you are passing a Dart function to a JavaScript API as an argument , you must
+wrap it using `allowInterop` or `allowInteropCaptureThis`. **Warning** There is
+a behavior difference between the Dart2JS and DDC compilers. When compiled with
+DDC there will be no errors despite missing `allowInterop` calls, because DDC
+uses JS calling semantics by default. When compiling with Dart2JS the
+`allowInterop` utility must be used.
 
-If you are passing a Dart function to a JavaScript API, you must wrap it using
-`allowInterop` or `allowInteropCaptureThis`.
+#### Making a Dart function callable from JavaScript
 
-## Contributing and Filing Bugs
+To provide a Dart function callable from JavaScript by name use a setter
+annotated with `@JS()`.
 
-Please file bugs and features requests on the [Github issue tracker][issues].
+```dart
+@JS()
+library callable_function;
 
-We also love and accept community contributions, from API suggestions to pull requests.
-Please file an issue before beginning work so we can discuss the design and implementation.
-We are trying to create issues for all current and future work, so if something there intrigues you (or you need it!) join in on the discussion.
+import 'package:js/js.dart';
 
-Code contributors must sign the
-[Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1).
+/// Allows assigning a function to be callable from `window.functionName()`
+@JS('functionName')
+external set _functionName(void Function() f);
+
+/// Allows calling the assigned function from Dart as well.
+@JS()
+external void functionName();
+
+void _someDartFunction() {
+  print('Hello from Dart!');
+}
+
+void main() {
+  _functionName = allowInterop(_someDartFunction);
+  // JavaScript code may now call `functionName()` or `window.functionName()`.
+}
+```
+
+## Known limitations and bugs
+
+### Differences betwenn Dart2JS and DDC
+
+Dart's production and development JavaScript compilers use different calling
+conventions and type representation, and therefore have different challenges in
+JavaScript interop. There are currently some know differences in behavior and
+bugs in one or both compilers.
+
+#### allowInterop is required in Dart2JS, optional in DDC
+
+DDC uses the same calling conventions as JavaScript and so Dart functions passed
+as callbacks can be invoked without modification. In Dart2JS the calling
+conventions are different and so `allowInterop` or `allowInteropCaptureThis`
+must be used for any callback.
+
+**Workaround:**: Always use `allowInterop` even when not required in DDC.
+
+#### Callbacks allow extra ignored arguments in DDC
+
+In JavaScript a caller may pass any number of "extra" arguments to a function
+and they will be ignored. DDC follows this behavior, Dart2JS will have a runtime
+error if a function is invoked with more arguments than expected.
+
+**Workaround:** Write functions that take the same number of arguments as will
+be passed from JavaScript. If the number is variable use optional positional
+arguments.
+
+#### DDC and Dart2JS have different representation for Maps
+
+Passing a `Map<String, String>` as an argument to a JavaScript function will
+have different behavior depending on the compiler. Calling something like
+`JSON.stringify()` will give different results.
+
+**Workaround:** Only pass object literals instead of Maps as arguments. For json
+specifically use `jsonEncode` in Dart rather than a JS alternative.
+
+#### Missing validation for anonymous factory constructors in DDC
+
+When using an `@anonymous` class to create JavaScript object literals Dart2JS
+will enforce that only named arguments are used, while DDC will allow positional
+arguments but may generate incorrect code.
+
+**Workaround:** Try builds in both development and release mode to get the full
+scope of static validation.
+
+### Sharp Edges
+
+Dart and JavaScript have different semantics and common patterns which makes it
+easy to make some mistakes, and difficult for the tools to provide safety. These
+sharp edges are known pitfalls.
+
+#### Lack of runtime type checking
+
+The return types of methods annotated with `@JS()` are not validated at runtime,
+so an incorrect type may "leak" into other Dart code and violate type system
+guarantees.
+
+**Workaround:** For any calls into JavaScript code that are not known to be safe
+in their return values, validate the results manually with `is` checks.
+
+#### List instances coming from JavaScript will always be `List<dynamic>`
+
+A JavaScript array does not have a reified element type, so an array returned
+from a JavaScript function cannot make guarantees about it's elements without
+inspecting each one. At runtime a check like `result is List` may succeed, while
+`result is List<String>` will always fail.
+
+**Workaround:** Use a `.cast<String>().toList()` call to get a `List` with the
+expected reified type at runtime.
+
+#### The `JsObject` type from `dart:js` can't be used with `@JS()` annotation
+
+`JsObject` and related code in `dart:js` uses a different approach and may not
+be passed as an argument to a method annotated with `@JS()`.
+
+**Workaround:** Avoid importing `dart:js` and only use the `package:js` provided
+approach. To handle object literals use `@anonymous` on an `@JS()` annotated
+class.
+
+## Reporting issues
+
+Please file bugs and features requests on the [SDK issue tracker][issues].
 
 [issues]: https://goo.gl/j3rzs0
diff --git a/pkg/js/lib/js.dart b/pkg/js/lib/js.dart
index 17b1ded..2880c21 100644
--- a/pkg/js/lib/js.dart
+++ b/pkg/js/lib/js.dart
@@ -2,14 +2,16 @@
 // 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.
 
-/// Allows interoperability with Javascript APIs.
+/// Annotations to mark interfaces to JavaScript.
 library js;
 
 export 'dart:js' show allowInterop, allowInteropCaptureThis;
 
-/// A metadata annotation that indicates that a Library, Class, or member is
-/// implemented directly in JavaScript. All external members of a class or
-/// library with this annotation implicitly have it as well.
+/// An annotation that indicates a library, class, or member is implemented
+/// directly in JavaScript.
+///
+/// All external members of a class or library with this annotation implicitly
+/// have it as well.
 ///
 /// Specifying [name] customizes the JavaScript name to use. By default the
 /// dart name is used. It is not valid to specify a custom [name] for class
@@ -23,10 +25,11 @@
   const _Anonymous();
 }
 
-/// A metadata annotation that indicates that a @JS annotated class is
-/// structural and does not have a known JavaScript prototype.
+/// An annotation that indicates a [JS] annotated class is structural and does
+/// not have a known JavaScript prototype.
 ///
-/// Factory constructors for anonymous JavaScript classes desugar to creating
-/// JavaScript object literals with name-value pairs corresponding to the
-/// parameter names and values.
+/// A class marked with [anonymous] must have an unnamed factory constructor
+/// with no positional arguments, only named arguments. Invoking the constructor
+/// desugars to creating a JavaScript object literal with name-value pairs
+/// corresponding to the parameter names and values.
 const _Anonymous anonymous = const _Anonymous();
diff --git a/pkg/js/lib/js_util.dart b/pkg/js/lib/js_util.dart
index 1e47e5d..860f40f 100644
--- a/pkg/js/lib/js_util.dart
+++ b/pkg/js/lib/js_util.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/// Allows interoperability with Javascript APIs.
+/// Utilities for interoperating with JavaScript.
 library js_util;
 
 export 'dart:js_util';
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index e6411b4..a7a4e0a 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,8 +1,8 @@
 name: js
-version: 0.6.1+1
+version: 0.6.2
 author: Dart Team <misc@dartlang.org>
 description: Access JavaScript from Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
 
 environment:
-  sdk: '>=1.19.0-dev.0.0 <3.0.0'
+  sdk: '>=2.0.0 <3.0.0'
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 399ab56..400dc42 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -763,7 +763,10 @@
       // Output 'a += 1' as '++a' and 'a -= 1' as '--a'.
       _outputIncDec(op, assignment.leftHandSide);
       return;
-    } else if (leftHandSide is VariableUse && rightHandSide is Binary) {
+    }
+    if (!assignment.isCompound &&
+        leftHandSide is VariableUse &&
+        rightHandSide is Binary) {
       Node rLeft = undefer(rightHandSide.left);
       Node rRight = undefer(rightHandSide.right);
       String op = rightHandSide.op;
diff --git a/pkg/js_ast/test/deferred_expression_test.dart b/pkg/js_ast/test/deferred_expression_test.dart
index 397aaaa..c91a151 100644
--- a/pkg/js_ast/test/deferred_expression_test.dart
+++ b/pkg/js_ast/test/deferred_expression_test.dart
@@ -29,6 +29,25 @@
   test(map, '# = # - 1', [deferred, variableUseAlias], '--variable');
   test(map, '# = # + 2', [variableUse, variableUseAlias], 'variable += 2');
   test(map, '# = # + 2', [deferred, variableUseAlias], 'variable += 2');
+  test(map, '# = # * 2', [variableUse, variableUseAlias], 'variable *= 2');
+  test(map, '# = # * 2', [deferred, variableUseAlias], 'variable *= 2');
+
+  test(map, '# += # + 1', [variableUse, variableUseAlias],
+      'variable += variable + 1');
+  test(map, '# += # + 1', [deferred, variableUseAlias],
+      'variable += variable + 1');
+  test(map, '# += # - 1', [variableUse, variableUseAlias],
+      'variable += variable - 1');
+  test(map, '# += # - 1', [deferred, variableUseAlias],
+      'variable += variable - 1');
+  test(map, '# += # + 2', [variableUse, variableUseAlias],
+      'variable += variable + 2');
+  test(map, '# += # + 2', [deferred, variableUseAlias],
+      'variable += variable + 2');
+  test(map, '# += # * 2', [variableUse, variableUseAlias],
+      'variable += variable * 2');
+  test(map, '# += # * 2', [deferred, variableUseAlias],
+      'variable += variable * 2');
 }
 
 void test(Map<Expression, DeferredExpression> map, String template,
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 0ff11cf..45fa1d8 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -4799,6 +4799,41 @@
 //                             TYPES
 // ------------------------------------------------------------------------
 
+/// Represents nullability of a type.
+enum Nullability {
+  /// Types in opt-out libraries are 'legacy' types.
+  ///
+  /// They are both subtypes and supertypes of the nullable and non-nullable
+  /// versions of the type.
+  legacy,
+
+  /// Nullable types are marked with the '?' modifier.
+  ///
+  /// Null, dynamic, and void are nullable by default.
+  nullable,
+
+  /// Non-nullable types are types that aren't marked with the '?' modifier.
+  ///
+  /// Note that Null, dynamic, and void that are nullable by default.  Note also
+  /// that some types denoted by a type parameter without the '?' modifier can
+  /// be something else rather than non-nullable.
+  nonNullable,
+
+  /// Non-legacy types that are neither nullable, nor non-nullable.
+  ///
+  /// An example of such type is type T in the example below.  Note that both
+  /// int and int? can be passed in for T, so an attempt to assign null to x is
+  /// a compile-time error as well as assigning x to y.
+  ///
+  ///   class A<T extends Object?> {
+  ///     foo(T x) {
+  ///       x = null;      // Compile-time error.
+  ///       Object y = x;  // Compile-time error.
+  ///     }
+  ///   }
+  neither
+}
+
 /// A syntax-independent notion of a type.
 ///
 /// [DartType]s are not AST nodes and may be shared between different parents.
@@ -4818,6 +4853,8 @@
 
   bool operator ==(Object other);
 
+  Nullability get nullability;
+
   /// If this is a typedef type, repeatedly unfolds its type definition until
   /// the root term is not a typedef type, otherwise returns the type itself.
   ///
@@ -4843,6 +4880,8 @@
   visitChildren(Visitor v) {}
 
   bool operator ==(Object other) => other is InvalidType;
+
+  Nullability get nullability => throw "InvalidType doesn't have nullabiliity";
 }
 
 class DynamicType extends DartType {
@@ -4855,6 +4894,8 @@
   visitChildren(Visitor v) {}
 
   bool operator ==(Object other) => other is DynamicType;
+
+  Nullability get nullability => Nullability.nullable;
 }
 
 class VoidType extends DartType {
@@ -4867,6 +4908,8 @@
   visitChildren(Visitor v) {}
 
   bool operator ==(Object other) => other is VoidType;
+
+  Nullability get nullability => Nullability.nullable;
 }
 
 class BottomType extends DartType {
@@ -4879,21 +4922,29 @@
   visitChildren(Visitor v) {}
 
   bool operator ==(Object other) => other is BottomType;
+
+  Nullability get nullability => Nullability.nonNullable;
 }
 
 @coq
 class InterfaceType extends DartType {
   Reference className;
+
+  final Nullability nullability;
+
   @nocoq
   final List<DartType> typeArguments;
 
   /// The [typeArguments] list must not be modified after this call. If the
   /// list is omitted, 'dynamic' type arguments are filled in.
-  InterfaceType(Class classNode, [List<DartType> typeArguments])
+  InterfaceType(Class classNode,
+      [List<DartType> typeArguments,
+      Nullability nullability = Nullability.legacy])
       : this.byReference(getClassReference(classNode),
-            typeArguments ?? _defaultTypeArguments(classNode));
+            typeArguments ?? _defaultTypeArguments(classNode), nullability);
 
-  InterfaceType.byReference(this.className, this.typeArguments);
+  InterfaceType.byReference(this.className, this.typeArguments,
+      [this.nullability = Nullability.legacy]);
 
   Class get classNode => className.asClass;
 
@@ -4946,6 +4997,7 @@
   @coqsingle
   final List<DartType> positionalParameters;
   final List<NamedType> namedParameters; // Must be sorted.
+  final Nullability nullability;
 
   /// The [Typedef] this function type is created for.
   final TypedefType typedefType;
@@ -4956,6 +5008,7 @@
   FunctionType(List<DartType> positionalParameters, this.returnType,
       {this.namedParameters: const <NamedType>[],
       this.typeParameters: const <TypeParameter>[],
+      this.nullability: Nullability.legacy,
       int requiredParameterCount,
       this.typedefType})
       : this.positionalParameters = positionalParameters,
@@ -5073,14 +5126,18 @@
 ///
 /// The underlying type can be extracted using [unalias].
 class TypedefType extends DartType {
+  final Nullability nullability;
   final Reference typedefReference;
   final List<DartType> typeArguments;
 
-  TypedefType(Typedef typedefNode, [List<DartType> typeArguments])
-      : this.byReference(
-            typedefNode.reference, typeArguments ?? const <DartType>[]);
+  TypedefType(Typedef typedefNode,
+      [List<DartType> typeArguments,
+      Nullability nullability = Nullability.legacy])
+      : this.byReference(typedefNode.reference,
+            typeArguments ?? const <DartType>[], nullability);
 
-  TypedefType.byReference(this.typedefReference, this.typeArguments);
+  TypedefType.byReference(this.typedefReference, this.typeArguments,
+      [this.nullability = Nullability.legacy]);
 
   Typedef get typedefNode => typedefReference.asTypedef;
 
@@ -5163,6 +5220,8 @@
 /// is the same as the [TypeParameter]'s bound.  This allows one to detect
 /// whether the bound has been promoted.
 class TypeParameterType extends DartType {
+  final Nullability nullability;
+
   TypeParameter parameter;
 
   /// An optional promoted bound on the type parameter.
@@ -5171,7 +5230,10 @@
   /// is therefore the same as the bound of [parameter].
   DartType promotedBound;
 
-  TypeParameterType(this.parameter, [this.promotedBound]);
+  TypeParameterType(this.parameter,
+      [this.promotedBound, Nullability nullability])
+      : this.nullability =
+            getNullability(parameter, promotedBound, nullability);
 
   accept(DartTypeVisitor v) => v.visitTypeParameterType(this);
   accept1(DartTypeVisitor1 v, arg) => v.visitTypeParameterType(this, arg);
@@ -5186,6 +5248,115 @@
 
   /// Returns the bound of the type parameter, accounting for promotions.
   DartType get bound => promotedBound ?? parameter.bound;
+
+  /// Get nullability of [TypeParameterType] from arguments to its constructor.
+  ///
+  /// This method is supposed to be used only in the constructor of
+  /// [TypeParameterType] to compute the value of
+  /// [TypeParameterType.nullability] from the arguments passed to the constructor.
+  static Nullability getNullability(TypeParameter parameter,
+      DartType promotedBound, Nullability nullability) {
+    // If promotedBound is null, getNullability returns the nullability of
+    // either T or T? where T is parameter and the presence of '?' is determined
+    // by nullability.
+
+    // If promotedBound isn't null, getNullability returns the nullability of an
+    // instesection of the left-hand side (referred to as LHS below) and the
+    // right-hand side (referred to as RHS below).  LHS is parameter followed by
+    // nullability, and RHS is promotedBound.  That is, getNullability returns
+    // the nullability of either T & P or T? & P where T is parameter, P is
+    // promotedBound, and the presence of '?' is determined by nullability.
+    // Note that RHS is always a subtype of the bound of the type parameter.
+
+    Nullability lhsNullability;
+
+    // If the nullability is explicitly nullable, that is, if the type parameter
+    // type is followed by '?' in the code, the nullability of the type is
+    // 'nullable.'
+    if (nullability == Nullability.nullable) {
+      lhsNullability = Nullability.nullable;
+    } else {
+      // If the bound is nullable, both nullable and non-nullable types can be
+      // passed in for the type parameter, making the corresponding type
+      // parameter types 'neither.'  Otherwise, the nullability matches that of
+      // the bound.
+      DartType bound = parameter.bound ?? const DynamicType();
+      Nullability boundNullability =
+          bound is InvalidType ? Nullability.neither : bound.nullability;
+      lhsNullability = boundNullability == Nullability.nullable
+          ? Nullability.neither
+          : boundNullability;
+    }
+    if (promotedBound == null) {
+      return lhsNullability;
+    }
+
+    // In practice a type parameter of legacy type can only be used in type
+    // annotations within the corresponding class declaration.  If it's legacy,
+    // then the entire library containing the class is opt-out, and any RHS is
+    // deemed to be legacy too.  So, it's necessary to only check LHS for being
+    // legacy.
+    if (lhsNullability == Nullability.legacy) {
+      return Nullability.legacy;
+    }
+
+    // Intersection is non-nullable if and only if RHS is non-nullable.
+    //
+    // The proof is as follows.  Intersection is non-nullable if at least one of
+    // LHS or RHS is non-nullable.  The case of non-nullable RHS is trivial.  In
+    // the case of non-nullable LHS, its bound should be non-nullable.  RHS is
+    // known to always be a subtype of the bound of LHS; therefore, RHS is
+    // non-nullable.
+    //
+    // Note that it also follows from the above that non-nullable RHS implies
+    // non-nullable LHS, so the check below covers the case lhsNullability ==
+    // Nullability.nonNullable.
+    if (promotedBound.nullability == Nullability.nonNullable) {
+      return Nullability.nonNullable;
+    }
+
+    // If the nullability of LHS is 'neither,' the nullability of the
+    // intersection is also 'neither' if RHS is 'neither' or nullable.
+    //
+    // Consider the following example:
+    //
+    //     class A<X extends Object?, Y extends X> {
+    //       foo(X x) {
+    //         if (x is Y) {
+    //           x = null;     // Compile-time error.  Consider X = Y = int.
+    //           Object a = x; // Compile-time error.  Consider X = Y = int?.
+    //         }
+    //         if (x is int?) {
+    //           x = null;     // Compile-time error.  Consider X = int.
+    //           Object b = x; // Compile-time error.  Consider X = int?.
+    //         }
+    //       }
+    //     }
+    //
+    // Note that RHS can't be 'legacy' or non-nullable at this point due to the
+    // checks above.
+    if (lhsNullability == Nullability.neither) {
+      return Nullability.neither;
+    }
+
+    // At this point the only possibility for LHS is to be nullable, and for RHS
+    // is to be either nullable or legacy.  Both combinations for LHS and RHS
+    // should yield the nullability of RHS as the nullability for the
+    // intersection.  Consider the following code for clarification:
+    //
+    //   class A<X extends Object?, Y extends X> {
+    //     foo(X? x) {
+    //       if (x is Y) {
+    //         x = null;     // Compile-time error.  Consider X = Y = int.
+    //         Object a = x; // Compile-time error.  Consider X = Y = int?.
+    //       }
+    //       if (x is int?) {
+    //         x = null;     // Ok.  Both X? and int? are nullable.
+    //       }
+    //     }
+    //   }
+    return promotedBound.nullability;
+  }
 }
 
 /// Declaration of a type variable.
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 474f907..ed156b1 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -247,14 +247,14 @@
   /// Compares members by name, using the same sort order as
   /// [getDeclaredMembers] and [getInterfaceMembers].
   static int compareMembers(Member first, Member second) {
-    return _compareNames(first.name, second.name);
+    return compareNames(first.name, second.name);
   }
 
   /// Compares names, using the same sort order as [getDeclaredMembers] and
   /// [getInterfaceMembers].
   ///
   /// This is an arbitrary as-fast-as-possible sorting criterion.
-  static int _compareNames(Name firstName, Name secondName) {
+  static int compareNames(Name firstName, Name secondName) {
     int firstHash = firstName.hashCode;
     int secondHash = secondName.hashCode;
     if (firstHash != secondHash) return firstHash - secondHash;
@@ -291,7 +291,7 @@
     while (low <= high) {
       int mid = low + ((high - low) >> 1);
       Member pivot = members[mid];
-      int comparison = _compareNames(name, pivot.name);
+      int comparison = compareNames(name, pivot.name);
       if (comparison < 0) {
         high = mid - 1;
       } else if (comparison > 0) {
diff --git a/pkg/kernel/lib/external_name.dart b/pkg/kernel/lib/external_name.dart
index 2646fc4..6577041 100644
--- a/pkg/kernel/lib/external_name.dart
+++ b/pkg/kernel/lib/external_name.dart
@@ -20,16 +20,36 @@
     return null;
   }
   for (final Expression annotation in procedure.annotations) {
-    if (annotation is ConstructorInvocation) {
-      if (_isExternalName(annotation.target.enclosingClass)) {
-        return (annotation.arguments.positional.single as StringLiteral).value;
-      }
-    } else if (annotation is ConstantExpression) {
-      final constant = annotation.constant;
-      if (constant is InstanceConstant) {
-        if (_isExternalName(constant.classNode)) {
-          return (constant.fieldValues.values.single as StringConstant).value;
-        }
+    final value = _getExternalNameValue(annotation);
+    if (value != null) {
+      return value;
+    }
+  }
+  return null;
+}
+
+/// Returns native extension URIs for given [library].
+List<String> getNativeExtensionUris(Library library) {
+  final uris = <String>[];
+  for (var annotation in library.annotations) {
+    final value = _getExternalNameValue(annotation);
+    if (value != null) {
+      uris.add(value);
+    }
+  }
+  return uris;
+}
+
+String _getExternalNameValue(Expression annotation) {
+  if (annotation is ConstructorInvocation) {
+    if (_isExternalName(annotation.target.enclosingClass)) {
+      return (annotation.arguments.positional.single as StringLiteral).value;
+    }
+  } else if (annotation is ConstantExpression) {
+    final constant = annotation.constant;
+    if (constant is InstanceConstant) {
+      if (_isExternalName(constant.classNode)) {
+        return (constant.fieldValues.values.single as StringConstant).value;
       }
     }
   }
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index b599cdf..8cb5c3f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -15,6 +15,7 @@
 class ContinuationVariables {
   static const awaitJumpVar = ':await_jump_var';
   static const awaitContextVar = ':await_ctx_var';
+  static const asyncStackTraceVar = ':async_stack_trace';
   static const exceptionParam = ':exception';
   static const stackTraceParam = ':stack_trace';
 
@@ -270,7 +271,7 @@
   final VariableDeclaration nestedClosureVariable =
       new VariableDeclaration(":async_op");
   final VariableDeclaration stackTraceVariable =
-      new VariableDeclaration(":async_stack_trace");
+      new VariableDeclaration(ContinuationVariables.asyncStackTraceVar);
   final VariableDeclaration thenContinuationVariable =
       new VariableDeclaration(":async_op_then");
   final VariableDeclaration catchErrorContinuationVariable =
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index eeb40cc..0365260 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
 name: kernel
 # Currently, kernel API is not stable and users should
 # not depend on semver semantics when depending on this package.
-version: 0.3.18
+version: 0.3.20
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
diff --git a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
new file mode 100644
index 0000000..368bfbd
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2019, 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:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+
+/// Responsible for building and maintaining information about nullability
+/// decorations related to the class hierarchy.
+///
+/// For instance, if one class is a subclass of the other, we record the
+/// nullabilities of all the types involved in the subclass relationship.
+class DecoratedClassHierarchy {
+  final VariableRepository _variables;
+
+  final NullabilityGraph _graph;
+
+  /// Cache for speeding up the computation of
+  /// [_getGenericSupertypeDecorations].
+  final Map<ClassElement, Map<ClassElement, DecoratedType>>
+      _genericSupertypeDecorations = {};
+
+  DecoratedClassHierarchy(this._variables, this._graph);
+
+  /// Retrieves a [DecoratedType] describing how [class_] implements
+  /// [superclass].
+  ///
+  /// If [class_] does not implement [superclass], raises an exception.
+  ///
+  /// Note that the returned [DecoratedType] will have a node of `never`,
+  /// because the relationship between a class and its superclass is not
+  /// nullable.
+  DecoratedType getDecoratedSupertype(
+      ClassElement class_, ClassElement superclass) {
+    assert(class_ is! ClassElementHandle);
+    assert(superclass is! ClassElementHandle);
+    if (superclass.typeParameters.isEmpty) {
+      return DecoratedType(superclass.type, _graph.never);
+    }
+    return _getGenericSupertypeDecorations(class_)[superclass] ??
+        (throw StateError('Unrelated types'));
+  }
+
+  /// Computes a map whose keys are all the superclasses of [class_], and whose
+  /// values indicate how [class_] implements each superclass.
+  Map<ClassElement, DecoratedType> _getGenericSupertypeDecorations(
+      ClassElement class_) {
+    var decorations = _genericSupertypeDecorations[class_];
+    if (decorations == null) {
+      // Call ourselves recursively to compute how each of [class_]'s direct
+      // superclasses relates to all of its transitive superclasses.
+      decorations = _genericSupertypeDecorations[class_] = {};
+      var decoratedDirectSupertypes =
+          _variables.decoratedDirectSupertypes(class_);
+      for (var entry in decoratedDirectSupertypes.entries) {
+        var superclass = entry.key;
+        var decoratedSupertype = entry.value;
+        var supertype = decoratedSupertype.type as InterfaceType;
+        // Compute a type substitution to determine how [class_] relates to
+        // this specific [superclass].
+        Map<TypeParameterElement, DecoratedType> substitution = {};
+        for (int i = 0; i < supertype.typeArguments.length; i++) {
+          substitution[supertype.typeParameters[i]] =
+              decoratedSupertype.typeArguments[i];
+        }
+        // Apply that substitution to the relation between [superclass] and
+        // each of its transitive superclasses, to determine the relation
+        // between [class_] and the transitive superclass.
+        var recursiveSupertypeDecorations =
+            _getGenericSupertypeDecorations(superclass);
+        for (var entry in recursiveSupertypeDecorations.entries) {
+          decorations[entry.key] ??= entry.value.substitute(substitution);
+        }
+        // Also record the relation between [class_] and its direct
+        // superclass.
+        decorations[superclass] ??= decoratedSupertype;
+      }
+    }
+    return decorations;
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
index 5205490..3387fbf 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -40,7 +40,47 @@
       this.positionalParameters = const [],
       this.namedParameters = const {},
       this.typeArguments = const []}) {
-    assert(node != null);
+    assert(() {
+      assert(node != null);
+      var type = this.type;
+      if (type is InterfaceType) {
+        assert(returnType == null);
+        assert(positionalParameters.isEmpty);
+        assert(namedParameters.isEmpty);
+        assert(typeArguments.length == type.typeArguments.length);
+        for (int i = 0; i < typeArguments.length; i++) {
+          assert(typeArguments[i].type == type.typeArguments[i]);
+        }
+      } else if (type is FunctionType) {
+        assert(returnType.type == type.returnType);
+        int positionalParameterCount = 0;
+        int namedParameterCount = 0;
+        for (var parameter in type.parameters) {
+          if (parameter.isNamed) {
+            assert(namedParameters[parameter.name].type == parameter.type);
+            namedParameterCount++;
+          } else {
+            assert(positionalParameters[positionalParameterCount].type ==
+                parameter.type);
+            positionalParameterCount++;
+          }
+        }
+        assert(positionalParameters.length == positionalParameterCount);
+        assert(namedParameters.length == namedParameterCount);
+        assert(typeArguments.isEmpty);
+      } else if (node is TypeParameterType) {
+        assert(returnType == null);
+        assert(positionalParameters.isEmpty);
+        assert(namedParameters.isEmpty);
+        assert(typeArguments.isEmpty);
+      } else {
+        assert(returnType == null);
+        assert(positionalParameters.isEmpty);
+        assert(namedParameters.isEmpty);
+        assert(typeArguments.isEmpty);
+      }
+      return true;
+    }());
   }
 
   /// Creates a [DecoratedType] corresponding to the given [element], which is
@@ -72,14 +112,32 @@
           throw UnimplementedError('Decorating ${type.displayName}');
         }
         return DecoratedType(type, graph.never);
+      } else if (type is TypeParameterType) {
+        return DecoratedType(type, graph.never);
       } else {
         throw type.runtimeType; // TODO(paulberry)
       }
     }
 
+    // Sanity check:
+    // Ensure the element is not from a library that is being migrated.
+    // If this assertion fires, it probably means that the NodeBuilder failed to
+    // generate the appropriate decorated type for the element when it was
+    // visiting the source file.
+    if (graph.isBeingMigrated(element.source)) {
+      throw 'Internal Error: DecorateType.forElement should not be called'
+          ' for elements being migrated: ${element.runtimeType} :: $element';
+    }
+
     DecoratedType decoratedType;
     if (element is ExecutableElement) {
       decoratedType = decorate(element.type);
+    } else if (element is TopLevelVariableElement) {
+      decoratedType = decorate(element.type);
+    } else if (element is TypeParameterElement) {
+      // By convention, type parameter elements are decorated with the type of
+      // their bounds.
+      decoratedType = decorate(element.bound ?? DynamicTypeImpl.instance);
     } else {
       // TODO(paulberry)
       throw UnimplementedError('Decorating ${element.runtimeType}');
@@ -87,14 +145,117 @@
     return decoratedType;
   }
 
+  /// Creates a decorated type corresponding to [type], with fresh nullability
+  /// nodes everywhere that don't correspond to any source location.  These
+  /// nodes can later be unioned with other nodes.
+  factory DecoratedType.forImplicitFunction(
+      FunctionType type, NullabilityNode node, NullabilityGraph graph,
+      {DecoratedType returnType}) {
+    if (type.typeFormals.isNotEmpty) {
+      throw new UnimplementedError('Decorating a generic function type');
+    }
+    var positionalParameters = <DecoratedType>[];
+    var namedParameters = <String, DecoratedType>{};
+    for (var parameter in type.parameters) {
+      if (parameter.isPositional) {
+        positionalParameters
+            .add(DecoratedType.forImplicitType(parameter.type, graph));
+      } else {
+        namedParameters[parameter.name] =
+            DecoratedType.forImplicitType(parameter.type, graph);
+      }
+    }
+    return DecoratedType(type, node,
+        returnType:
+            returnType ?? DecoratedType.forImplicitType(type.returnType, graph),
+        namedParameters: namedParameters,
+        positionalParameters: positionalParameters);
+  }
+
+  /// Creates a DecoratedType corresponding to [type], with fresh nullability
+  /// nodes everywhere that don't correspond to any source location.  These
+  /// nodes can later be unioned with other nodes.
+  factory DecoratedType.forImplicitType(DartType type, NullabilityGraph graph) {
+    if (type.isDynamic || type.isVoid) {
+      return DecoratedType(type, graph.always);
+    } else if (type is InterfaceType) {
+      return DecoratedType(type, NullabilityNode.forInferredType(),
+          typeArguments: type.typeArguments
+              .map((t) => DecoratedType.forImplicitType(t, graph))
+              .toList());
+    } else if (type is FunctionType) {
+      return DecoratedType.forImplicitFunction(
+          type, NullabilityNode.forInferredType(), graph);
+    } else if (type is TypeParameterType) {
+      return DecoratedType(type, NullabilityNode.forInferredType());
+    }
+    // TODO(paulberry)
+    throw UnimplementedError(
+        'DecoratedType.forImplicitType(${type.runtimeType})');
+  }
+
+  /// If `this` represents an interface type, returns the substitution necessary
+  /// to produce this type using the class's type as a starting point.
+  /// Otherwise throws an exception.
+  ///
+  /// For instance, if `this` represents `List<int?1>`, returns the substitution
+  /// `{T: int?1}`, where `T` is the [TypeParameterElement] for `List`'s type
+  /// parameter.
+  Map<TypeParameterElement, DecoratedType> get asSubstitution {
+    var type = this.type;
+    if (type is InterfaceType) {
+      return Map<TypeParameterElement, DecoratedType>.fromIterables(
+          type.element.typeParameters, typeArguments);
+    } else {
+      throw StateError(
+          'Tried to convert a non-interface type to a substitution');
+    }
+  }
+
+  /// If this type is a function type, returns its generic formal parameters.
+  /// Otherwise returns `null`.
+  List<TypeParameterElement> get typeFormals {
+    var type = this.type;
+    if (type is FunctionType) {
+      return type.typeFormals;
+    } else {
+      return null;
+    }
+  }
+
+  /// Converts one function type into another by substituting the given
+  /// [argumentTypes] for the function's generic parameters.
+  DecoratedType instantiate(List<DecoratedType> argumentTypes) {
+    var type = this.type as FunctionType;
+    var typeFormals = type.typeFormals;
+    List<DartType> undecoratedArgumentTypes = [];
+    Map<TypeParameterElement, DecoratedType> substitution = {};
+    for (int i = 0; i < argumentTypes.length; i++) {
+      var argumentType = argumentTypes[i];
+      undecoratedArgumentTypes.add(argumentType.type);
+      substitution[typeFormals[i]] = argumentType;
+    }
+    return _substituteFunctionAfterFormals(
+        type.instantiate(undecoratedArgumentTypes), substitution);
+  }
+
   /// Apply the given [substitution] to this type.
   ///
   /// [undecoratedResult] is the result of the substitution, as determined by
-  /// the normal type system.
+  /// the normal type system.  If not supplied, it is inferred.
   DecoratedType substitute(
       Map<TypeParameterElement, DecoratedType> substitution,
-      DartType undecoratedResult) {
+      [DartType undecoratedResult]) {
     if (substitution.isEmpty) return this;
+    if (undecoratedResult == null) {
+      List<DartType> argumentTypes = [];
+      List<DartType> parameterTypes = [];
+      for (var entry in substitution.entries) {
+        argumentTypes.add(entry.value.type);
+        parameterTypes.add(entry.key.type);
+      }
+      undecoratedResult = type.substitute2(argumentTypes, parameterTypes);
+    }
     return _substitute(substitution, undecoratedResult);
   }
 
@@ -112,11 +273,31 @@
       }
       return '$name$args$trailing';
     } else if (type is FunctionType) {
-      assert(type.typeFormals.isEmpty); // TODO(paulberry)
-      assert(type.namedParameterTypes.isEmpty &&
-          namedParameters.isEmpty); // TODO(paulberry)
-      var args = positionalParameters.map((p) => p.toString()).join(', ');
-      return '$returnType Function($args)$trailing';
+      String formals = '';
+      if (type.typeFormals.isNotEmpty) {
+        formals = '<${type.typeFormals.join(', ')}>';
+      }
+      List<String> paramStrings = [];
+      for (int i = 0; i < positionalParameters.length; i++) {
+        var prefix = '';
+        if (i == type.normalParameterTypes.length) {
+          prefix = '[';
+        }
+        paramStrings.add('$prefix${positionalParameters[i]}');
+      }
+      if (type.normalParameterTypes.length < positionalParameters.length) {
+        paramStrings.last += ']';
+      }
+      if (namedParameters.isNotEmpty) {
+        var prefix = '{';
+        for (var entry in namedParameters.entries) {
+          paramStrings.add('$prefix${entry.key}: ${entry.value}');
+          prefix = '';
+        }
+        paramStrings.last += '}';
+      }
+      var args = paramStrings.join(', ');
+      return '$returnType Function$formals($args)$trailing';
     } else if (type is DynamicTypeImpl) {
       return 'dynamic';
     } else {
@@ -138,30 +319,49 @@
     var type = this.type;
     if (type is FunctionType && undecoratedResult is FunctionType) {
       assert(type.typeFormals.isEmpty); // TODO(paulberry)
-      var newPositionalParameters = <DecoratedType>[];
-      for (int i = 0; i < positionalParameters.length; i++) {
-        var numRequiredParameters =
-            undecoratedResult.normalParameterTypes.length;
-        var undecoratedParameterType = i < numRequiredParameters
-            ? undecoratedResult.normalParameterTypes[i]
-            : undecoratedResult
-                .optionalParameterTypes[i - numRequiredParameters];
-        newPositionalParameters.add(positionalParameters[i]
-            ._substitute(substitution, undecoratedParameterType));
+      return _substituteFunctionAfterFormals(undecoratedResult, substitution);
+    } else if (type is InterfaceType && undecoratedResult is InterfaceType) {
+      List<DecoratedType> newTypeArguments = [];
+      for (int i = 0; i < typeArguments.length; i++) {
+        newTypeArguments.add(typeArguments[i]
+            .substitute(substitution, undecoratedResult.typeArguments[i]));
       }
       return DecoratedType(undecoratedResult, node,
-          returnType: returnType._substitute(
-              substitution, undecoratedResult.returnType),
-          positionalParameters: newPositionalParameters);
+          typeArguments: newTypeArguments);
     } else if (type is TypeParameterType) {
       var inner = substitution[type.element];
-      return DecoratedType(undecoratedResult,
-          NullabilityNode.forSubstitution(inner?.node, node));
+      if (inner == null) {
+        return this;
+      } else {
+        return inner
+            .withNode(NullabilityNode.forSubstitution(inner.node, node));
+      }
     } else if (type is VoidType) {
       return this;
     }
     throw '$type.substitute($substitution)'; // TODO(paulberry)
   }
+
+  /// Performs the logic that is common to substitution and function type
+  /// instantiation.  Namely, a decorated type is formed whose undecorated type
+  /// is [undecoratedResult], and whose return type, positional parameters, and
+  /// named parameters are formed by performing the given [substitution].
+  DecoratedType _substituteFunctionAfterFormals(FunctionType undecoratedResult,
+      Map<TypeParameterElement, DecoratedType> substitution) {
+    var newPositionalParameters = <DecoratedType>[];
+    for (int i = 0; i < positionalParameters.length; i++) {
+      var numRequiredParameters = undecoratedResult.normalParameterTypes.length;
+      var undecoratedParameterType = i < numRequiredParameters
+          ? undecoratedResult.normalParameterTypes[i]
+          : undecoratedResult.optionalParameterTypes[i - numRequiredParameters];
+      newPositionalParameters.add(positionalParameters[i]
+          ._substitute(substitution, undecoratedParameterType));
+    }
+    return DecoratedType(undecoratedResult, node,
+        returnType:
+            returnType._substitute(substitution, undecoratedResult.returnType),
+        positionalParameters: newPositionalParameters);
+  }
 }
 
 /// A [DecoratedType] based on a type annotation appearing explicitly in the
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
new file mode 100644
index 0000000..08c3f80
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -0,0 +1,1466 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_origin.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+
+/// Visitor that builds nullability graph edges by examining code to be
+/// migrated.
+///
+/// The return type of each `visit...` method is a [DecoratedType] indicating
+/// the static type of the visited expression, along with the constraint
+/// variables that will determine its nullability.  For `visit...` methods that
+/// don't visit expressions, `null` will be returned.
+class EdgeBuilder extends GeneralizingAstVisitor<DecoratedType> {
+  final InheritanceManager2 _inheritanceManager;
+
+  /// The repository of constraint variables and decorated types (from a
+  /// previous pass over the source code).
+  final VariableRepository _variables;
+
+  final NullabilityMigrationListener /*?*/ listener;
+
+  final NullabilityGraph _graph;
+
+  /// The file being analyzed.
+  final Source _source;
+
+  final DecoratedClassHierarchy _decoratedClassHierarchy;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `Object`.
+  final DecoratedType _notNullType;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `bool`.
+  final DecoratedType _nonNullableBoolType;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `Type`.
+  final DecoratedType _nonNullableTypeType;
+
+  /// For convenience, a [DecoratedType] representing `Null`.
+  final DecoratedType _nullType;
+
+  /// The [DecoratedType] of the innermost function or method being visited, or
+  /// `null` if the visitor is not inside any function or method.
+  ///
+  /// This is needed to construct the appropriate nullability constraints for
+  /// return statements.
+  DecoratedType _currentFunctionType;
+
+  /// Information about the most recently visited binary expression whose
+  /// boolean value could possibly affect nullability analysis.
+  _ConditionInfo _conditionInfo;
+
+  /// The set of nullability nodes that would have to be `nullable` for the code
+  /// currently being visited to be reachable.
+  ///
+  /// Guard variables are attached to the left hand side of any generated
+  /// constraints, so that constraints do not take effect if they come from
+  /// code that can be proven unreachable by the migration tool.
+  final _guards = <NullabilityNode>[];
+
+  /// Indicates whether the statement or expression being visited is within
+  /// conditional control flow.  If `true`, this means that the enclosing
+  /// function might complete normally without executing the current statement
+  /// or expression.
+  bool _inConditionalControlFlow = false;
+
+  NullabilityNode _lastConditionalNode;
+
+  EdgeBuilder(TypeProvider typeProvider, TypeSystem typeSystem, this._variables,
+      this._graph, this._source, this.listener)
+      : _decoratedClassHierarchy = DecoratedClassHierarchy(_variables, _graph),
+        _inheritanceManager = InheritanceManager2(typeSystem),
+        _notNullType = DecoratedType(typeProvider.objectType, _graph.never),
+        _nonNullableBoolType =
+            DecoratedType(typeProvider.boolType, _graph.never),
+        _nonNullableTypeType =
+            DecoratedType(typeProvider.typeType, _graph.never),
+        _nullType = DecoratedType(typeProvider.nullType, _graph.always);
+
+  /// Gets the decorated type of [element] from [_variables], performing any
+  /// necessary substitutions.
+  DecoratedType getOrComputeElementType(Element element,
+      {DecoratedType targetType}) {
+    Map<TypeParameterElement, DecoratedType> substitution;
+    Element baseElement;
+    if (element is Member) {
+      assert(targetType != null);
+      baseElement = element.baseElement;
+      var targetTypeType = targetType.type;
+      if (targetTypeType is InterfaceType &&
+          baseElement is ClassMemberElement) {
+        var enclosingClass = baseElement.enclosingElement;
+        assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
+        substitution = <TypeParameterElement, DecoratedType>{};
+        assert(enclosingClass.typeParameters.length ==
+            targetTypeType.typeArguments.length); // TODO(paulberry)
+        for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
+          substitution[enclosingClass.typeParameters[i]] =
+              targetType.typeArguments[i];
+        }
+      }
+    } else {
+      baseElement = element;
+    }
+    DecoratedType decoratedBaseType;
+    if (baseElement is PropertyAccessorElement &&
+        baseElement.isSynthetic &&
+        !baseElement.variable.isSynthetic) {
+      var variable = baseElement.variable;
+      var decoratedElementType = _variables.decoratedElementType(variable);
+      if (baseElement.isGetter) {
+        decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
+            returnType: decoratedElementType);
+      } else {
+        assert(baseElement.isSetter);
+        decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
+            positionalParameters: [decoratedElementType],
+            returnType: DecoratedType(VoidTypeImpl.instance, _graph.always));
+      }
+    } else {
+      decoratedBaseType = _variables.decoratedElementType(baseElement);
+    }
+    if (substitution != null) {
+      DartType elementType;
+      if (element is MethodElement) {
+        elementType = element.type;
+      } else if (element is ConstructorElement) {
+        elementType = element.type;
+      } else {
+        throw element.runtimeType; // TODO(paulberry)
+      }
+      return decoratedBaseType.substitute(substitution, elementType);
+    } else {
+      return decoratedBaseType;
+    }
+  }
+
+  @override
+  DecoratedType visitAsExpression(AsExpression node) {
+    // TODO(brianwilkerson)
+    _unimplemented(node, 'AsExpression');
+  }
+
+  @override
+  DecoratedType visitAssertStatement(AssertStatement node) {
+    _handleAssignment(node.condition, _notNullType);
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      if (!_inConditionalControlFlow &&
+          _conditionInfo.trueDemonstratesNonNullIntent != null) {
+        _graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
+            _graph.never, NonNullAssertionOrigin(_source, node.offset),
+            hard: true);
+      }
+    }
+    node.message?.accept(this);
+    return null;
+  }
+
+  @override
+  DecoratedType visitAssignmentExpression(AssignmentExpression node) {
+    if (node.operator.type != TokenType.EQ) {
+      // TODO(paulberry)
+      _unimplemented(node, 'Assignment with operator ${node.operator.lexeme}');
+    }
+    var leftType = node.leftHandSide.accept(this);
+    var conditionalNode = _lastConditionalNode;
+    _lastConditionalNode = null;
+    var expressionType = _handleAssignment(node.rightHandSide, leftType);
+    if (_isConditionalExpression(node.leftHandSide)) {
+      expressionType = expressionType.withNode(
+          NullabilityNode.forLUB(conditionalNode, expressionType.node));
+      _variables.recordDecoratedExpressionType(node, expressionType);
+    }
+    return expressionType;
+  }
+
+  @override
+  DecoratedType visitAwaitExpression(AwaitExpression node) {
+    var expressionType = node.expression.accept(this);
+    // TODO(paulberry) Handle subclasses of Future.
+    if (expressionType.type.isDartAsyncFuture ||
+        expressionType.type.isDartAsyncFutureOr) {
+      expressionType = expressionType.typeArguments[0];
+    }
+    return expressionType;
+  }
+
+  @override
+  DecoratedType visitBinaryExpression(BinaryExpression node) {
+    var operatorType = node.operator.type;
+    if (operatorType == TokenType.EQ_EQ || operatorType == TokenType.BANG_EQ) {
+      assert(node.leftOperand is! NullLiteral); // TODO(paulberry)
+      var leftType = node.leftOperand.accept(this);
+      node.rightOperand.accept(this);
+      if (node.rightOperand is NullLiteral) {
+        // TODO(paulberry): figure out what the rules for isPure should be.
+        // TODO(paulberry): only set falseChecksNonNull in unconditional
+        // control flow
+        bool isPure = node.leftOperand is SimpleIdentifier;
+        var conditionInfo = _ConditionInfo(node,
+            isPure: isPure,
+            trueGuard: leftType.node,
+            falseDemonstratesNonNullIntent: leftType.node);
+        _conditionInfo = operatorType == TokenType.EQ_EQ
+            ? conditionInfo
+            : conditionInfo.not(node);
+      }
+      return _nonNullableBoolType;
+    } else if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
+        operatorType == TokenType.BAR_BAR) {
+      _handleAssignment(node.leftOperand, _notNullType);
+      _handleAssignment(node.rightOperand, _notNullType);
+      return _nonNullableBoolType;
+    } else if (operatorType == TokenType.QUESTION_QUESTION) {
+      DecoratedType expressionType;
+      var leftType = node.leftOperand.accept(this);
+      try {
+        _guards.add(leftType.node);
+        var rightType = node.rightOperand.accept(this);
+        var ifNullNode = NullabilityNode.forIfNotNull();
+        expressionType = DecoratedType(node.staticType, ifNullNode);
+        _graph.connect(rightType.node, expressionType.node,
+            IfNullOrigin(_source, node.offset),
+            guards: _guards);
+      } finally {
+        _guards.removeLast();
+      }
+      _variables.recordDecoratedExpressionType(node, expressionType);
+      return expressionType;
+    } else if (operatorType.isUserDefinableOperator) {
+      _handleAssignment(node.leftOperand, _notNullType);
+      var callee = node.staticElement;
+      assert(!(callee is ClassMemberElement &&
+          callee
+              .enclosingElement.typeParameters.isNotEmpty)); // TODO(paulberry)
+      assert(callee != null); // TODO(paulberry)
+      var calleeType = getOrComputeElementType(callee);
+      // TODO(paulberry): substitute if necessary
+      assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
+      _handleAssignment(node.rightOperand, calleeType.positionalParameters[0]);
+      return calleeType.returnType;
+    } else {
+      // TODO(paulberry)
+      node.leftOperand.accept(this);
+      node.rightOperand.accept(this);
+      _unimplemented(
+          node, 'Binary expression with operator ${node.operator.lexeme}');
+    }
+  }
+
+  @override
+  DecoratedType visitBooleanLiteral(BooleanLiteral node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitCascadeExpression(CascadeExpression node) {
+    var type = node.target.accept(this);
+    node.cascadeSections.accept(this);
+    return type;
+  }
+
+  @override
+  DecoratedType visitClassDeclaration(ClassDeclaration node) {
+    node.members.accept(this);
+    return null;
+  }
+
+  @override
+  DecoratedType visitClassTypeAlias(ClassTypeAlias node) {
+    var classElement = node.declaredElement;
+    var supertype = classElement.supertype;
+    var superElement = supertype.element;
+    if (superElement is ClassElementHandle) {
+      superElement = (superElement as ClassElementHandle).actualElement;
+    }
+    for (var constructorElement in classElement.constructors) {
+      assert(constructorElement.isSynthetic);
+      var superConstructorElement =
+          superElement.getNamedConstructor(constructorElement.name);
+      var constructorDecoratedType = _variables
+          .decoratedElementType(constructorElement)
+          .substitute(_decoratedClassHierarchy
+              .getDecoratedSupertype(classElement, superElement)
+              .asSubstitution);
+      var superConstructorDecoratedType =
+          _variables.decoratedElementType(superConstructorElement);
+      var origin = ImplicitMixinSuperCallOrigin(_source, node.offset);
+      _unionDecoratedTypeParameters(
+          constructorDecoratedType, superConstructorDecoratedType, origin);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitComment(Comment node) {
+    // Ignore comments.
+    return null;
+  }
+
+  @override
+  DecoratedType visitConditionalExpression(ConditionalExpression node) {
+    _handleAssignment(node.condition, _notNullType);
+    // TODO(paulberry): guard anything inside the true and false branches
+    var thenType = node.thenExpression.accept(this);
+    var elseType = node.elseExpression.accept(this);
+
+    var overallType = _decorateUpperOrLowerBound(
+        node, node.staticType, thenType, elseType, true);
+    _variables.recordDecoratedExpressionType(node, overallType);
+    return overallType;
+  }
+
+  @override
+  DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
+    _handleExecutableDeclaration(
+        node,
+        node.declaredElement,
+        node.metadata,
+        null,
+        node.parameters,
+        node.initializers,
+        node.body,
+        node.redirectedConstructor);
+    return null;
+  }
+
+  @override
+  DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
+    node.parameter.accept(this);
+    var defaultValue = node.defaultValue;
+    if (defaultValue == null) {
+      if (node.declaredElement.hasRequired) {
+        // Nothing to do; the implicit default value of `null` will never be
+        // reached.
+      } else {
+        _graph.connect(
+            _graph.always,
+            getOrComputeElementType(node.declaredElement).node,
+            OptionalFormalParameterOrigin(_source, node.offset),
+            guards: _guards);
+      }
+    } else {
+      _handleAssignment(
+          defaultValue, getOrComputeElementType(node.declaredElement),
+          canInsertChecks: false);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitDoubleLiteral(DoubleLiteral node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    if (_currentFunctionType == null) {
+      _unimplemented(
+          node,
+          'ExpressionFunctionBody with no current function '
+          '(parent is ${node.parent.runtimeType})');
+    }
+    _handleAssignment(node.expression, _currentFunctionType.returnType);
+    return null;
+  }
+
+  @override
+  DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
+    var parameterElement = node.declaredElement as FieldFormalParameterElement;
+    var parameterType = _variables.decoratedElementType(parameterElement);
+    var fieldType = _variables.decoratedElementType(parameterElement.field);
+    var origin = FieldFormalParameterOrigin(_source, node.offset);
+    if (node.type == null) {
+      _unionDecoratedTypes(parameterType, fieldType, origin);
+    } else {
+      _checkAssignment(origin,
+          source: parameterType, destination: fieldType, hard: true);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
+    node.functionExpression.parameters?.accept(this);
+    assert(_currentFunctionType == null);
+    _currentFunctionType =
+        _variables.decoratedElementType(node.declaredElement);
+    _inConditionalControlFlow = false;
+    try {
+      node.functionExpression.body.accept(this);
+    } finally {
+      _currentFunctionType = null;
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitFunctionExpression(FunctionExpression node) {
+    // TODO(brianwilkerson)
+    _unimplemented(node, 'FunctionExpression');
+  }
+
+  @override
+  DecoratedType visitFunctionExpressionInvocation(
+      FunctionExpressionInvocation node) {
+    DecoratedType calleeType = node.function.accept(this);
+    return _handleInvocationArguments(node, node.argumentList.arguments,
+        node.typeArguments, calleeType, null);
+  }
+
+  @override
+  DecoratedType visitIfStatement(IfStatement node) {
+    // TODO(paulberry): should the use of a boolean in an if-statement be
+    // treated like an implicit `assert(b != null)`?  Probably.
+    _handleAssignment(node.condition, _notNullType);
+    _inConditionalControlFlow = true;
+    NullabilityNode trueGuard;
+    NullabilityNode falseGuard;
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      trueGuard = _conditionInfo.trueGuard;
+      falseGuard = _conditionInfo.falseGuard;
+      _variables.recordConditionalDiscard(_source, node,
+          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
+    }
+    if (trueGuard != null) {
+      _guards.add(trueGuard);
+    }
+    try {
+      node.thenStatement.accept(this);
+    } finally {
+      if (trueGuard != null) {
+        _guards.removeLast();
+      }
+    }
+    if (falseGuard != null) {
+      _guards.add(falseGuard);
+    }
+    try {
+      node.elseStatement?.accept(this);
+    } finally {
+      if (falseGuard != null) {
+        _guards.removeLast();
+      }
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitIndexExpression(IndexExpression node) {
+    DecoratedType targetType;
+    var target = node.realTarget;
+    if (target != null) {
+      targetType = _handleAssignment(target, _notNullType);
+    }
+    var callee = node.staticElement;
+    if (callee == null) {
+      // TODO(paulberry)
+      _unimplemented(node, 'Index expression with no static type');
+    }
+    var calleeType = getOrComputeElementType(callee, targetType: targetType);
+    // TODO(paulberry): substitute if necessary
+    _handleAssignment(node.index, calleeType.positionalParameters[0]);
+    if (node.inSetterContext()) {
+      return calleeType.positionalParameters[1];
+    } else {
+      return calleeType.returnType;
+    }
+  }
+
+  @override
+  DecoratedType visitInstanceCreationExpression(
+      InstanceCreationExpression node) {
+    var callee = node.staticElement;
+    var typeParameters = callee.enclosingElement.typeParameters;
+    List<DecoratedType> decoratedTypeArguments;
+    var typeArguments = node.constructorName.type.typeArguments;
+    if (typeArguments != null) {
+      decoratedTypeArguments = typeArguments.arguments
+          .map((t) => _variables.decoratedTypeAnnotation(_source, t))
+          .toList();
+    } else {
+      decoratedTypeArguments = const [];
+    }
+    var createdType = DecoratedType(node.staticType, _graph.never,
+        typeArguments: decoratedTypeArguments);
+    var calleeType = getOrComputeElementType(callee, targetType: createdType);
+    _handleInvocationArguments(node, node.argumentList.arguments, typeArguments,
+        calleeType, typeParameters);
+    return createdType;
+  }
+
+  @override
+  DecoratedType visitIntegerLiteral(IntegerLiteral node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitIsExpression(IsExpression node) {
+    var type = node.type;
+    if (type is NamedType && type.typeArguments != null) {
+      // TODO(brianwilkerson) Figure out what constraints we need to add to
+      //  allow the tool to decide whether to make the type arguments nullable.
+      // TODO(brianwilkerson)
+      _unimplemented(node, 'Is expression with type arguments');
+    } else if (type is GenericFunctionType) {
+      // TODO(brianwilkerson)
+      _unimplemented(node, 'Is expression with GenericFunctionType');
+    }
+    node.visitChildren(this);
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitLibraryDirective(LibraryDirective node) {
+    // skip directives
+    return null;
+  }
+
+  @override
+  DecoratedType visitListLiteral(ListLiteral node) {
+    var listType = node.staticType as InterfaceType;
+    if (node.typeArguments == null) {
+      // TODO(brianwilkerson) We might want to create a fake node in the graph
+      //  to represent the type argument so that we can still create edges from
+      //  the elements to it.
+      // TODO(brianwilkerson)
+      _unimplemented(node, 'List literal with no type arguments');
+    } else {
+      var typeArgumentType = _variables.decoratedTypeAnnotation(
+          _source, node.typeArguments.arguments[0]);
+      if (typeArgumentType == null) {
+        _unimplemented(node, 'Could not compute type argument type');
+      }
+      for (var element in node.elements) {
+        if (element is Expression) {
+          _handleAssignment(element, typeArgumentType);
+        } else {
+          // Handle spread and control flow elements.
+          element.accept(this);
+          // TODO(brianwilkerson)
+          _unimplemented(node, 'Spread or control flow element');
+        }
+      }
+      return DecoratedType(listType, _graph.never,
+          typeArguments: [typeArgumentType]);
+    }
+  }
+
+  @override
+  DecoratedType visitMethodDeclaration(MethodDeclaration node) {
+    if (node.typeParameters != null) {
+      _unimplemented(node, 'Generic method');
+    }
+    _handleExecutableDeclaration(node, node.declaredElement, node.metadata,
+        node.returnType, node.parameters, null, node.body, null);
+    return null;
+  }
+
+  @override
+  DecoratedType visitMethodInvocation(MethodInvocation node) {
+    DecoratedType targetType;
+    var target = node.realTarget;
+    bool isConditional = _isConditionalExpression(node);
+    if (target != null) {
+      if (isConditional) {
+        targetType = target.accept(this);
+      } else {
+        _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
+        targetType = _handleAssignment(target, _notNullType);
+      }
+    }
+    var callee = node.methodName.staticElement;
+    if (callee == null) {
+      // TODO(paulberry)
+      _unimplemented(node, 'Unresolved method name');
+    }
+    var calleeType = getOrComputeElementType(callee, targetType: targetType);
+    if (callee is PropertyAccessorElement) {
+      calleeType = calleeType.returnType;
+    }
+    var expressionType = _handleInvocationArguments(node,
+        node.argumentList.arguments, node.typeArguments, calleeType, null);
+    if (isConditional) {
+      expressionType = expressionType.withNode(
+          NullabilityNode.forLUB(targetType.node, expressionType.node));
+      _variables.recordDecoratedExpressionType(node, expressionType);
+    }
+    return expressionType;
+  }
+
+  @override
+  DecoratedType visitNamespaceDirective(NamespaceDirective node) {
+    // skip directives
+    return null;
+  }
+
+  @override
+  DecoratedType visitNode(AstNode node) {
+    if (listener != null) {
+      try {
+        return super.visitNode(node);
+      } catch (exception, stackTrace) {
+        listener.addDetail('''
+$exception
+
+$stackTrace''');
+        return null;
+      }
+    } else {
+      return super.visitNode(node);
+    }
+  }
+
+  @override
+  DecoratedType visitNullLiteral(NullLiteral node) {
+    return _nullType;
+  }
+
+  @override
+  DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
+    return node.expression.accept(this);
+  }
+
+  @override
+  DecoratedType visitPostfixExpression(PostfixExpression node) {
+    var operatorType = node.operator.type;
+    if (operatorType == TokenType.PLUS_PLUS ||
+        operatorType == TokenType.MINUS_MINUS) {
+      _handleAssignment(node.operand, _notNullType);
+      var callee = node.staticElement;
+      if (callee is ClassMemberElement &&
+          callee.enclosingElement.typeParameters.isNotEmpty) {
+        // TODO(paulberry)
+        _unimplemented(node,
+            'Operator ${operatorType.lexeme} defined on a class with type parameters');
+      }
+      if (callee == null) {
+        // TODO(paulberry)
+        _unimplemented(node, 'Unresolved operator ${operatorType.lexeme}');
+      }
+      var calleeType = getOrComputeElementType(callee);
+      // TODO(paulberry): substitute if necessary
+      return calleeType.returnType;
+    }
+    _unimplemented(
+        node, 'Postfix expression with operator ${node.operator.lexeme}');
+  }
+
+  @override
+  DecoratedType visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (node.prefix.staticElement is ImportElement) {
+      // TODO(paulberry)
+      _unimplemented(node, 'PrefixedIdentifier with a prefix');
+    } else {
+      return _handlePropertyAccess(node, node.prefix, node.identifier);
+    }
+  }
+
+  @override
+  DecoratedType visitPrefixExpression(PrefixExpression node) {
+    var targetType = _handleAssignment(node.operand, _notNullType);
+    var operatorType = node.operator.type;
+    if (operatorType == TokenType.BANG) {
+      return _nonNullableBoolType;
+    } else if (operatorType == TokenType.PLUS_PLUS ||
+        operatorType == TokenType.MINUS_MINUS) {
+      var callee = node.staticElement;
+      if (callee is ClassMemberElement &&
+          callee.enclosingElement.typeParameters.isNotEmpty) {
+        // TODO(paulberry)
+        _unimplemented(node,
+            'Operator ${operatorType.lexeme} defined on a class with type parameters');
+      }
+      if (callee == null) {
+        // TODO(paulberry)
+        _unimplemented(node, 'Unresolved operator ${operatorType.lexeme}');
+      }
+      var calleeType = getOrComputeElementType(callee);
+      // TODO(paulberry): substitute if necessary
+      return calleeType.returnType;
+    } else {
+      var callee = node.staticElement;
+      var calleeType = getOrComputeElementType(callee, targetType: targetType);
+      return _handleInvocationArguments(node, [], null, calleeType, null);
+    }
+  }
+
+  @override
+  DecoratedType visitPropertyAccess(PropertyAccess node) {
+    return _handlePropertyAccess(node, node.realTarget, node.propertyName);
+  }
+
+  @override
+  DecoratedType visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    var callee = node.constructorName.staticElement;
+    var calleeType = _variables.decoratedElementType(callee);
+    _handleInvocationArguments(
+        node, node.argumentList.arguments, null, calleeType, null);
+    return null;
+  }
+
+  @override
+  DecoratedType visitReturnStatement(ReturnStatement node) {
+    DecoratedType returnType = _currentFunctionType.returnType;
+    Expression returnValue = node.expression;
+    // TODO(danrubel): This does not handle situations where the returnType
+    // or the returnValue's type extends or implements dart:async Future.
+    if ((returnType.type.isDartAsyncFuture ||
+            returnType.type.isDartAsyncFutureOr) &&
+        node.thisOrAncestorOfType<FunctionBody>().isAsynchronous &&
+        !returnValue.staticType.isDartAsyncFuture) {
+      returnType = returnType.typeArguments?.first;
+      if (returnType == null) {
+        return null;
+      }
+    }
+    if (returnValue == null) {
+      _checkAssignment(null,
+          source: _nullType, destination: returnType, hard: false);
+    } else {
+      _handleAssignment(returnValue, returnType);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitSetOrMapLiteral(SetOrMapLiteral node) {
+    var listType = node.staticType as InterfaceType;
+    var typeArguments = node.typeArguments?.arguments;
+    if (typeArguments == null) {
+      // TODO(brianwilkerson) We might want to create fake nodes in the graph to
+      //  represent the type arguments so that we can still create edges from
+      //  the elements to them.
+      // TODO(brianwilkerson)
+      _unimplemented(node, 'Set or map literal with no type arguments');
+    } else if (typeArguments.length == 1) {
+      var elementType =
+          _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
+      for (var element in node.elements) {
+        if (element is Expression) {
+          _handleAssignment(element, elementType);
+        } else {
+          // Handle spread and control flow elements.
+          element.accept(this);
+          // TODO(brianwilkerson)
+          _unimplemented(node, 'Spread or control flow element');
+        }
+      }
+      return DecoratedType(listType, _graph.never,
+          typeArguments: [elementType]);
+    } else if (typeArguments.length == 2) {
+      var keyType =
+          _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
+      var valueType =
+          _variables.decoratedTypeAnnotation(_source, typeArguments[1]);
+      for (var element in node.elements) {
+        if (element is MapLiteralEntry) {
+          _handleAssignment(element.key, keyType);
+          _handleAssignment(element.value, valueType);
+        } else {
+          // Handle spread and control flow elements.
+          element.accept(this);
+          // TODO(brianwilkerson)
+          _unimplemented(node, 'Spread or control flow element');
+        }
+      }
+      return DecoratedType(listType, _graph.never,
+          typeArguments: [keyType, valueType]);
+    } else {
+      // TODO(brianwilkerson)
+      _unimplemented(
+          node, 'Set or map literal with more than two type arguments');
+    }
+  }
+
+  @override
+  DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
+    var staticElement = node.staticElement;
+    if (staticElement is ParameterElement ||
+        staticElement is LocalVariableElement ||
+        staticElement is FunctionElement ||
+        staticElement is MethodElement) {
+      return getOrComputeElementType(staticElement);
+    } else if (staticElement is PropertyAccessorElement) {
+      var elementType = getOrComputeElementType(staticElement);
+      return staticElement.isGetter
+          ? elementType.returnType
+          : elementType.positionalParameters[0];
+    } else if (staticElement is ClassElement) {
+      return _nonNullableTypeType;
+    } else {
+      // TODO(paulberry)
+      _unimplemented(node,
+          'Simple identifier with a static element of type ${staticElement.runtimeType}');
+    }
+  }
+
+  @override
+  DecoratedType visitStringLiteral(StringLiteral node) {
+    node.visitChildren(this);
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitSuperExpression(SuperExpression node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitSymbolLiteral(SymbolLiteral node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitThisExpression(ThisExpression node) {
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitThrowExpression(ThrowExpression node) {
+    node.expression.accept(this);
+    // TODO(paulberry): do we need to check the expression type?  I think not.
+    return DecoratedType(node.staticType, _graph.never);
+  }
+
+  @override
+  DecoratedType visitTypeName(TypeName typeName) {
+    var typeArguments = typeName.typeArguments?.arguments;
+    var element = typeName.name.staticElement;
+    if (element is TypeParameterizedElement) {
+      if (typeArguments == null) {
+        var instantiatedType =
+            _variables.decoratedTypeAnnotation(_source, typeName);
+        if (instantiatedType == null) {
+          throw new StateError('No type annotation for type name '
+              '${typeName.toSource()}, offset=${typeName.offset}');
+        }
+        var origin = InstantiateToBoundsOrigin(_source, typeName.offset);
+        for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
+          _unionDecoratedTypes(
+              instantiatedType.typeArguments[i],
+              _variables.decoratedElementType(element.typeParameters[i]),
+              origin);
+        }
+      } else {
+        for (int i = 0; i < typeArguments.length; i++) {
+          DecoratedType bound;
+          bound = _variables.decoratedElementType(element.typeParameters[i]);
+          var argumentType =
+              _variables.decoratedTypeAnnotation(_source, typeArguments[i]);
+          if (argumentType == null) {
+            _unimplemented(typeName,
+                'No decorated type for type argument ${typeArguments[i]} ($i)');
+          }
+          _checkAssignment(null,
+              source: argumentType, destination: bound, hard: true);
+        }
+      }
+    }
+    return _nonNullableTypeType;
+  }
+
+  @override
+  DecoratedType visitVariableDeclarationList(VariableDeclarationList node) {
+    node.metadata.accept(this);
+    var typeAnnotation = node.type;
+    for (var variable in node.variables) {
+      variable.metadata.accept(this);
+      var initializer = variable.initializer;
+      if (initializer != null) {
+        var destinationType = getOrComputeElementType(variable.declaredElement);
+        if (typeAnnotation == null) {
+          var initializerType = initializer.accept(this);
+          if (initializerType == null) {
+            throw StateError('No type computed for ${initializer.runtimeType} '
+                '(${initializer.toSource()}) offset=${initializer.offset}');
+          }
+          _unionDecoratedTypes(initializerType, destinationType,
+              InitializerInferenceOrigin(_source, variable.name.offset));
+        } else {
+          _handleAssignment(initializer, destinationType);
+        }
+      }
+    }
+    return null;
+  }
+
+  /// Creates the necessary constraint(s) for an assignment from [source] to
+  /// [destination].  [origin] should be used as the origin for any edges
+  /// created.  [hard] indicates whether a hard edge should be created.
+  void _checkAssignment(EdgeOrigin origin,
+      {@required DecoratedType source,
+      @required DecoratedType destination,
+      @required bool hard}) {
+    var edge = _graph.connect(source.node, destination.node, origin,
+        guards: _guards, hard: hard);
+    if (origin is ExpressionChecks) {
+      origin.edges.add(edge);
+    }
+    // TODO(paulberry): generalize this.
+    if ((_isSimple(source) || destination.type.isObject) &&
+        _isSimple(destination)) {
+      // Ok; nothing further to do.
+    } else if (source.type is InterfaceType &&
+        destination.type is InterfaceType &&
+        source.type.element == destination.type.element) {
+      assert(source.typeArguments.length == destination.typeArguments.length);
+      for (int i = 0; i < source.typeArguments.length; i++) {
+        _checkAssignment(origin,
+            source: source.typeArguments[i],
+            destination: destination.typeArguments[i],
+            hard: false);
+      }
+    } else if (source.type is FunctionType &&
+        destination.type is FunctionType) {
+      _checkAssignment(origin,
+          source: source.returnType,
+          destination: destination.returnType,
+          hard: hard);
+      if (source.typeArguments.isNotEmpty ||
+          destination.typeArguments.isNotEmpty) {
+        throw UnimplementedError('TODO(paulberry)');
+      }
+      for (int i = 0;
+          i < source.positionalParameters.length &&
+              i < destination.positionalParameters.length;
+          i++) {
+        // Note: source and destination are swapped due to contravariance.
+        _checkAssignment(origin,
+            source: destination.positionalParameters[i],
+            destination: source.positionalParameters[i],
+            hard: hard);
+      }
+      for (var entry in destination.namedParameters.entries) {
+        // Note: source and destination are swapped due to contravariance.
+        _checkAssignment(origin,
+            source: entry.value,
+            destination: source.namedParameters[entry.key],
+            hard: hard);
+      }
+    } else if (destination.type.isDynamic || source.type.isDynamic) {
+      // ok; nothing further to do.
+    } else {
+      throw '$destination <= $source'; // TODO(paulberry)
+    }
+  }
+
+  /// Double checks that [name] is not the name of a method or getter declared
+  /// on [Object].
+  ///
+  /// TODO(paulberry): get rid of this method and put the correct logic into the
+  /// call sites.
+  void _checkNonObjectMember(String name) {
+    assert(name != 'toString');
+    assert(name != 'hashCode');
+    assert(name != 'noSuchMethod');
+    assert(name != 'runtimeType');
+  }
+
+  DecoratedType _decorateUpperOrLowerBound(AstNode astNode, DartType type,
+      DecoratedType left, DecoratedType right, bool isLUB,
+      {NullabilityNode node}) {
+    if (type.isDynamic || type.isVoid) {
+      if (type.isDynamic) {
+        _unimplemented(astNode, 'LUB/GLB with dynamic');
+      }
+      return DecoratedType(type, _graph.always);
+    }
+    node ??= isLUB
+        ? NullabilityNode.forLUB(left.node, right.node)
+        : _nullabilityNodeForGLB(astNode, left.node, right.node);
+    if (type is InterfaceType) {
+      if (type.typeArguments.isEmpty) {
+        return DecoratedType(type, node);
+      } else {
+        var leftType = left.type;
+        var rightType = right.type;
+        if (leftType is InterfaceType && rightType is InterfaceType) {
+          if (leftType.element != type.element ||
+              rightType.element != type.element) {
+            _unimplemented(astNode, 'LUB/GLB with substitution');
+          }
+          List<DecoratedType> newTypeArguments = [];
+          for (int i = 0; i < type.typeArguments.length; i++) {
+            newTypeArguments.add(_decorateUpperOrLowerBound(
+                astNode,
+                type.typeArguments[i],
+                left.typeArguments[i],
+                right.typeArguments[i],
+                isLUB));
+          }
+          return DecoratedType(type, node, typeArguments: newTypeArguments);
+        } else {
+          _unimplemented(
+              astNode,
+              'LUB/GLB with unexpected types: ${leftType.runtimeType}/'
+              '${rightType.runtimeType}');
+        }
+      }
+    } else if (type is FunctionType) {
+      var leftType = left.type;
+      var rightType = right.type;
+      if (leftType is FunctionType && rightType is FunctionType) {
+        var returnType = _decorateUpperOrLowerBound(
+            astNode, type.returnType, left.returnType, right.returnType, isLUB);
+        List<DecoratedType> positionalParameters = [];
+        Map<String, DecoratedType> namedParameters = {};
+        int positionalParameterCount = 0;
+        for (var parameter in type.parameters) {
+          DecoratedType leftParameterType;
+          DecoratedType rightParameterType;
+          if (parameter.isNamed) {
+            leftParameterType = left.namedParameters[parameter.name];
+            rightParameterType = right.namedParameters[parameter.name];
+          } else {
+            leftParameterType =
+                left.positionalParameters[positionalParameterCount];
+            rightParameterType =
+                right.positionalParameters[positionalParameterCount];
+            positionalParameterCount++;
+          }
+          var decoratedParameterType = _decorateUpperOrLowerBound(astNode,
+              parameter.type, leftParameterType, rightParameterType, !isLUB);
+          if (parameter.isNamed) {
+            namedParameters[parameter.name] = decoratedParameterType;
+          } else {
+            positionalParameters.add(decoratedParameterType);
+          }
+        }
+        return DecoratedType(type, node,
+            returnType: returnType,
+            positionalParameters: positionalParameters,
+            namedParameters: namedParameters);
+      } else {
+        _unimplemented(
+            astNode,
+            'LUB/GLB with unexpected types: ${leftType.runtimeType}/'
+            '${rightType.runtimeType}');
+      }
+    } else if (type is TypeParameterType) {
+      _unimplemented(astNode, 'LUB/GLB with type parameter types');
+    }
+    _unimplemented(astNode, '_decorateUpperOrLowerBound');
+  }
+
+  /// Creates the necessary constraint(s) for an assignment of the given
+  /// [expression] to a destination whose type is [destinationType].
+  DecoratedType _handleAssignment(
+      Expression expression, DecoratedType destinationType,
+      {bool canInsertChecks = true}) {
+    var sourceType = expression.accept(this);
+    if (sourceType == null) {
+      throw StateError('No type computed for ${expression.runtimeType} '
+          '(${expression.toSource()}) offset=${expression.offset}');
+    }
+    ExpressionChecks expressionChecks;
+    if (canInsertChecks) {
+      expressionChecks = ExpressionChecks(expression.end);
+      _variables.recordExpressionChecks(_source, expression, expressionChecks);
+    }
+    _checkAssignment(expressionChecks,
+        source: sourceType,
+        destination: destinationType,
+        hard: _isVariableOrParameterReference(expression) &&
+            !_inConditionalControlFlow);
+    return sourceType;
+  }
+
+  void _handleConstructorRedirection(
+      FormalParameterList parameters, ConstructorName redirectedConstructor) {
+    var callee = redirectedConstructor.staticElement;
+    if (callee is ConstructorMember) {
+      callee = (callee as ConstructorMember).baseElement;
+    }
+    var redirectedClass = callee.enclosingElement;
+    var calleeType = _variables.decoratedElementType(callee);
+    _handleInvocationArguments(
+        redirectedConstructor,
+        parameters.parameters,
+        redirectedConstructor.type.typeArguments,
+        calleeType,
+        redirectedClass.typeParameters);
+  }
+
+  void _handleExecutableDeclaration(
+      AstNode node,
+      ExecutableElement declaredElement,
+      NodeList<Annotation> metadata,
+      TypeAnnotation returnType,
+      FormalParameterList parameters,
+      NodeList<ConstructorInitializer> initializers,
+      FunctionBody body,
+      ConstructorName redirectedConstructor) {
+    assert(_currentFunctionType == null);
+    metadata.accept(this);
+    returnType?.accept(this);
+    parameters?.accept(this);
+    _currentFunctionType = _variables.decoratedElementType(declaredElement);
+    _inConditionalControlFlow = false;
+    try {
+      initializers?.accept(this);
+      body.accept(this);
+      if (redirectedConstructor != null) {
+        _handleConstructorRedirection(parameters, redirectedConstructor);
+      }
+      if (declaredElement is! ConstructorElement) {
+        var classElement = declaredElement.enclosingElement as ClassElement;
+        var origin = InheritanceOrigin(_source, node.offset);
+        for (var overridden in _inheritanceManager.getOverridden(
+                classElement.type,
+                Name(classElement.library.source.uri, declaredElement.name)) ??
+            const []) {
+          var overriddenElement = overridden.element as ExecutableElement;
+          assert(overriddenElement is! ExecutableMember);
+          var overriddenClass =
+              overriddenElement.enclosingElement as ClassElement;
+          var decoratedOverriddenFunctionType =
+              _variables.decoratedElementType(overriddenElement);
+          var decoratedSupertype = _decoratedClassHierarchy
+              .getDecoratedSupertype(classElement, overriddenClass);
+          var substitution = decoratedSupertype.asSubstitution;
+          var overriddenFunctionType =
+              decoratedOverriddenFunctionType.substitute(substitution);
+          if (returnType == null) {
+            _unionDecoratedTypes(_currentFunctionType.returnType,
+                overriddenFunctionType.returnType, origin);
+          } else {
+            _checkAssignment(origin,
+                source: _currentFunctionType.returnType,
+                destination: overriddenFunctionType.returnType,
+                hard: true);
+          }
+          if (parameters != null) {
+            int positionalParameterCount = 0;
+            for (var parameter in parameters.parameters) {
+              NormalFormalParameter normalParameter;
+              if (parameter is NormalFormalParameter) {
+                normalParameter = parameter;
+              } else {
+                normalParameter =
+                    (parameter as DefaultFormalParameter).parameter;
+              }
+              DecoratedType currentParameterType;
+              DecoratedType overriddenParameterType;
+              if (parameter.isNamed) {
+                var name = normalParameter.identifier.name;
+                currentParameterType =
+                    _currentFunctionType.namedParameters[name];
+                overriddenParameterType =
+                    overriddenFunctionType.namedParameters[name];
+              } else {
+                if (positionalParameterCount <
+                    _currentFunctionType.positionalParameters.length) {
+                  currentParameterType = _currentFunctionType
+                      .positionalParameters[positionalParameterCount];
+                }
+                if (positionalParameterCount <
+                    overriddenFunctionType.positionalParameters.length) {
+                  overriddenParameterType = overriddenFunctionType
+                      .positionalParameters[positionalParameterCount];
+                }
+                positionalParameterCount++;
+              }
+              if (overriddenParameterType != null) {
+                if (_isUntypedParameter(normalParameter)) {
+                  _unionDecoratedTypes(
+                      overriddenParameterType, currentParameterType, origin);
+                } else {
+                  _checkAssignment(origin,
+                      source: overriddenParameterType,
+                      destination: currentParameterType,
+                      hard: true);
+                }
+              }
+            }
+          }
+        }
+      }
+    } finally {
+      _currentFunctionType = null;
+    }
+  }
+
+  /// Creates the necessary constraint(s) for an [argumentList] when invoking an
+  /// executable element whose type is [calleeType].
+  ///
+  /// Returns the decorated return type of the invocation, after any necessary
+  /// substitutions.
+  DecoratedType _handleInvocationArguments(
+      AstNode node,
+      Iterable<AstNode> arguments,
+      TypeArgumentList typeArguments,
+      DecoratedType calleeType,
+      List<TypeParameterElement> constructorTypeParameters) {
+    var typeFormals = constructorTypeParameters ?? calleeType.typeFormals;
+    if (typeFormals.isNotEmpty) {
+      if (typeArguments != null) {
+        var argumentTypes = typeArguments.arguments
+            .map((t) => _variables.decoratedTypeAnnotation(_source, t))
+            .toList();
+        if (constructorTypeParameters != null) {
+          calleeType = calleeType.substitute(
+              Map<TypeParameterElement, DecoratedType>.fromIterables(
+                  constructorTypeParameters, argumentTypes));
+        } else {
+          calleeType = calleeType.instantiate(argumentTypes);
+        }
+      } else {
+        _unimplemented(node, 'Inferred type parameters in invocation');
+      }
+    }
+    int i = 0;
+    var suppliedNamedParameters = Set<String>();
+    for (var argument in arguments) {
+      String name;
+      Expression expression;
+      if (argument is NamedExpression) {
+        name = argument.name.label.name;
+        expression = argument.expression;
+      } else if (argument is FormalParameter) {
+        if (argument.isNamed) {
+          name = argument.identifier.name;
+        }
+        expression = argument.identifier;
+      } else {
+        expression = argument;
+      }
+      DecoratedType parameterType;
+      if (name != null) {
+        parameterType = calleeType.namedParameters[name];
+        if (parameterType == null) {
+          // TODO(paulberry)
+          _unimplemented(expression, 'Missing type for named parameter');
+        }
+        suppliedNamedParameters.add(name);
+      } else {
+        if (calleeType.positionalParameters.length <= i) {
+          // TODO(paulberry)
+          _unimplemented(node, 'Missing positional parameter at $i');
+        }
+        parameterType = calleeType.positionalParameters[i++];
+      }
+      _handleAssignment(expression, parameterType);
+    }
+    // Any parameters not supplied must be optional.
+    for (var entry in calleeType.namedParameters.entries) {
+      if (suppliedNamedParameters.contains(entry.key)) continue;
+      entry.value.node.recordNamedParameterNotSupplied(_guards, _graph,
+          NamedParameterNotSuppliedOrigin(_source, node.offset));
+    }
+    return calleeType.returnType;
+  }
+
+  DecoratedType _handlePropertyAccess(
+      Expression node, Expression target, SimpleIdentifier propertyName) {
+    DecoratedType targetType;
+    bool isConditional = _isConditionalExpression(node);
+    if (isConditional) {
+      targetType = target.accept(this);
+    } else {
+      _checkNonObjectMember(propertyName.name); // TODO(paulberry)
+      targetType = _handleAssignment(target, _notNullType);
+    }
+    var callee = propertyName.staticElement;
+    if (callee == null) {
+      // TODO(paulberry)
+      _unimplemented(node, 'Unresolved property access');
+    }
+    var calleeType = getOrComputeElementType(callee, targetType: targetType);
+    // TODO(paulberry): substitute if necessary
+    if (propertyName.inSetterContext()) {
+      if (isConditional) {
+        _lastConditionalNode = targetType.node;
+      }
+      return calleeType.positionalParameters[0];
+    } else {
+      var expressionType = callee is PropertyAccessorElement
+          ? calleeType.returnType
+          : calleeType;
+      if (isConditional) {
+        expressionType = expressionType.withNode(
+            NullabilityNode.forLUB(targetType.node, expressionType.node));
+        _variables.recordDecoratedExpressionType(node, expressionType);
+      }
+      return expressionType;
+    }
+  }
+
+  bool _isConditionalExpression(Expression expression) {
+    Token token;
+    if (expression is MethodInvocation) {
+      token = expression.operator;
+      if (token == null) return false;
+    } else if (expression is PropertyAccess) {
+      token = expression.operator;
+    } else {
+      return false;
+    }
+    switch (token.type) {
+      case TokenType.PERIOD:
+      case TokenType.PERIOD_PERIOD:
+        return false;
+      case TokenType.QUESTION_PERIOD:
+        return true;
+      default:
+        // TODO(paulberry)
+        _unimplemented(
+            expression, 'Conditional expression with operator ${token.lexeme}');
+    }
+  }
+
+  /// Double checks that [type] is sufficiently simple for this naive prototype
+  /// implementation.
+  ///
+  /// TODO(paulberry): get rid of this method and put the correct logic into the
+  /// call sites.
+  bool _isSimple(DecoratedType type) {
+    if (type.type.isBottom) return true;
+    if (type.type.isVoid) return true;
+    if (type.type is TypeParameterType) return true;
+    if (type.type is! InterfaceType) return false;
+    if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
+    return true;
+  }
+
+  bool _isUntypedParameter(NormalFormalParameter parameter) {
+    if (parameter is SimpleFormalParameter) {
+      return parameter.type == null;
+    } else if (parameter is FieldFormalParameter) {
+      return parameter.type == null;
+    } else {
+      return false;
+    }
+  }
+
+  bool _isVariableOrParameterReference(Expression expression) {
+    expression = expression.unParenthesized;
+    if (expression is SimpleIdentifier) {
+      var element = expression.staticElement;
+      if (element is LocalVariableElement) return true;
+      if (element is ParameterElement) return true;
+    }
+    return false;
+  }
+
+  NullabilityNode _nullabilityNodeForGLB(
+      AstNode astNode, NullabilityNode leftNode, NullabilityNode rightNode) {
+    var node = NullabilityNode.forGLB();
+    var origin = GreatestLowerBoundOrigin(_source, astNode.offset);
+    _graph.connect(leftNode, node, origin, guards: [rightNode]);
+    _graph.connect(node, leftNode, origin);
+    _graph.connect(node, rightNode, origin);
+    return node;
+  }
+
+  @alwaysThrows
+  void _unimplemented(AstNode node, String message) {
+    CompilationUnit unit = node.root as CompilationUnit;
+    StringBuffer buffer = StringBuffer();
+    buffer.write(message);
+    buffer.write(' in "');
+    buffer.write(node.toSource());
+    buffer.write('" on line ');
+    buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
+    buffer.write(' of "');
+    buffer.write(unit.declaredElement.source.fullName);
+    buffer.write('"');
+    throw UnimplementedError(buffer.toString());
+  }
+
+  void _unionDecoratedTypeParameters(
+      DecoratedType x, DecoratedType y, EdgeOrigin origin) {
+    for (int i = 0;
+        i < x.positionalParameters.length && i < y.positionalParameters.length;
+        i++) {
+      _unionDecoratedTypes(
+          x.positionalParameters[i], y.positionalParameters[i], origin);
+    }
+    for (var entry in x.namedParameters.entries) {
+      var superParameterType = y.namedParameters[entry.key];
+      if (superParameterType != null) {
+        _unionDecoratedTypes(entry.value, y.namedParameters[entry.key], origin);
+      }
+    }
+  }
+
+  void _unionDecoratedTypes(
+      DecoratedType x, DecoratedType y, EdgeOrigin origin) {
+    _graph.union(x.node, y.node, origin);
+    _unionDecoratedTypeParameters(x, y, origin);
+    for (int i = 0;
+        i < x.typeArguments.length && i < y.typeArguments.length;
+        i++) {
+      _unionDecoratedTypes(x.typeArguments[i], y.typeArguments[i], origin);
+    }
+    if (x.returnType != null && y.returnType != null) {
+      _unionDecoratedTypes(x.returnType, y.returnType, origin);
+    }
+  }
+}
+
+/// Information about a binary expression whose boolean value could possibly
+/// affect nullability analysis.
+class _ConditionInfo {
+  /// The [expression] of interest.
+  final Expression condition;
+
+  /// Indicates whether [condition] is pure (free from side effects).
+  ///
+  /// For example, a condition like `x == null` is pure (assuming `x` is a local
+  /// variable or static variable), because evaluating it has no user-visible
+  /// effect other than returning a boolean value.
+  final bool isPure;
+
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
+  /// order for [condition] to evaluate to `true`.
+  final NullabilityNode trueGuard;
+
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
+  /// order for [condition] to evaluate to `false`.
+  final NullabilityNode falseGuard;
+
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  //  /// non-null intent if [condition] is asserted to be `true`.
+  final NullabilityNode trueDemonstratesNonNullIntent;
+
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  /// non-null intent if [condition] is asserted to be `false`.
+  final NullabilityNode falseDemonstratesNonNullIntent;
+
+  _ConditionInfo(this.condition,
+      {@required this.isPure,
+      this.trueGuard,
+      this.falseGuard,
+      this.trueDemonstratesNonNullIntent,
+      this.falseDemonstratesNonNullIntent});
+
+  /// Returns a new [_ConditionInfo] describing the boolean "not" of `this`.
+  _ConditionInfo not(Expression condition) => _ConditionInfo(condition,
+      isPure: isPure,
+      trueGuard: falseGuard,
+      falseGuard: trueGuard,
+      trueDemonstratesNonNullIntent: falseDemonstratesNonNullIntent,
+      falseDemonstratesNonNullIntent: trueDemonstratesNonNullIntent);
+}
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 487edc1..db1c8c5 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -34,6 +34,58 @@
   EdgeOriginWithLocation(this.source, this.offset);
 }
 
+/// Edge origin resulting from the relationship between a field formal parameter
+/// and the corresponding field.
+class FieldFormalParameterOrigin extends EdgeOriginWithLocation {
+  FieldFormalParameterOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from the use of greatest lower bound.
+///
+/// For example, in the following code snippet:
+///   void Function(int) f(void Function(int) x, void Function(int) y)
+///       => x ?? y;
+///
+/// the `int` in the return type is nullable if both the `int`s in the types of
+/// `x` and `y` are nullable, due to the fact that the `int` in the return type
+/// is the greatest lower bound of the two other `int`s.
+class GreatestLowerBoundOrigin extends EdgeOriginWithLocation {
+  GreatestLowerBoundOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from the presence of a `??` operator.
+class IfNullOrigin extends EdgeOriginWithLocation {
+  IfNullOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from the implicit call from a mixin application
+/// constructor to the corresponding super constructor.
+///
+/// For example, in the following code snippet:
+///   class C {
+///     C(int i);
+///   }
+///   mixin M {}
+///   class D = C with M;
+///
+/// this class is used for the edge connecting the types of the `i` parameters
+/// between the implicit constructor for `D` and the explicit constructor for
+/// `C`.
+class ImplicitMixinSuperCallOrigin extends EdgeOriginWithLocation {
+  ImplicitMixinSuperCallOrigin(Source source, int offset)
+      : super(source, offset);
+}
+
+/// Edge origin resulting from an inheritance relationship between two methods.
+class InheritanceOrigin extends EdgeOriginWithLocation {
+  InheritanceOrigin(Source source, int offset) : super(source, offset);
+}
+
+/// Edge origin resulting from a type that is inferred from its initializer.
+class InitializerInferenceOrigin extends EdgeOriginWithLocation {
+  InitializerInferenceOrigin(Source source, int offset) : super(source, offset);
+}
+
 /// Edge origin resulting from a class that is instantiated to bounds.
 ///
 /// For example, in the following code snippet:
diff --git a/pkg/nnbd_migration/lib/src/graph_builder.dart b/pkg/nnbd_migration/lib/src/graph_builder.dart
deleted file mode 100644
index 6f99c8a..0000000
--- a/pkg/nnbd_migration/lib/src/graph_builder.dart
+++ /dev/null
@@ -1,980 +0,0 @@
-// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:meta/meta.dart';
-import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:nnbd_migration/src/conditional_discard.dart';
-import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/edge_origin.dart';
-import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
-
-/// Visitor that builds nullability graph edges by examining code to be
-/// migrated.
-///
-/// The return type of each `visit...` method is a [DecoratedType] indicating
-/// the static type of the visited expression, along with the constraint
-/// variables that will determine its nullability.  For `visit...` methods that
-/// don't visit expressions, `null` will be returned.
-class GraphBuilder extends GeneralizingAstVisitor<DecoratedType> {
-  /// The repository of constraint variables and decorated types (from a
-  /// previous pass over the source code).
-  final VariableRepository _variables;
-
-  final NullabilityMigrationListener /*?*/ listener;
-
-  final NullabilityGraph _graph;
-
-  /// The file being analyzed.
-  final Source _source;
-
-  /// For convenience, a [DecoratedType] representing non-nullable `Object`.
-  final DecoratedType _notNullType;
-
-  /// For convenience, a [DecoratedType] representing non-nullable `bool`.
-  final DecoratedType _nonNullableBoolType;
-
-  /// For convenience, a [DecoratedType] representing non-nullable `Type`.
-  final DecoratedType _nonNullableTypeType;
-
-  /// For convenience, a [DecoratedType] representing `Null`.
-  final DecoratedType _nullType;
-
-  /// The [DecoratedType] of the innermost function or method being visited, or
-  /// `null` if the visitor is not inside any function or method.
-  ///
-  /// This is needed to construct the appropriate nullability constraints for
-  /// return statements.
-  DecoratedType _currentFunctionType;
-
-  /// Information about the most recently visited binary expression whose
-  /// boolean value could possibly affect nullability analysis.
-  _ConditionInfo _conditionInfo;
-
-  /// The set of nullability nodes that would have to be `nullable` for the code
-  /// currently being visited to be reachable.
-  ///
-  /// Guard variables are attached to the left hand side of any generated
-  /// constraints, so that constraints do not take effect if they come from
-  /// code that can be proven unreachable by the migration tool.
-  final _guards = <NullabilityNode>[];
-
-  /// Indicates whether the statement or expression being visited is within
-  /// conditional control flow.  If `true`, this means that the enclosing
-  /// function might complete normally without executing the current statement
-  /// or expression.
-  bool _inConditionalControlFlow = false;
-
-  NullabilityNode _lastConditionalNode;
-
-  GraphBuilder(TypeProvider typeProvider, this._variables, this._graph,
-      this._source, this.listener)
-      : _notNullType = DecoratedType(typeProvider.objectType, _graph.never),
-        _nonNullableBoolType =
-            DecoratedType(typeProvider.boolType, _graph.never),
-        _nonNullableTypeType =
-            DecoratedType(typeProvider.typeType, _graph.never),
-        _nullType = DecoratedType(typeProvider.nullType, _graph.always);
-
-  /// Gets the decorated type of [element] from [_variables], performing any
-  /// necessary substitutions.
-  DecoratedType getOrComputeElementType(Element element,
-      {DecoratedType targetType}) {
-    Map<TypeParameterElement, DecoratedType> substitution;
-    Element baseElement;
-    if (element is Member) {
-      assert(targetType != null);
-      baseElement = element.baseElement;
-      var targetTypeType = targetType.type;
-      if (targetTypeType is InterfaceType &&
-          baseElement is ClassMemberElement) {
-        var enclosingClass = baseElement.enclosingElement;
-        assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
-        substitution = <TypeParameterElement, DecoratedType>{};
-        assert(enclosingClass.typeParameters.length ==
-            targetTypeType.typeArguments.length); // TODO(paulberry)
-        for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
-          substitution[enclosingClass.typeParameters[i]] =
-              targetType.typeArguments[i];
-        }
-      }
-    } else {
-      baseElement = element;
-    }
-    DecoratedType decoratedBaseType;
-    if (baseElement is PropertyAccessorElement &&
-        baseElement.isSynthetic &&
-        !baseElement.variable.isSynthetic) {
-      var variable = baseElement.variable;
-      var decoratedElementType =
-          _variables.decoratedElementType(variable, create: true);
-      if (baseElement.isGetter) {
-        decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
-            returnType: decoratedElementType);
-      } else {
-        assert(baseElement.isSetter);
-        decoratedBaseType = DecoratedType(baseElement.type, _graph.never,
-            positionalParameters: [decoratedElementType]);
-      }
-    } else {
-      decoratedBaseType =
-          _variables.decoratedElementType(baseElement, create: true);
-    }
-    if (substitution != null) {
-      DartType elementType;
-      if (element is MethodElement) {
-        elementType = element.type;
-      } else {
-        throw element.runtimeType; // TODO(paulberry)
-      }
-      return decoratedBaseType.substitute(substitution, elementType);
-    } else {
-      return decoratedBaseType;
-    }
-  }
-
-  @override
-  DecoratedType visitAsExpression(AsExpression node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'AsExpression');
-  }
-
-  @override
-  DecoratedType visitAssertStatement(AssertStatement node) {
-    _handleAssignment(_notNullType, node.condition);
-    if (identical(_conditionInfo?.condition, node.condition)) {
-      if (!_inConditionalControlFlow &&
-          _conditionInfo.trueDemonstratesNonNullIntent != null) {
-        _graph.connect(_conditionInfo.trueDemonstratesNonNullIntent,
-            _graph.never, NonNullAssertionOrigin(_source, node.offset),
-            hard: true);
-      }
-    }
-    node.message?.accept(this);
-    return null;
-  }
-
-  @override
-  DecoratedType visitAssignmentExpression(AssignmentExpression node) {
-    if (node.operator.type != TokenType.EQ) {
-      // TODO(paulberry)
-      _unimplemented(node, 'Assignment with operator ${node.operator.lexeme}');
-    }
-    var leftType = node.leftHandSide.accept(this);
-    var conditionalNode = _lastConditionalNode;
-    _lastConditionalNode = null;
-    var expressionType = _handleAssignment(leftType, node.rightHandSide);
-    if (_isConditionalExpression(node.leftHandSide)) {
-      expressionType = expressionType.withNode(
-          NullabilityNode.forLUB(conditionalNode, expressionType.node));
-      _variables.recordDecoratedExpressionType(node, expressionType);
-    }
-    return expressionType;
-  }
-
-  @override
-  DecoratedType visitAwaitExpression(AwaitExpression node) {
-    var expressionType = node.expression.accept(this);
-    // TODO(paulberry) Handle subclasses of Future.
-    if (expressionType.type.isDartAsyncFuture ||
-        expressionType.type.isDartAsyncFutureOr) {
-      expressionType = expressionType.typeArguments[0];
-    }
-    return expressionType;
-  }
-
-  @override
-  DecoratedType visitBinaryExpression(BinaryExpression node) {
-    var operatorType = node.operator.type;
-    if (operatorType == TokenType.EQ_EQ || operatorType == TokenType.BANG_EQ) {
-      assert(node.leftOperand is! NullLiteral); // TODO(paulberry)
-      var leftType = node.leftOperand.accept(this);
-      node.rightOperand.accept(this);
-      if (node.rightOperand is NullLiteral) {
-        // TODO(paulberry): figure out what the rules for isPure should be.
-        // TODO(paulberry): only set falseChecksNonNull in unconditional
-        // control flow
-        bool isPure = node.leftOperand is SimpleIdentifier;
-        var conditionInfo = _ConditionInfo(node,
-            isPure: isPure,
-            trueGuard: leftType.node,
-            falseDemonstratesNonNullIntent: leftType.node);
-        _conditionInfo = operatorType == TokenType.EQ_EQ
-            ? conditionInfo
-            : conditionInfo.not(node);
-      }
-      return _nonNullableBoolType;
-    } else if (operatorType.isUserDefinableOperator) {
-      _handleAssignment(_notNullType, node.leftOperand);
-      var callee = node.staticElement;
-      assert(!(callee is ClassMemberElement &&
-          callee
-              .enclosingElement.typeParameters.isNotEmpty)); // TODO(paulberry)
-      assert(callee != null); // TODO(paulberry)
-      var calleeType = getOrComputeElementType(callee);
-      // TODO(paulberry): substitute if necessary
-      assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
-      _handleAssignment(calleeType.positionalParameters[0], node.rightOperand);
-      return calleeType.returnType;
-    } else {
-      // TODO(paulberry)
-      _unimplemented(
-          node, 'Binary expression with operator ${node.operator.lexeme}');
-    }
-  }
-
-  @override
-  DecoratedType visitBooleanLiteral(BooleanLiteral node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitCascadeExpression(CascadeExpression node) {
-    var type = node.target.accept(this);
-    node.cascadeSections.accept(this);
-    return type;
-  }
-
-  @override
-  DecoratedType visitClassDeclaration(ClassDeclaration node) {
-    node.members.accept(this);
-    return null;
-  }
-
-  @override
-  DecoratedType visitConditionalExpression(ConditionalExpression node) {
-    _handleAssignment(_notNullType, node.condition);
-    // TODO(paulberry): guard anything inside the true and false branches
-    var thenType = node.thenExpression.accept(this);
-    assert(_isSimple(thenType)); // TODO(paulberry)
-    var elseType = node.elseExpression.accept(this);
-    assert(_isSimple(elseType)); // TODO(paulberry)
-    var overallType = DecoratedType(
-        node.staticType, NullabilityNode.forLUB(thenType.node, elseType.node));
-    _variables.recordDecoratedExpressionType(node, overallType);
-    return overallType;
-  }
-
-  @override
-  DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
-    var defaultValue = node.defaultValue;
-    if (defaultValue == null) {
-      if (node.declaredElement.hasRequired) {
-        // Nothing to do; the implicit default value of `null` will never be
-        // reached.
-      } else {
-        _graph.connect(
-            _graph.always,
-            getOrComputeElementType(node.declaredElement).node,
-            OptionalFormalParameterOrigin(_source, node.offset),
-            guards: _guards);
-      }
-    } else {
-      _handleAssignment(
-          getOrComputeElementType(node.declaredElement), defaultValue,
-          canInsertChecks: false);
-    }
-    return null;
-  }
-
-  @override
-  DecoratedType visitDoubleLiteral(DoubleLiteral node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _handleAssignment(_currentFunctionType.returnType, node.expression);
-    return null;
-  }
-
-  @override
-  DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
-    node.functionExpression.parameters?.accept(this);
-    assert(_currentFunctionType == null);
-    _currentFunctionType =
-        _variables.decoratedElementType(node.declaredElement);
-    _inConditionalControlFlow = false;
-    try {
-      node.functionExpression.body.accept(this);
-    } finally {
-      _currentFunctionType = null;
-    }
-    return null;
-  }
-
-  @override
-  DecoratedType visitFunctionExpression(FunctionExpression node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'FunctionExpression');
-  }
-
-  @override
-  DecoratedType visitFunctionExpressionInvocation(
-      FunctionExpressionInvocation node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'FunctionExpressionInvocation');
-  }
-
-  @override
-  DecoratedType visitIfStatement(IfStatement node) {
-    // TODO(paulberry): should the use of a boolean in an if-statement be
-    // treated like an implicit `assert(b != null)`?  Probably.
-    _handleAssignment(_notNullType, node.condition);
-    _inConditionalControlFlow = true;
-    NullabilityNode trueGuard;
-    NullabilityNode falseGuard;
-    if (identical(_conditionInfo?.condition, node.condition)) {
-      trueGuard = _conditionInfo.trueGuard;
-      falseGuard = _conditionInfo.falseGuard;
-      _variables.recordConditionalDiscard(_source, node,
-          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
-    }
-    if (trueGuard != null) {
-      _guards.add(trueGuard);
-    }
-    try {
-      node.thenStatement.accept(this);
-    } finally {
-      if (trueGuard != null) {
-        _guards.removeLast();
-      }
-    }
-    if (falseGuard != null) {
-      _guards.add(falseGuard);
-    }
-    try {
-      node.elseStatement?.accept(this);
-    } finally {
-      if (falseGuard != null) {
-        _guards.removeLast();
-      }
-    }
-    return null;
-  }
-
-  @override
-  DecoratedType visitIndexExpression(IndexExpression node) {
-    DecoratedType targetType;
-    var target = node.realTarget;
-    if (target != null) {
-      targetType = _handleAssignment(_notNullType, target);
-    }
-    var callee = node.staticElement;
-    if (callee == null) {
-      // TODO(paulberry)
-      _unimplemented(node, 'Index expression with no static type');
-    }
-    var calleeType = getOrComputeElementType(callee, targetType: targetType);
-    // TODO(paulberry): substitute if necessary
-    _handleAssignment(calleeType.positionalParameters[0], node.index);
-    if (node.inSetterContext()) {
-      return calleeType.positionalParameters[1];
-    } else {
-      return calleeType.returnType;
-    }
-  }
-
-  @override
-  DecoratedType visitInstanceCreationExpression(
-      InstanceCreationExpression node) {
-    var callee = node.staticElement;
-    var calleeType = getOrComputeElementType(callee);
-    if (callee.enclosingElement.typeParameters.isNotEmpty) {
-      // If the class has type parameters then we might need to substitute the
-      // appropriate type arguments.
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Instance creation expression with type arguments');
-    }
-    _handleInvocationArguments(node.argumentList, calleeType);
-    return calleeType.returnType;
-  }
-
-  @override
-  DecoratedType visitIntegerLiteral(IntegerLiteral node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitIsExpression(IsExpression node) {
-    var type = node.type;
-    if (type is NamedType && type.typeArguments != null) {
-      // TODO(brianwilkerson) Figure out what constraints we need to add to
-      //  allow the tool to decide whether to make the type arguments nullable.
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Is expression with type arguments');
-    } else if (type is GenericFunctionType) {
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Is expression with GenericFunctionType');
-    }
-    node.visitChildren(this);
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitListLiteral(ListLiteral node) {
-    var listType = node.staticType as InterfaceType;
-    if (node.typeArguments == null) {
-      // TODO(brianwilkerson) We might want to create a fake node in the graph
-      //  to represent the type argument so that we can still create edges from
-      //  the elements to it.
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'List literal with no type arguments');
-    } else {
-      var typeArgumentType = _variables.decoratedTypeAnnotation(
-          _source, node.typeArguments.arguments[0]);
-      for (var element in node.elements) {
-        if (element is Expression) {
-          _handleAssignment(typeArgumentType, element);
-        } else {
-          // Handle spread and control flow elements.
-          element.accept(this);
-          // TODO(brianwilkerson)
-          _unimplemented(node, 'Spread or control flow element');
-        }
-      }
-      return DecoratedType(listType, _graph.never,
-          typeArguments: [typeArgumentType]);
-    }
-  }
-
-  @override
-  DecoratedType visitMethodDeclaration(MethodDeclaration node) {
-    node.parameters?.accept(this);
-    assert(_currentFunctionType == null);
-    _currentFunctionType =
-        _variables.decoratedElementType(node.declaredElement);
-    _inConditionalControlFlow = false;
-    try {
-      node.body.accept(this);
-    } finally {
-      _currentFunctionType = null;
-    }
-    return null;
-  }
-
-  @override
-  DecoratedType visitMethodInvocation(MethodInvocation node) {
-    DecoratedType targetType;
-    var target = node.realTarget;
-    bool isConditional = _isConditionalExpression(node);
-    if (target != null) {
-      if (isConditional) {
-        targetType = target.accept(this);
-      } else {
-        _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
-        targetType = _handleAssignment(_notNullType, target);
-      }
-    }
-    var callee = node.methodName.staticElement;
-    if (callee == null) {
-      // TODO(paulberry)
-      _unimplemented(node, 'Unresolved method name');
-    }
-    var calleeType = getOrComputeElementType(callee, targetType: targetType);
-    // TODO(paulberry): substitute if necessary
-    _handleInvocationArguments(node.argumentList, calleeType);
-    var expressionType = calleeType.returnType;
-    if (isConditional) {
-      expressionType = expressionType.withNode(
-          NullabilityNode.forLUB(targetType.node, expressionType.node));
-      _variables.recordDecoratedExpressionType(node, expressionType);
-    }
-    return expressionType;
-  }
-
-  @override
-  DecoratedType visitNamespaceDirective(NamespaceDirective node) {
-    // skip directives
-    return null;
-  }
-
-  @override
-  DecoratedType visitNode(AstNode node) {
-    if (listener != null) {
-      try {
-        return super.visitNode(node);
-      } catch (exception, stackTrace) {
-        listener.addDetail('''
-$exception
-
-$stackTrace''');
-        return null;
-      }
-    } else {
-      return super.visitNode(node);
-    }
-  }
-
-  @override
-  DecoratedType visitNullLiteral(NullLiteral node) {
-    return _nullType;
-  }
-
-  @override
-  DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
-    return node.expression.accept(this);
-  }
-
-  @override
-  DecoratedType visitPostfixExpression(PostfixExpression node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'PostfixExpression');
-  }
-
-  @override
-  DecoratedType visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (node.prefix.staticElement is ImportElement) {
-      // TODO(paulberry)
-      _unimplemented(node, 'PrefixedIdentifier with a prefix');
-    } else {
-      return _handlePropertyAccess(node, node.prefix, node.identifier);
-    }
-  }
-
-  @override
-  DecoratedType visitPrefixExpression(PrefixExpression node) {
-    /* DecoratedType operandType = */
-    _handleAssignment(_notNullType, node.operand);
-    if (node.operator.type == TokenType.BANG) {
-      return _nonNullableBoolType;
-    }
-    // TODO(brianwilkerson) The remaining cases are invocations.
-    _unimplemented(
-        node, 'Prefix expression with operator ${node.operator.lexeme}');
-  }
-
-  @override
-  DecoratedType visitPropertyAccess(PropertyAccess node) {
-    return _handlePropertyAccess(node, node.realTarget, node.propertyName);
-  }
-
-  @override
-  DecoratedType visitReturnStatement(ReturnStatement node) {
-    if (node.expression == null) {
-      _checkAssignment(_currentFunctionType.returnType, _nullType, null,
-          hard: false);
-    } else {
-      _handleAssignment(_currentFunctionType.returnType, node.expression);
-    }
-    return null;
-  }
-
-  @override
-  DecoratedType visitSetOrMapLiteral(SetOrMapLiteral node) {
-    var listType = node.staticType as InterfaceType;
-    var typeArguments = node.typeArguments?.arguments;
-    if (typeArguments == null) {
-      // TODO(brianwilkerson) We might want to create fake nodes in the graph to
-      //  represent the type arguments so that we can still create edges from
-      //  the elements to them.
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Set or map literal with no type arguments');
-    } else if (typeArguments.length == 1) {
-      var elementType =
-          _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
-      for (var element in node.elements) {
-        if (element is Expression) {
-          _handleAssignment(elementType, element);
-        } else {
-          // Handle spread and control flow elements.
-          element.accept(this);
-          // TODO(brianwilkerson)
-          _unimplemented(node, 'Spread or control flow element');
-        }
-      }
-      return DecoratedType(listType, _graph.never,
-          typeArguments: [elementType]);
-    } else if (typeArguments.length == 2) {
-      var keyType =
-          _variables.decoratedTypeAnnotation(_source, typeArguments[0]);
-      var valueType =
-          _variables.decoratedTypeAnnotation(_source, typeArguments[1]);
-      for (var element in node.elements) {
-        if (element is MapLiteralEntry) {
-          _handleAssignment(keyType, element.key);
-          _handleAssignment(valueType, element.value);
-        } else {
-          // Handle spread and control flow elements.
-          element.accept(this);
-          // TODO(brianwilkerson)
-          _unimplemented(node, 'Spread or control flow element');
-        }
-      }
-      return DecoratedType(listType, _graph.never,
-          typeArguments: [keyType, valueType]);
-    } else {
-      // TODO(brianwilkerson)
-      _unimplemented(
-          node, 'Set or map literal with more than two type arguments');
-    }
-  }
-
-  @override
-  DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
-    var staticElement = node.staticElement;
-    if (staticElement is ParameterElement ||
-        staticElement is LocalVariableElement) {
-      return getOrComputeElementType(staticElement);
-    } else if (staticElement is PropertyAccessorElement) {
-      // TODO(danrubel): assuming getter context... need to handle setter
-      return getOrComputeElementType(staticElement).returnType;
-    } else if (staticElement is ClassElement) {
-      return _nonNullableTypeType;
-    } else {
-      // TODO(paulberry)
-      _unimplemented(node,
-          'Simple identifier with a static element of type ${staticElement.runtimeType}');
-    }
-  }
-
-  @override
-  DecoratedType visitStringLiteral(StringLiteral node) {
-    node.visitChildren(this);
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitSuperExpression(SuperExpression node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitSymbolLiteral(SymbolLiteral node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitThisExpression(ThisExpression node) {
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitThrowExpression(ThrowExpression node) {
-    node.expression.accept(this);
-    // TODO(paulberry): do we need to check the expression type?  I think not.
-    return DecoratedType(node.staticType, _graph.never);
-  }
-
-  @override
-  DecoratedType visitTypeName(TypeName typeName) {
-    var typeArguments = typeName.typeArguments?.arguments;
-    var element = typeName.name.staticElement;
-    if (element is TypeParameterizedElement) {
-      if (typeArguments == null) {
-        var instantiatedType =
-            _variables.decoratedTypeAnnotation(_source, typeName);
-        if (instantiatedType == null) {
-          throw new StateError('No type annotation for type name '
-              '${typeName.toSource()}, offset=${typeName.offset}');
-        }
-        var origin = InstantiateToBoundsOrigin(_source, typeName.offset);
-        for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
-          _unionDecoratedTypes(
-              instantiatedType.typeArguments[i],
-              _variables.decoratedElementType(element.typeParameters[i],
-                  create: true),
-              origin);
-        }
-      } else {
-        for (int i = 0; i < typeArguments.length; i++) {
-          DecoratedType bound;
-          bound = _variables.decoratedElementType(element.typeParameters[i],
-              create: true);
-          _checkAssignment(
-              bound,
-              _variables.decoratedTypeAnnotation(_source, typeArguments[i]),
-              null,
-              hard: true);
-        }
-      }
-    }
-    return _nonNullableTypeType;
-  }
-
-  @override
-  DecoratedType visitVariableDeclaration(VariableDeclaration node) {
-    var destinationType = getOrComputeElementType(node.declaredElement);
-    var initializer = node.initializer;
-    if (initializer == null) {
-      // TODO(paulberry)
-      _unimplemented(node, 'Variable declaration with no initializer');
-    } else {
-      _handleAssignment(destinationType, initializer);
-    }
-    return null;
-  }
-
-  /// Creates the necessary constraint(s) for an assignment from [sourceType] to
-  /// [destinationType].  [expressionChecks] tracks checks that might have to be
-  /// done on the type of an expression.  [hard] indicates whether a hard edge
-  /// should be created.
-  void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
-      ExpressionChecks expressionChecks,
-      {@required bool hard}) {
-    var edge = _graph.connect(
-        sourceType.node, destinationType.node, expressionChecks,
-        guards: _guards, hard: hard);
-    expressionChecks?.edges?.add(edge);
-    // TODO(paulberry): generalize this.
-
-    if ((_isSimple(sourceType) || destinationType.type.isObject) &&
-        _isSimple(destinationType)) {
-      // Ok; nothing further to do.
-      return;
-    }
-
-    if (sourceType.type is InterfaceType &&
-        destinationType.type is InterfaceType &&
-        sourceType.type.element == destinationType.type.element) {
-      assert(sourceType.typeArguments.length ==
-          destinationType.typeArguments.length);
-      for (int i = 0; i < sourceType.typeArguments.length; i++) {
-        _checkAssignment(destinationType.typeArguments[i],
-            sourceType.typeArguments[i], expressionChecks,
-            hard: false);
-      }
-      return;
-    }
-
-    if (destinationType.type.isDynamic || sourceType.type.isDynamic) {
-      // ok; nothing further to do.
-      return;
-    }
-
-    // TODO(paulberry)
-    throw '$destinationType <= $sourceType';
-  }
-
-  /// Double checks that [name] is not the name of a method or getter declared
-  /// on [Object].
-  ///
-  /// TODO(paulberry): get rid of this method and put the correct logic into the
-  /// call sites.
-  void _checkNonObjectMember(String name) {
-    assert(name != 'toString');
-    assert(name != 'hashCode');
-    assert(name != 'noSuchMethod');
-    assert(name != 'runtimeType');
-  }
-
-  /// Creates the necessary constraint(s) for an assignment of the given
-  /// [expression] to a destination whose type is [destinationType].
-  DecoratedType _handleAssignment(
-      DecoratedType destinationType, Expression expression,
-      {bool canInsertChecks = true}) {
-    var sourceType = expression.accept(this);
-    if (sourceType == null) {
-      throw StateError('No type computed for ${expression.runtimeType} '
-          '(${expression.toSource()}) offset=${expression.offset}');
-    }
-    ExpressionChecks expressionChecks;
-    if (canInsertChecks) {
-      expressionChecks = ExpressionChecks(expression.end);
-      _variables.recordExpressionChecks(_source, expression, expressionChecks);
-    }
-    _checkAssignment(destinationType, sourceType, expressionChecks,
-        hard: _isVariableOrParameterReference(expression) &&
-            !_inConditionalControlFlow);
-    return sourceType;
-  }
-
-  /// Creates the necessary constraint(s) for an [argumentList] when invoking an
-  /// executable element whose type is [calleeType].
-  void _handleInvocationArguments(
-      ArgumentList argumentList, DecoratedType calleeType) {
-    var arguments = argumentList.arguments;
-    int i = 0;
-    var suppliedNamedParameters = Set<String>();
-    for (var expression in arguments) {
-      if (expression is NamedExpression) {
-        var name = expression.name.label.name;
-        var parameterType = calleeType.namedParameters[name];
-        if (parameterType == null) {
-          // TODO(paulberry)
-          _unimplemented(expression, 'Missing type for named parameter');
-        }
-        _handleAssignment(parameterType, expression.expression);
-        suppliedNamedParameters.add(name);
-      } else {
-        if (calleeType.positionalParameters.length <= i) {
-          // TODO(paulberry)
-          _unimplemented(argumentList, 'Missing positional parameter at $i');
-        }
-        _handleAssignment(calleeType.positionalParameters[i++], expression);
-      }
-    }
-    // Any parameters not supplied must be optional.
-    for (var entry in calleeType.namedParameters.entries) {
-      if (suppliedNamedParameters.contains(entry.key)) continue;
-      entry.value.node.recordNamedParameterNotSupplied(_guards, _graph,
-          NamedParameterNotSuppliedOrigin(_source, argumentList.offset));
-    }
-  }
-
-  DecoratedType _handlePropertyAccess(
-      Expression node, Expression target, SimpleIdentifier propertyName) {
-    DecoratedType targetType;
-    bool isConditional = _isConditionalExpression(node);
-    if (isConditional) {
-      targetType = target.accept(this);
-    } else {
-      _checkNonObjectMember(propertyName.name); // TODO(paulberry)
-      targetType = _handleAssignment(_notNullType, target);
-    }
-    var callee = propertyName.staticElement;
-    if (callee == null) {
-      // TODO(paulberry)
-      _unimplemented(node, 'Unresolved property access');
-    }
-    var calleeType = getOrComputeElementType(callee, targetType: targetType);
-    // TODO(paulberry): substitute if necessary
-    if (propertyName.inSetterContext()) {
-      if (isConditional) {
-        _lastConditionalNode = targetType.node;
-      }
-      return calleeType.positionalParameters[0];
-    } else {
-      var expressionType = calleeType.returnType;
-      if (isConditional) {
-        expressionType = expressionType.withNode(
-            NullabilityNode.forLUB(targetType.node, expressionType.node));
-        _variables.recordDecoratedExpressionType(node, expressionType);
-      }
-      return expressionType;
-    }
-  }
-
-  bool _isConditionalExpression(Expression expression) {
-    Token token;
-    if (expression is MethodInvocation) {
-      token = expression.operator;
-      if (token == null) return false;
-    } else if (expression is PropertyAccess) {
-      token = expression.operator;
-    } else {
-      return false;
-    }
-    switch (token.type) {
-      case TokenType.PERIOD:
-      case TokenType.PERIOD_PERIOD:
-        return false;
-      case TokenType.QUESTION_PERIOD:
-        return true;
-      default:
-        // TODO(paulberry)
-        _unimplemented(
-            expression, 'Conditional expression with operator ${token.lexeme}');
-    }
-  }
-
-  /// Double checks that [type] is sufficiently simple for this naive prototype
-  /// implementation.
-  ///
-  /// TODO(paulberry): get rid of this method and put the correct logic into the
-  /// call sites.
-  bool _isSimple(DecoratedType type) {
-    if (type.type.isBottom) return true;
-    if (type.type.isVoid) return true;
-    if (type.type is TypeParameterType) return true;
-    if (type.type is! InterfaceType) return false;
-    if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
-    return true;
-  }
-
-  bool _isVariableOrParameterReference(Expression expression) {
-    expression = expression.unParenthesized;
-    if (expression is SimpleIdentifier) {
-      var element = expression.staticElement;
-      if (element is LocalVariableElement) return true;
-      if (element is ParameterElement) return true;
-    }
-    return false;
-  }
-
-  @alwaysThrows
-  void _unimplemented(AstNode node, String message) {
-    CompilationUnit unit = node.root as CompilationUnit;
-    StringBuffer buffer = StringBuffer();
-    buffer.write(message);
-    buffer.write(' in "');
-    buffer.write(node.toSource());
-    buffer.write('" on line ');
-    buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
-    buffer.write(' of "');
-    buffer.write(unit.declaredElement.source.fullName);
-    buffer.write('"');
-    throw UnimplementedError(buffer.toString());
-  }
-
-  void _unionDecoratedTypes(
-      DecoratedType x, DecoratedType y, EdgeOrigin origin) {
-    _graph.union(x.node, y.node, origin);
-    if (x.typeArguments.isNotEmpty ||
-        y.typeArguments.isNotEmpty ||
-        x.returnType != null ||
-        y.returnType != null ||
-        x.positionalParameters.isNotEmpty ||
-        y.positionalParameters.isNotEmpty ||
-        x.namedParameters.isNotEmpty ||
-        y.namedParameters.isNotEmpty) {
-      // TODO(paulberry)
-      throw UnimplementedError('_unionDecoratedTypes($x, $y, $origin)');
-    }
-  }
-}
-
-/// Information about a binary expression whose boolean value could possibly
-/// affect nullability analysis.
-class _ConditionInfo {
-  /// The [expression] of interest.
-  final Expression condition;
-
-  /// Indicates whether [condition] is pure (free from side effects).
-  ///
-  /// For example, a condition like `x == null` is pure (assuming `x` is a local
-  /// variable or static variable), because evaluating it has no user-visible
-  /// effect other than returning a boolean value.
-  final bool isPure;
-
-  /// If not `null`, the [NullabilityNode] that would need to be nullable in
-  /// order for [condition] to evaluate to `true`.
-  final NullabilityNode trueGuard;
-
-  /// If not `null`, the [NullabilityNode] that would need to be nullable in
-  /// order for [condition] to evaluate to `false`.
-  final NullabilityNode falseGuard;
-
-  /// If not `null`, the [NullabilityNode] that should be asserted to have
-  //  /// non-null intent if [condition] is asserted to be `true`.
-  final NullabilityNode trueDemonstratesNonNullIntent;
-
-  /// If not `null`, the [NullabilityNode] that should be asserted to have
-  /// non-null intent if [condition] is asserted to be `false`.
-  final NullabilityNode falseDemonstratesNonNullIntent;
-
-  _ConditionInfo(this.condition,
-      {@required this.isPure,
-      this.trueGuard,
-      this.falseGuard,
-      this.trueDemonstratesNonNullIntent,
-      this.falseDemonstratesNonNullIntent});
-
-  /// Returns a new [_ConditionInfo] describing the boolean "not" of `this`.
-  _ConditionInfo not(Expression condition) => _ConditionInfo(condition,
-      isPure: isPure,
-      trueGuard: falseGuard,
-      falseGuard: trueGuard,
-      trueDemonstratesNonNullIntent: falseDemonstratesNonNullIntent,
-      falseDemonstratesNonNullIntent: trueDemonstratesNonNullIntent);
-}
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index 202fe0a..43c9143 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -48,40 +49,107 @@
 
   final TypeProvider _typeProvider;
 
-  NodeBuilder(this._variables, this._source, this.listener, this._graph,
-      this._typeProvider);
+  /// For convenience, a [DecoratedType] representing non-nullable `Object`.
+  final DecoratedType _nonNullableObjectType;
 
-  /// Creates and stores a [DecoratedType] object corresponding to the given
-  /// [type] AST, and returns it.
-  DecoratedType decorateType(TypeAnnotation type, AstNode enclosingNode) {
-    return type == null
-        // TODO(danrubel): Return something other than this
-        // to indicate that we should insert a type for the declaration
-        // that is missing a type reference.
-        ? new DecoratedType(
-            DynamicTypeImpl.instance,
-            NullabilityNode.forInferredDynamicType(
-                _graph, _source, enclosingNode.offset))
-        : type.accept(this);
+  NodeBuilder(this._variables, this._source, this.listener, this._graph,
+      this._typeProvider)
+      : _nonNullableObjectType =
+            DecoratedType(_typeProvider.objectType, _graph.never);
+
+  @override
+  DecoratedType visitCatchClause(CatchClause node) {
+    DecoratedType exceptionType = node.exceptionType?.accept(this);
+    if (node.exceptionParameter != null) {
+      exceptionType ??= DecoratedType(_typeProvider.objectType, _graph.never);
+      _variables.recordDecoratedElementType(
+          node.exceptionParameter.staticElement, exceptionType);
+    }
+    node.stackTraceParameter?.accept(this);
+    node.body?.accept(this);
+    return null;
+  }
+
+  @override
+  DecoratedType visitClassDeclaration(ClassDeclaration node) {
+    node.metadata.accept(this);
+    node.name.accept(this);
+    node.typeParameters?.accept(this);
+    node.nativeClause?.accept(this);
+    node.members.accept(this);
+    var classElement = node.declaredElement;
+    _handleSupertypeClauses(classElement, node.extendsClause?.superclass,
+        node.withClause, node.implementsClause, null);
+    var constructors = classElement.constructors;
+    if (constructors.length == 1) {
+      var constructorElement = constructors[0];
+      if (constructorElement.isSynthetic) {
+        // Need to create a decorated type for the default constructor.
+        var decoratedReturnType =
+            _createDecoratedTypeForClass(classElement, node);
+        var functionType = DecoratedType(constructorElement.type, _graph.never,
+            returnType: decoratedReturnType,
+            positionalParameters: [],
+            namedParameters: {});
+        _variables.recordDecoratedElementType(constructorElement, functionType);
+      }
+    }
+    return null;
+  }
+
+  @override
+  visitClassTypeAlias(ClassTypeAlias node) {
+    node.metadata.accept(this);
+    node.name.accept(this);
+    node.typeParameters?.accept(this);
+    var classElement = node.declaredElement;
+    _handleSupertypeClauses(classElement, node.superclass, node.withClause,
+        node.implementsClause, null);
+    for (var constructorElement in classElement.constructors) {
+      assert(constructorElement.isSynthetic);
+      var decoratedReturnType =
+          _createDecoratedTypeForClass(classElement, node);
+      var functionType = DecoratedType.forImplicitFunction(
+          constructorElement.type, _graph.never, _graph,
+          returnType: decoratedReturnType);
+      _variables.recordDecoratedElementType(constructorElement, functionType);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitCompilationUnit(CompilationUnit node) {
+    _graph.migrating(_source);
+    return super.visitCompilationUnit(node);
   }
 
   @override
   DecoratedType visitConstructorDeclaration(ConstructorDeclaration node) {
-    if (node.factoryKeyword != null) {
-      // Factory constructors can return null, but we don't want to propagate a
-      // null type if we can prove that null is never returned.
-      // TODO(brianwilkerson)
-      _unimplemented(node, 'Declaration of a factory constructor');
-    }
-    _handleExecutableDeclaration(
-        node.declaredElement, null, node.parameters, node.body, node);
+    _handleExecutableDeclaration(node.declaredElement, null, node.parameters,
+        node.body, node.redirectedConstructor, node);
     return null;
   }
 
   @override
+  DecoratedType visitDeclaredIdentifier(DeclaredIdentifier node) {
+    node.metadata.accept(this);
+    DecoratedType type = node.type?.accept(this);
+    if (node.identifier != null) {
+      _variables.recordDecoratedElementType(
+          node.identifier.staticElement,
+          type ??
+              DecoratedType.forImplicitType(node.declaredElement.type, _graph));
+    }
+    return type;
+  }
+
+  @override
   DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
     var decoratedType = node.parameter.accept(this);
-    if (node.declaredElement.hasRequired || node.defaultValue != null) {
+    if (node.defaultValue != null) {
+      node.defaultValue.accept(this);
+      return null;
+    } else if (node.declaredElement.hasRequired) {
       return null;
     }
     if (decoratedType == null) {
@@ -95,26 +163,19 @@
 
   @override
   DecoratedType visitFieldFormalParameter(FieldFormalParameter node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'FieldFormalParameter');
-  }
-
-  @override
-  DecoratedType visitFormalParameter(FormalParameter node) {
-    // Do not visit children
-    // TODO(paulberry): handle all types of formal parameters
-    // - NormalFormalParameter
-    // - SimpleFormalParameter
-    // - FieldFormalParameter
-    // - FunctionTypedFormalParameter
-    // - DefaultFormalParameter
-    return null;
+    return _handleFormalParameter(
+        node, node.type, node.typeParameters, node.parameters);
   }
 
   @override
   DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
-    _handleExecutableDeclaration(node.declaredElement, node.returnType,
-        node.functionExpression.parameters, node.functionExpression.body, node);
+    _handleExecutableDeclaration(
+        node.declaredElement,
+        node.returnType,
+        node.functionExpression.parameters,
+        node.functionExpression.body,
+        null,
+        node);
     return null;
   }
 
@@ -127,14 +188,25 @@
   @override
   DecoratedType visitFunctionTypedFormalParameter(
       FunctionTypedFormalParameter node) {
-    // TODO(brianwilkerson)
-    _unimplemented(node, 'FunctionTypedFormalParameter');
+    return _handleFormalParameter(
+        node, node.returnType, node.typeParameters, node.parameters);
   }
 
   @override
   DecoratedType visitMethodDeclaration(MethodDeclaration node) {
     _handleExecutableDeclaration(node.declaredElement, node.returnType,
-        node.parameters, node.body, node);
+        node.parameters, node.body, null, node);
+    return null;
+  }
+
+  @override
+  visitMixinDeclaration(MixinDeclaration node) {
+    node.metadata.accept(this);
+    node.name?.accept(this);
+    node.typeParameters?.accept(this);
+    node.members.accept(this);
+    _handleSupertypeClauses(
+        node.declaredElement, null, null, node.implementsClause, node.onClause);
     return null;
   }
 
@@ -157,15 +229,7 @@
 
   @override
   DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
-    var type = decorateType(node.type, node);
-    var declaredElement = node.declaredElement;
-    _variables.recordDecoratedElementType(declaredElement, type);
-    if (declaredElement.isNamed) {
-      _namedParameters[declaredElement.name] = type;
-    } else {
-      _positionalParameters.add(type);
-    }
-    return type;
+    return _handleFormalParameter(node, node.type, null, null);
   }
 
   @override
@@ -183,14 +247,15 @@
       return decoratedType;
     }
     var typeArguments = const <DecoratedType>[];
-    DecoratedType returnType;
+    DecoratedType decoratedReturnType;
     var positionalParameters = const <DecoratedType>[];
     var namedParameters = const <String, DecoratedType>{};
     if (type is InterfaceType && type.typeParameters.isNotEmpty) {
       if (node is TypeName) {
         if (node.typeArguments == null) {
-          typeArguments =
-              type.typeArguments.map(_decorateImplicitTypeArgument).toList();
+          typeArguments = type.typeArguments
+              .map((t) => DecoratedType.forImplicitType(t, _graph))
+              .toList();
         } else {
           typeArguments =
               node.typeArguments.arguments.map((t) => t.accept(this)).toList();
@@ -200,15 +265,16 @@
       }
     }
     if (node is GenericFunctionType) {
-      returnType = decorateType(node.returnType, node);
+      var returnType = node.returnType;
+      decoratedReturnType = returnType == null
+          ? DecoratedType.forImplicitType(DynamicTypeImpl.instance, _graph)
+          : returnType.accept(this);
       if (node.typeParameters != null) {
         // TODO(paulberry)
         _unimplemented(node, 'Generic function type with type parameters');
       }
       positionalParameters = <DecoratedType>[];
       namedParameters = <String, DecoratedType>{};
-    }
-    if (node is GenericFunctionType) {
       var previousPositionalParameters = _positionalParameters;
       var previousNamedParameters = _namedParameters;
       try {
@@ -220,10 +286,21 @@
         _namedParameters = previousNamedParameters;
       }
     }
-    var decoratedType = DecoratedTypeAnnotation(
-        type, NullabilityNode.forTypeAnnotation(node.end), node.end,
+    NullabilityNode nullabilityNode;
+    var parent = node.parent;
+    if (parent is ExtendsClause ||
+        parent is ImplementsClause ||
+        parent is WithClause ||
+        parent is OnClause ||
+        parent is ClassTypeAlias ||
+        parent is CatchClause) {
+      nullabilityNode = _graph.never;
+    } else {
+      nullabilityNode = NullabilityNode.forTypeAnnotation(node.end);
+    }
+    var decoratedType = DecoratedTypeAnnotation(type, nullabilityNode, node.end,
         typeArguments: typeArguments,
-        returnType: returnType,
+        returnType: decoratedReturnType,
         positionalParameters: positionalParameters,
         namedParameters: namedParameters);
     _variables.recordDecoratedTypeAnnotation(_source, node, decoratedType);
@@ -250,20 +327,31 @@
   @override
   DecoratedType visitTypeParameter(TypeParameter node) {
     var element = node.declaredElement;
-    var decoratedBound = node.bound?.accept(this) ??
-        DecoratedType(
-            element.bound ?? _typeProvider.objectType,
-            NullabilityNode.forInferredDynamicType(
-                _graph, _source, node.offset));
+    var bound = node.bound;
+    DecoratedType decoratedBound;
+    if (bound != null) {
+      decoratedBound = bound.accept(this);
+    } else {
+      var nullabilityNode = NullabilityNode.forInferredType();
+      _graph.union(_graph.always, nullabilityNode,
+          AlwaysNullableTypeOrigin(_source, node.offset));
+      decoratedBound = DecoratedType(_typeProvider.objectType, nullabilityNode);
+    }
     _variables.recordDecoratedElementType(element, decoratedBound);
     return null;
   }
 
   @override
   DecoratedType visitVariableDeclarationList(VariableDeclarationList node) {
-    var type = decorateType(node.type, node);
+    node.metadata.accept(this);
+    var typeAnnotation = node.type;
+    var type = typeAnnotation?.accept(this);
     for (var variable in node.variables) {
-      _variables.recordDecoratedElementType(variable.declaredElement, type);
+      variable.metadata.accept(this);
+      var declaredElement = variable.declaredElement;
+      _variables.recordDecoratedElementType(declaredElement,
+          type ?? DecoratedType.forImplicitType(declaredElement.type, _graph));
+      variable.initializer?.accept(this);
     }
     return null;
   }
@@ -276,20 +364,13 @@
     return _NullabilityComment.none;
   }
 
-  /// Creates a DecoratedType corresponding to [type], with fresh nullability
-  /// nodes everywhere that don't correspond to any source location.  These
-  /// nodes can later be unioned with other nodes.
-  DecoratedType _decorateImplicitTypeArgument(DartType type) {
-    if (type.isDynamic) {
-      return DecoratedType(type, _graph.always);
-    } else if (type is InterfaceType) {
-      return DecoratedType(type, NullabilityNode.forInferredType(),
-          typeArguments:
-              type.typeArguments.map(_decorateImplicitTypeArgument).toList());
-    }
-    // TODO(paulberry)
-    throw UnimplementedError(
-        '_decorateImplicitTypeArgument(${type.runtimeType})');
+  DecoratedType _createDecoratedTypeForClass(
+      ClassElement classElement, AstNode node) {
+    var typeArguments = classElement.typeParameters
+        .map((t) => DecoratedType(t.type, _graph.never))
+        .toList();
+    return DecoratedType(classElement.type, _graph.never,
+        typeArguments: typeArguments);
   }
 
   /// Common handling of function and method declarations.
@@ -298,46 +379,124 @@
       TypeAnnotation returnType,
       FormalParameterList parameters,
       FunctionBody body,
+      ConstructorName redirectedConstructor,
       AstNode enclosingNode) {
+    var functionType = declaredElement.type;
     DecoratedType decoratedReturnType;
-    if (returnType == null && declaredElement is ConstructorElement) {
+    if (returnType != null) {
+      decoratedReturnType = returnType.accept(this);
+    } else if (declaredElement is ConstructorElement) {
       // Constructors have no explicit return type annotation, so use the
       // implicit return type.
-      if (declaredElement.isFactory) {
-        // Factory constructors can return null, but we don't want to propagate
-        // a null type if we can prove that null is never returned.
-        // TODO(brianwilkerson)
-        _unimplemented(
-            parameters.parent, 'Declaration of a factory constructor');
-      }
-      if (declaredElement.enclosingElement.typeParameters.isNotEmpty) {
-        // Need to decorate the type parameters appropriately.
-        // TODO(paulberry,brianwilkerson)
-        _unimplemented(parameters.parent,
-            'Declaration of a constructor with type parameters');
-      }
-      decoratedReturnType = new DecoratedType(
-          declaredElement.enclosingElement.type, _graph.never);
+      decoratedReturnType = _createDecoratedTypeForClass(
+          declaredElement.enclosingElement, parameters.parent);
     } else {
-      decoratedReturnType = decorateType(returnType, enclosingNode);
+      // Inferred return type.
+      decoratedReturnType =
+          DecoratedType.forImplicitType(functionType.returnType, _graph);
     }
     var previousPositionalParameters = _positionalParameters;
     var previousNamedParameters = _namedParameters;
     _positionalParameters = [];
     _namedParameters = {};
-    DecoratedType functionType;
+    DecoratedType decoratedFunctionType;
     try {
       parameters?.accept(this);
-      body?.accept(this);
-      functionType = DecoratedType(declaredElement.type, _graph.never,
+      redirectedConstructor?.accept(this);
+      decoratedFunctionType = DecoratedType(functionType, _graph.never,
           returnType: decoratedReturnType,
           positionalParameters: _positionalParameters,
           namedParameters: _namedParameters);
+      body?.accept(this);
     } finally {
       _positionalParameters = previousPositionalParameters;
       _namedParameters = previousNamedParameters;
     }
-    _variables.recordDecoratedElementType(declaredElement, functionType);
+    _variables.recordDecoratedElementType(
+        declaredElement, decoratedFunctionType);
+  }
+
+  DecoratedType _handleFormalParameter(
+      FormalParameter node,
+      TypeAnnotation type,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters) {
+    var declaredElement = node.declaredElement;
+    node.metadata?.accept(this);
+    DecoratedType decoratedType;
+    if (parameters == null) {
+      decoratedType = type != null
+          ? type.accept(this)
+          : DecoratedType.forImplicitType(declaredElement.type, _graph);
+    } else {
+      var decoratedReturnType = type == null
+          ? DecoratedType.forImplicitType(DynamicTypeImpl.instance, _graph)
+          : type.accept(this);
+      if (typeParameters != null) {
+        // TODO(paulberry)
+        _unimplemented(
+            typeParameters, 'Function-typed parameter with type parameters');
+      }
+      var positionalParameters = <DecoratedType>[];
+      var namedParameters = <String, DecoratedType>{};
+      var previousPositionalParameters = _positionalParameters;
+      var previousNamedParameters = _namedParameters;
+      try {
+        _positionalParameters = positionalParameters;
+        _namedParameters = namedParameters;
+        parameters.accept(this);
+      } finally {
+        _positionalParameters = previousPositionalParameters;
+        _namedParameters = previousNamedParameters;
+      }
+      decoratedType = DecoratedTypeAnnotation(declaredElement.type,
+          NullabilityNode.forTypeAnnotation(node.end), node.end,
+          returnType: decoratedReturnType,
+          positionalParameters: positionalParameters,
+          namedParameters: namedParameters);
+    }
+    _variables.recordDecoratedElementType(declaredElement, decoratedType);
+    if (declaredElement.isNamed) {
+      _namedParameters[declaredElement.name] = decoratedType;
+    } else {
+      _positionalParameters.add(decoratedType);
+    }
+    return decoratedType;
+  }
+
+  void _handleSupertypeClauses(
+      ClassElement declaredElement,
+      TypeName superclass,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      OnClause onClause) {
+    var supertypes = <TypeName>[];
+    supertypes.add(superclass);
+    if (withClause != null) {
+      supertypes.addAll(withClause.mixinTypes);
+    }
+    if (implementsClause != null) {
+      supertypes.addAll(implementsClause.interfaces);
+    }
+    if (onClause != null) {
+      supertypes.addAll(onClause.superclassConstraints);
+    }
+    var decoratedSupertypes = <ClassElement, DecoratedType>{};
+    for (var supertype in supertypes) {
+      DecoratedType decoratedSupertype;
+      if (supertype == null) {
+        decoratedSupertype = _nonNullableObjectType;
+      } else {
+        decoratedSupertype = supertype.accept(this);
+      }
+      var class_ = (decoratedSupertype.type as InterfaceType).element;
+      if (class_ is ClassElementHandle) {
+        class_ = (class_ as ClassElementHandle).actualElement;
+      }
+      decoratedSupertypes[class_] = decoratedSupertype;
+    }
+    _variables.recordDecoratedDirectSupertypes(
+        declaredElement, decoratedSupertypes);
   }
 
   @alwaysThrows
@@ -363,6 +522,11 @@
 /// ([NodeBuilder], which finds all the variables that need to be
 /// constrained).
 abstract class VariableRecorder {
+  /// Associates a [class_] with decorated type information for the superclasses
+  /// it directly implements/extends/etc.
+  void recordDecoratedDirectSupertypes(ClassElement class_,
+      Map<ClassElement, DecoratedType> decoratedDirectSupertypes);
+
   /// Associates decorated type information with the given [element].
   void recordDecoratedElementType(Element element, DecoratedType type);
 
@@ -386,12 +550,18 @@
 /// results of the first ([NodeBuilder], which finds all the
 /// variables that need to be constrained).
 abstract class VariableRepository {
+  /// Given a [class_], gets the decorated type information for the superclasses
+  /// it directly implements/extends/etc.
+  Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
+      ClassElement class_);
+
   /// Retrieves the [DecoratedType] associated with the static type of the given
   /// [element].
   ///
-  /// If [create] is `true`, and no decorated type is found for the given
-  /// element, one is synthesized using [DecoratedType.forElement].
-  DecoratedType decoratedElementType(Element element, {bool create: false});
+  /// If no decorated type is found for the given element, and the element is in
+  /// a library that's not being migrated, a decorated type is synthesized using
+  /// [DecoratedType.forElement].
+  DecoratedType decoratedElementType(Element element);
 
   /// Gets the [DecoratedType] associated with the given [typeAnnotation].
   DecoratedType decoratedTypeAnnotation(
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 3d405a3..6fede39 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -7,8 +7,8 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_builder.dart';
 import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/graph_builder.dart';
 import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/potential_modification.dart';
@@ -59,8 +59,8 @@
 
   void processInput(ResolvedUnitResult result) {
     var unit = result.unit;
-    unit.accept(GraphBuilder(result.typeProvider, _variables, _graph,
-        unit.declaredElement.source, _permissive ? listener : null));
+    unit.accept(EdgeBuilder(result.typeProvider, result.typeSystem, _variables,
+        _graph, unit.declaredElement.source, _permissive ? listener : null));
   }
 }
 
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index d71920e..6e345f4 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -97,6 +97,9 @@
   /// node.
   final NullabilityNode never = _NullabilityNodeImmutable('never', false);
 
+  /// Set containing all sources being migrated.
+  final _sourcesBeingMigrated = <Source>{};
+
   /// Records that [sourceNode] is immediately upstream from [destinationNode].
   ///
   /// Returns the edge created by the connection.
@@ -108,6 +111,16 @@
     return _connect(sources, destinationNode, kind, origin);
   }
 
+  /// Determine if [source] is in the code being migrated.
+  bool isBeingMigrated(Source source) {
+    return _sourcesBeingMigrated.contains(source);
+  }
+
+  /// Record source as code that is being migrated.
+  void migrating(Source source) {
+    _sourcesBeingMigrated.add(source);
+  }
+
   /// Determines the nullability of each node in the graph by propagating
   /// nullability information from one node to another.
   ///
@@ -154,7 +167,9 @@
       var destinations =
           edges.where((edge) => edge.primarySource == source).map((edge) {
         var suffixes = <Object>[];
-        if (edge.hard) {
+        if (edge.isUnion) {
+          suffixes.add('union');
+        } else if (edge.hard) {
           suffixes.add('hard');
         }
         suffixes.addAll(edge.guards);
@@ -257,6 +272,14 @@
 /// testing.
 @visibleForTesting
 class NullabilityGraphForTesting extends NullabilityGraph {
+  /// Iterates through all edges that have this node as one of their sources.
+  ///
+  /// There is no guarantee of uniqueness of the iterated edges.
+  @visibleForTesting
+  Iterable<NullabilityEdge> getDownstreamEdges(NullabilityNode node) {
+    return node._downstreamEdges;
+  }
+
   /// Iterates through all edges that have this node as their destination.
   ///
   /// There is no guarantee of uniqueness of the iterated nodes.
@@ -288,17 +311,17 @@
   /// List of edges that have this node as their destination.
   final _upstreamEdges = <NullabilityEdge>[];
 
-  /// Creates a [NullabilityNode] representing the nullability of a variable
-  /// whose type is `dynamic` due to type inference.
+  /// Creates a [NullabilityNode] representing the nullability of an expression
+  /// which is nullable iff two other nullability nodes are both nullable.
   ///
-  /// TODO(paulberry): this should go away; we should decorate the actual
-  /// inferred type rather than assuming `dynamic`.
-  factory NullabilityNode.forInferredDynamicType(
-      NullabilityGraph graph, Source source, int offset) {
-    var node = _NullabilityNodeSimple('inferredDynamic($offset)');
-    graph.union(node, graph.always, AlwaysNullableTypeOrigin(source, offset));
-    return node;
-  }
+  /// The caller is required to create the appropriate graph edges to ensure
+  /// that the appropriate relationship between the nodes' nullabilities holds.
+  factory NullabilityNode.forGLB() => _NullabilityNodeSimple('GLB');
+
+  /// Creates a [NullabilityNode] representing the nullability of a variable
+  /// whose type is determined by the `??` operator.
+  factory NullabilityNode.forIfNotNull() =>
+      _NullabilityNodeSimple('?? operator');
 
   /// Creates a [NullabilityNode] representing the nullability of a variable
   /// whose type is determined by type inference.
@@ -306,12 +329,7 @@
       _NullabilityNodeSimple('inferred');
 
   /// Creates a [NullabilityNode] representing the nullability of an
-  /// expression which is nullable iff both [a] and [b] are nullable.
-  ///
-  /// The constraint variable contained in the new node is created using the
-  /// [joinNullabilities] callback.  TODO(paulberry): this should become
-  /// unnecessary once constraint solving is performed directly using
-  /// [NullabilityNode] objects.
+  /// expression which is nullable iff either [a] or [b] is nullable.
   factory NullabilityNode.forLUB(NullabilityNode left, NullabilityNode right) =
       NullabilityNodeForLUB._;
 
@@ -387,6 +405,11 @@
   void trackPossiblyOptional() {
     _isPossiblyOptional = true;
   }
+
+  @visibleForTesting
+  static void clearDebugNames() {
+    _debugNamesInUse.clear();
+  }
 }
 
 /// Derived class for nullability nodes that arise from the least-upper-bound
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 9a8e653..ccb4aec 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:nnbd_migration/src/conditional_discard.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
@@ -17,6 +18,9 @@
 
   final _decoratedElementTypes = <Element, DecoratedType>{};
 
+  final _decoratedDirectSupertypes =
+      <ClassElement, Map<ClassElement, DecoratedType>>{};
+
   final _decoratedTypeAnnotations =
       <Source, Map<int, DecoratedTypeAnnotation>>{};
 
@@ -25,16 +29,32 @@
   Variables(this._graph);
 
   @override
-  DecoratedType decoratedElementType(Element element, {bool create: false}) =>
-      _decoratedElementTypes[element] ??= create
-          ? DecoratedType.forElement(element, _graph)
-          : throw StateError('No element found');
+  Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
+      ClassElement class_) {
+    assert(class_ is! ClassElementHandle);
+    return _decoratedDirectSupertypes[class_] ??
+        _decorateDirectSupertypes(class_);
+  }
+
+  @override
+  DecoratedType decoratedElementType(Element element) =>
+      _decoratedElementTypes[element] ??= _createDecoratedElementType(element);
 
   @override
   DecoratedType decoratedTypeAnnotation(
       Source source, TypeAnnotation typeAnnotation) {
-    return _decoratedTypeAnnotations[source]
-        [_uniqueOffsetForTypeAnnotation(typeAnnotation)];
+    var annotationsInSource = _decoratedTypeAnnotations[source];
+    if (annotationsInSource == null) {
+      throw StateError('No declarated type annotations in ${source.fullName}; '
+          'expected one for ${typeAnnotation.toSource()}');
+    }
+    DecoratedTypeAnnotation decoratedTypeAnnotation =
+        annotationsInSource[_uniqueOffsetForTypeAnnotation(typeAnnotation)];
+    if (decoratedTypeAnnotation == null) {
+      throw StateError('Missing declarated type annotation'
+          ' in ${source.fullName}; for ${typeAnnotation.toSource()}');
+    }
+    return decoratedTypeAnnotation;
   }
 
   Map<Source, List<PotentialModification>> getPotentialModifications() =>
@@ -47,7 +67,30 @@
         source, ConditionalModification(node, conditionalDiscard));
   }
 
+  @override
+  void recordDecoratedDirectSupertypes(ClassElement class_,
+      Map<ClassElement, DecoratedType> decoratedDirectSupertypes) {
+    assert(() {
+      assert(class_ is! ClassElementHandle);
+      for (var key in decoratedDirectSupertypes.keys) {
+        assert(key is! ClassElementHandle);
+      }
+      return true;
+    }());
+    _decoratedDirectSupertypes[class_] = decoratedDirectSupertypes;
+  }
+
   void recordDecoratedElementType(Element element, DecoratedType type) {
+    assert(() {
+      var library = element.library;
+      if (library == null) {
+        // No problem; the element is probably a parameter of a function type
+        // expressed using new-style Function syntax.
+      } else {
+        assert(_graph.isBeingMigrated(library.source));
+      }
+      return true;
+    }());
     _decoratedElementTypes[element] = type;
   }
 
@@ -126,6 +169,28 @@
     (_potentialModifications[source] ??= []).add(potentialModification);
   }
 
+  DecoratedType _createDecoratedElementType(Element element) {
+    if (_graph.isBeingMigrated(element.library.source)) {
+      throw StateError('A decorated type for $element should have been stored '
+          'by the NodeBuilder via recordDecoratedElementType');
+    }
+    return DecoratedType.forElement(element, _graph);
+  }
+
+  /// Creates an entry [_decoratedDirectSupertypes] for an already-migrated
+  /// class.
+  Map<ClassElement, DecoratedType> _decorateDirectSupertypes(
+      ClassElement class_) {
+    if (class_.type.isObject) {
+      // TODO(paulberry): this special case is just to get the basic
+      // infrastructure working (necessary since all classes derive from
+      // Object).  Once we have the full implementation this case shouldn't be
+      // needed.
+      return const {};
+    }
+    throw UnimplementedError('TODO(paulberry)');
+  }
+
   int _uniqueOffsetForTypeAnnotation(TypeAnnotation typeAnnotation) =>
       typeAnnotation is GenericFunctionType
           ? typeAnnotation.functionKeyword.offset
diff --git a/pkg/nnbd_migration/test/abstract_single_unit.dart b/pkg/nnbd_migration/test/abstract_single_unit.dart
index 25c5f87..9ccb588 100644
--- a/pkg/nnbd_migration/test/abstract_single_unit.dart
+++ b/pkg/nnbd_migration/test/abstract_single_unit.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 
@@ -20,12 +21,14 @@
 
   String testCode;
   String testFile;
+  Uri testUri;
   Source testSource;
   ResolvedUnitResult testAnalysisResult;
   CompilationUnit testUnit;
   CompilationUnitElement testUnitElement;
   LibraryElement testLibraryElement;
   FindNode findNode;
+  FindElement findElement;
 
   void addTestSource(String code, [Uri uri]) {
     testCode = code;
@@ -33,7 +36,7 @@
   }
 
   Future<void> resolveTestUnit(String code) async {
-    addTestSource(code);
+    addTestSource(code, testUri);
     testAnalysisResult = await session.getResolvedUnit(testFile);
     testUnit = testAnalysisResult.unit;
     if (verifyNoTestUnitErrors) {
@@ -50,11 +53,13 @@
     testUnitElement = testUnit.declaredElement;
     testLibraryElement = testUnitElement.library;
     findNode = FindNode(code, testUnit);
+    findElement = FindElement(testUnit);
   }
 
   @override
   void setUp() {
     super.setUp();
     testFile = convertPath('/home/test/lib/test.dart');
+    testUri = Uri.parse('package:test/test.dart');
   }
 }
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index c378285..e53b981 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -76,6 +76,44 @@
 
 /// Mixin containing test cases for the provisional API.
 mixin _ProvisionalApiTestCases on _ProvisionalApiTestBase {
+  test_class_alias_synthetic_constructor_with_parameters() async {
+    var content = '''
+void main() {
+  D d = D(null);
+}
+class C {
+  C(int i);
+}
+mixin M {}
+class D = C with M;
+''';
+    var expected = '''
+void main() {
+  D d = D(null);
+}
+class C {
+  C(int? i);
+}
+mixin M {}
+class D = C with M;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_class_with_default_constructor() async {
+    var content = '''
+void main() => f(Foo());
+f(Foo f) {}
+class Foo {}
+''';
+    var expected = '''
+void main() => f(Foo());
+f(Foo f) {}
+class Foo {}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_comment_bang_implies_non_null_intent() async {
     var content = '''
 void f(int/*!*/ i) {}
@@ -224,6 +262,72 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_constructorDeclaration_factory_non_null_return() async {
+    var content = '''
+class C {
+  C._();
+  factory C() {
+    C c = f();
+    return c;
+  }
+}
+C f() => null;
+''';
+    var expected = '''
+class C {
+  C._();
+  factory C() {
+    C c = f()!;
+    return c;
+  }
+}
+C? f() => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_constructorDeclaration_factory_simple() async {
+    var content = '''
+class C {
+  C._();
+  factory C(int i) => C._();
+}
+main() {
+  C(null);
+}
+''';
+    var expected = '''
+class C {
+  C._();
+  factory C(int? i) => C._();
+}
+main() {
+  C(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_constructorDeclaration_named() async {
+    var content = '''
+class C {
+  C.named(int i);
+}
+main() {
+  C.named(null);
+}
+''';
+    var expected = '''
+class C {
+  C.named(int? i);
+}
+main() {
+  C.named(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_constructorDeclaration_namedParameter() async {
     var content = '''
 class C {
@@ -332,6 +436,24 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_data_flow_function_return_type() async {
+    var content = '''
+int Function() f(int Function() x) => x;
+int g() => null;
+main() {
+  f(g);
+}
+''';
+    var expected = '''
+int? Function() f(int? Function() x) => x;
+int? g() => null;
+main() {
+  f(g);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_data_flow_generic_contravariant_inward() async {
     var content = '''
 class C<T> {
@@ -370,6 +492,52 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_data_flow_generic_contravariant_inward_function() async {
+    var content = '''
+T f<T>(T t) => t;
+int g(int x) => f<int>(x);
+void h() {
+  g(null);
+}
+''';
+
+    // As with the generic class case (see
+    // [test_data_flow_generic_contravariant_inward_function]), we favor adding
+    // nullability at the call site, so that other uses of `f` don't necessarily
+    // see a nullable return value.
+    var expected = '''
+T f<T>(T t) => t;
+int? g(int? x) => f<int?>(x);
+void h() {
+  g(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_generic_contravariant_inward_using_core_class() async {
+    var content = '''
+void f(List<int> x, int i) {
+  x.add(i);
+}
+void test(List<int> x) {
+  f(x, null);
+}
+''';
+    // TODO(paulberry): possible improvement: detect that since add uses T in
+    // a contravariant way, and deduce that test should change to
+    // `void test(List<int?> x)`
+    var expected = '''
+void f(List<int?> x, int? i) {
+  x.add(i);
+}
+void test(List<int> x) {
+  f(x, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_data_flow_generic_covariant_outward() async {
     var content = '''
 class C<T> {
@@ -645,6 +813,217 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_field_formal_param_typed() async {
+    var content = '''
+class C {
+  int i;
+  C(int this.i);
+}
+main() {
+  C(null);
+}
+''';
+    var expected = '''
+class C {
+  int? i;
+  C(int? this.i);
+}
+main() {
+  C(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_field_formal_param_typed_non_nullable() async {
+    var content = '''
+class C {
+  int/*!*/ i;
+  C(int this.i);
+}
+void f(int i, bool b) {
+  if (b) {
+    C(i);
+  }
+}
+main() {
+  f(null, false);
+}
+''';
+    var expected = '''
+class C {
+  int/*!*/ i;
+  C(int this.i);
+}
+void f(int? i, bool b) {
+  if (b) {
+    C(i!);
+  }
+}
+main() {
+  f(null, false);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_field_formal_param_untyped() async {
+    var content = '''
+class C {
+  int i;
+  C(this.i);
+}
+main() {
+  C(null);
+}
+''';
+    var expected = '''
+class C {
+  int? i;
+  C(this.i);
+}
+main() {
+  C(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_field_type_inferred() async {
+    var content = '''
+int f() => null;
+class C {
+  var x = 1;
+  void g() {
+    x = f();
+  }
+}
+''';
+    // The type of x is inferred from its initializer, so it is non-nullable,
+    // even though we try to assign a nullable value to it.  So a null check
+    // must be added.
+    var expected = '''
+int? f() => null;
+class C {
+  var x = 1;
+  void g() {
+    x = f()!;
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_function_expression_invocation() async {
+    var content = '''
+abstract class C {
+  void Function(int) f();
+  int/*?*/ Function() g();
+}
+int test(C c) {
+  c.f()(null);
+  return c.g()();
+}
+''';
+    var expected = '''
+abstract class C {
+  void Function(int?) f();
+  int?/*?*/ Function() g();
+}
+int? test(C c) {
+  c.f()(null);
+  return c.g()();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_function_expression_invocation_via_getter() async {
+    var content = '''
+abstract class C {
+  void Function(int) get f;
+  int/*?*/ Function() get g;
+}
+int test(C c) {
+  c.f(null);
+  return c.g();
+}
+''';
+    var expected = '''
+abstract class C {
+  void Function(int?) get f;
+  int?/*?*/ Function() get g;
+}
+int? test(C c) {
+  c.f(null);
+  return c.g();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_function_typed_field_formal_param() async {
+    var content = '''
+class C {
+  int Function(int) f;
+  C(int this.f(int i));
+}
+int g(int i) => i;
+int test(int i) => C(g).f(i);
+main() {
+  test(null);
+}
+''';
+    var expected = '''
+class C {
+  int? Function(int?) f;
+  C(int? this.f(int? i));
+}
+int? g(int? i) => i;
+int? test(int? i) => C(g).f(i);
+main() {
+  test(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_function_typed_formal_param() async {
+    var content = '''
+int f(int callback(int i), int j) => callback(j);
+int g(int i) => i;
+int test(int i) => f(g, i);
+main() {
+  test(null);
+}
+''';
+    var expected = '''
+int? f(int? callback(int? i), int? j) => callback(j);
+int? g(int? i) => i;
+int? test(int? i) => f(g, i);
+main() {
+  test(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_generic_function_type_syntax_inferred_dynamic_return() async {
+    var content = '''
+abstract class C {
+  Function() f();
+}
+Object g(C c) => c.f()();
+''';
+    var expected = '''
+abstract class C {
+  Function() f();
+}
+Object? g(C c) => c.f()();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_genericType_noTypeArguments() async {
     var content = '''
 void f(C c) {}
@@ -710,6 +1089,148 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_inferred_method_parameter_type_non_nullable() async {
+    var content = '''
+class B {
+  void f(int i) {
+    assert(i != null);
+  }
+}
+class C extends B {
+  void f(i) {}
+}
+void g(C c, int i, bool b) {
+  if (b) {
+    c.f(i);
+  }
+}
+void h(C c) {
+  g(c, null, false);
+}
+''';
+    // B.f's parameter type is `int`.  Since C.f's parameter type is inferred
+    // from B.f's, it has a parameter type of `int` too.  Therefore there must
+    // be a null check in g().
+    var expected = '''
+class B {
+  void f(int i) {
+    assert(i != null);
+  }
+}
+class C extends B {
+  void f(i) {}
+}
+void g(C c, int? i, bool b) {
+  if (b) {
+    c.f(i!);
+  }
+}
+void h(C c) {
+  g(c, null, false);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_inferred_method_parameter_type_nullable() async {
+    var content = '''
+class B {
+  void f(int i) {}
+}
+class C extends B {
+  void f(i) {}
+}
+void g(C c) {
+  c.f(null);
+}
+''';
+    // The call to C.f from g forces C.f's parameter to be nullable.  Since
+    // C.f's parameter type is inferred from B.f's parameter type, B.f's
+    // parameter must be nullable too.
+    var expected = '''
+class B {
+  void f(int? i) {}
+}
+class C extends B {
+  void f(i) {}
+}
+void g(C c) {
+  c.f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_inferred_method_return_type_non_nullable() async {
+    var content = '''
+class B {
+  int f() => 1;
+}
+class C extends B {
+  f() => 1;
+}
+int g(C c) => c.f();
+''';
+    // B.f's return type is `int`.  Since C.f's return type is inferred from
+    // B.f's, it has a return type of `int` too.  Therefore g's return type
+    // must be `int`.
+    var expected = '''
+class B {
+  int f() => 1;
+}
+class C extends B {
+  f() => 1;
+}
+int g(C c) => c.f();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_inferred_method_return_type_nullable() async {
+    var content = '''
+class B {
+  int f() => null;
+}
+class C extends B {
+  f() => 1;
+}
+int g(C c) => c.f();
+''';
+    // B.f's return type is `int?`.  Since C.f's return type is inferred from
+    // B.f's, it has a return type of `int?` too.  Therefore g's return type
+    // must be `int?`.
+    var expected = '''
+class B {
+  int? f() => null;
+}
+class C extends B {
+  f() => 1;
+}
+int? g(C c) => c.f();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_instance_creation_generic() async {
+    var content = '''
+class C<T> {
+  C(T t);
+}
+main() {
+  C<int> c = C<int>(null);
+}
+''';
+    var expected = '''
+class C<T> {
+  C(T t);
+}
+main() {
+  C<int?> c = C<int?>(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_instanceCreation_noTypeArguments_noParameters() async {
     var content = '''
 void main() {
@@ -732,6 +1253,27 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_localVariable_type_inferred() async {
+    var content = '''
+int f() => null;
+void main() {
+  var x = 1;
+  x = f();
+}
+''';
+    // The type of x is inferred from its initializer, so it is non-nullable,
+    // even though we try to assign a nullable value to it.  So a null check
+    // must be added.
+    var expected = '''
+int? f() => null;
+void main() {
+  var x = 1;
+  x = f()!;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_named_parameter_no_default_unused() async {
     var content = '''
 void f({String s}) {}
@@ -1023,6 +1565,154 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_override_parameter_type_non_nullable() async {
+    var content = '''
+abstract class Base {
+  void f(int i);
+}
+class Derived extends Base {
+  void f(int i) {
+    assert(i != null);
+  }
+}
+void g(int i, bool b, Base base) {
+  if (b) {
+    base.f(i);
+  }
+}
+void h(Base base) {
+  g(null, false, base);
+}
+''';
+    var expected = '''
+abstract class Base {
+  void f(int i);
+}
+class Derived extends Base {
+  void f(int i) {
+    assert(i != null);
+  }
+}
+void g(int? i, bool b, Base base) {
+  if (b) {
+    base.f(i!);
+  }
+}
+void h(Base base) {
+  g(null, false, base);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_override_parameter_type_nullable() async {
+    var content = '''
+abstract class Base {
+  void f(int i);
+}
+class Derived extends Base {
+  void f(int i) {}
+}
+void g(int i, Base base) {
+  base.f(null);
+}
+''';
+    var expected = '''
+abstract class Base {
+  void f(int? i);
+}
+class Derived extends Base {
+  void f(int? i) {}
+}
+void g(int i, Base base) {
+  base.f(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_override_return_type_non_nullable() async {
+    var content = '''
+abstract class Base {
+  int/*!*/ f();
+}
+class Derived extends Base {
+  int f() => g();
+}
+int g() => null;
+''';
+    var expected = '''
+abstract class Base {
+  int/*!*/ f();
+}
+class Derived extends Base {
+  int f() => g()!;
+}
+int? g() => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_override_return_type_nullable() async {
+    var content = '''
+abstract class Base {
+  int f();
+}
+class Derived extends Base {
+  int f() => null;
+}
+''';
+    var expected = '''
+abstract class Base {
+  int? f();
+}
+class Derived extends Base {
+  int? f() => null;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_override_return_type_nullable_substitution_complex() async {
+    var content = '''
+abstract class Base<T> {
+  T f();
+}
+class Derived extends Base<List<int>> {
+  List<int> f() => <int>[null];
+}
+''';
+    var expected = '''
+abstract class Base<T> {
+  T f();
+}
+class Derived extends Base<List<int?>> {
+  List<int?> f() => <int?>[null];
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_override_return_type_nullable_substitution_simple() async {
+    var content = '''
+abstract class Base<T> {
+  T f();
+}
+class Derived extends Base<int> {
+  int f() => null;
+}
+''';
+    var expected = '''
+abstract class Base<T> {
+  T f();
+}
+class Derived extends Base<int?> {
+  int? f() => null;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_parameter_genericFunctionType() async {
     var content = '''
 int f(int x, int Function(int i) g) {
@@ -1037,6 +1727,42 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_prefix_minus() async {
+    var content = '''
+class C {
+  D operator-() => null;
+}
+class D {}
+D test(C c) => -c;
+''';
+    var expected = '''
+class C {
+  D? operator-() => null;
+}
+class D {}
+D? test(C c) => -c;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_prefix_minus_substitute() async {
+    var content = '''
+abstract class C<T> {
+  D<T> operator-();
+}
+class D<U> {}
+D<int> test(C<int/*?*/> c) => -c;
+''';
+    var expected = '''
+abstract class C<T> {
+  D<T> operator-();
+}
+class D<U> {}
+D<int?> test(C<int?/*?*/> c) => -c;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_prefixExpression_bang() async {
     var content = '''
 bool f(bool b) => !b;
@@ -1063,6 +1789,54 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_redirecting_constructor_factory() async {
+    var content = '''
+class C {
+  factory C(int i, int j) = D;
+}
+class D implements C {
+  D(int i, int j);
+}
+main() {
+  C(null, 1);
+}
+''';
+    var expected = '''
+class C {
+  factory C(int? i, int j) = D;
+}
+class D implements C {
+  D(int? i, int j);
+}
+main() {
+  C(null, 1);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_redirecting_constructor_ordinary() async {
+    var content = '''
+class C {
+  C(int i, int j) : this.named(j, i);
+  C.named(int j, int i);
+}
+main() {
+  C(null, 1);
+}
+''';
+    var expected = '''
+class C {
+  C(int? i, int j) : this.named(j, i);
+  C.named(int j, int? i);
+}
+main() {
+  C(null, 1);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_single_file_multiple_changes() async {
     var content = '''
 int f() => null;
@@ -1085,6 +1859,49 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  test_topLevelFunction_parameterType_implicit_dynamic() async {
+    var content = '''
+Object f(x) => x;
+''';
+    var expected = '''
+Object? f(x) => x;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_topLevelFunction_returnType_implicit_dynamic() async {
+    var content = '''
+f() {}
+Object g() => f();
+''';
+    var expected = '''
+f() {}
+Object? g() => f();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_topLevelVariable_type_inferred() async {
+    var content = '''
+int f() => null;
+var x = 1;
+void main() {
+  x = f();
+}
+''';
+    // The type of x is inferred from its initializer, so it is non-nullable,
+    // even though we try to assign a nullable value to it.  So a null check
+    // must be added.
+    var expected = '''
+int? f() => null;
+var x = 1;
+void main() {
+  x = f()!;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   test_two_files() async {
     var root = '/home/test/lib';
     var path1 = convertPath('$root/file1.dart');
@@ -1397,6 +2214,12 @@
     with _ProvisionalApiTestCases {
   @override
   bool get _usePermissiveMode => true;
+
+  // TODO(danrubel): Remove this once the superclass test has been fixed.
+  // This runs in permissive mode but not when permissive mode is disabled.
+  test_instanceCreation_noTypeArguments_noParameters() async {
+    super.test_instanceCreation_noTypeArguments_noParameters();
+  }
 }
 
 /// Tests of the provisional API, where the driver is reset between calls to
diff --git a/pkg/nnbd_migration/test/decorated_class_hierarchy_test.dart b/pkg/nnbd_migration/test/decorated_class_hierarchy_test.dart
new file mode 100644
index 0000000..9e09dca
--- /dev/null
+++ b/pkg/nnbd_migration/test/decorated_class_hierarchy_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:nnbd_migration/src/decorated_class_hierarchy.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DecoratedClassHierarchyTest);
+  });
+}
+
+@reflectiveTest
+class DecoratedClassHierarchyTest extends MigrationVisitorTestBase {
+  DecoratedClassHierarchy _hierarchy;
+
+  @override
+  Future<CompilationUnit> analyze(String code) async {
+    var unit = await super.analyze(code);
+    _hierarchy = DecoratedClassHierarchy(variables, graph);
+    return unit;
+  }
+
+  test_getDecoratedSupertype_complex() async {
+    await analyze('''
+class Base<T> {}
+class Intermediate<U> extends Base<List<U>> {}
+class Derived<V> extends Intermediate<Map<int, V>> {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.class_('Derived'), findElement.class_('Base'));
+    var listRef = decoratedTypeAnnotation('List');
+    var uRef = decoratedTypeAnnotation('U>>');
+    var mapRef = decoratedTypeAnnotation('Map');
+    var intRef = decoratedTypeAnnotation('int');
+    var vRef = decoratedTypeAnnotation('V>>');
+    expect(decoratedSupertype.type.toString(), 'Base<List<Map<int, V>>>');
+    expect(decoratedSupertype.node, same(never));
+    var baseArgs = decoratedSupertype.typeArguments;
+    expect(baseArgs, hasLength(1));
+    expect(baseArgs[0].type.toString(), 'List<Map<int, V>>');
+    expect(baseArgs[0].node, same(listRef.node));
+    var listArgs = baseArgs[0].typeArguments;
+    expect(listArgs, hasLength(1));
+    expect(listArgs[0].type.toString(), 'Map<int, V>');
+    var mapNode = listArgs[0].node as NullabilityNodeForSubstitution;
+    expect(mapNode.innerNode, same(mapRef.node));
+    expect(mapNode.outerNode, same(uRef.node));
+    var mapArgs = listArgs[0].typeArguments;
+    expect(mapArgs, hasLength(2));
+    expect(mapArgs[0].type.toString(), 'int');
+    expect(mapArgs[0].node, same(intRef.node));
+    expect(mapArgs[1].type.toString(), 'V');
+    expect(mapArgs[1].node, same(vRef.node));
+  }
+
+  test_getDecoratedSupertype_extends_simple() async {
+    await analyze('''
+class Base<T, U> {}
+class Derived<V, W> extends Base<V, W> {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.class_('Derived'), findElement.class_('Base'));
+    var vRef = decoratedTypeAnnotation('V, W> {');
+    var wRef = decoratedTypeAnnotation('W> {');
+    expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+    expect(decoratedSupertype.node, same(never));
+    expect(decoratedSupertype.typeArguments, hasLength(2));
+    expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+    expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+    expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+    expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+  }
+
+  test_getDecoratedSupertype_implements_simple() async {
+    await analyze('''
+class Base<T, U> {}
+class Derived<V, W> implements Base<V, W> {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.class_('Derived'), findElement.class_('Base'));
+    var vRef = decoratedTypeAnnotation('V, W> {');
+    var wRef = decoratedTypeAnnotation('W> {');
+    expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+    expect(decoratedSupertype.node, same(never));
+    expect(decoratedSupertype.typeArguments, hasLength(2));
+    expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+    expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+    expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+    expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+  }
+
+  test_getDecoratedSupertype_not_generic() async {
+    await analyze('''
+class Base {}
+class Derived<T> extends Base {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.class_('Derived'), findElement.class_('Base'));
+    expect(decoratedSupertype.type.toString(), 'Base');
+    expect(decoratedSupertype.node, same(never));
+    expect(decoratedSupertype.typeArguments, isEmpty);
+  }
+
+  test_getDecoratedSupertype_on_simple() async {
+    await analyze('''
+class Base<T, U> {}
+mixin Derived<V, W> on Base<V, W> {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.mixin('Derived'), findElement.class_('Base'));
+    var vRef = decoratedTypeAnnotation('V, W> {');
+    var wRef = decoratedTypeAnnotation('W> {');
+    expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+    expect(decoratedSupertype.node, same(never));
+    expect(decoratedSupertype.typeArguments, hasLength(2));
+    expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+    expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+    expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+    expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+  }
+
+  test_getDecoratedSupertype_unrelated_type() async {
+    await analyze('''
+class A<T> {}
+class B<T> {}
+''');
+    expect(
+        () => _hierarchy.getDecoratedSupertype(
+            findElement.class_('A'), findElement.class_('B')),
+        throwsA(TypeMatcher<StateError>()));
+  }
+
+  test_getDecoratedSupertype_with_simple() async {
+    await analyze('''
+class Base<T, U> {}
+class Derived<V, W> extends Object with Base<V, W> {}
+''');
+    var decoratedSupertype = _hierarchy.getDecoratedSupertype(
+        findElement.class_('Derived'), findElement.class_('Base'));
+    var vRef = decoratedTypeAnnotation('V, W> {');
+    var wRef = decoratedTypeAnnotation('W> {');
+    expect(decoratedSupertype.type.toString(), 'Base<V, W>');
+    expect(decoratedSupertype.node, same(never));
+    expect(decoratedSupertype.typeArguments, hasLength(2));
+    expect(decoratedSupertype.typeArguments[0].type.toString(), 'V');
+    expect(decoratedSupertype.typeArguments[0].node, same(vRef.node));
+    expect(decoratedSupertype.typeArguments[1].type.toString(), 'W');
+    expect(decoratedSupertype.typeArguments[1].node, same(wRef.node));
+  }
+}
diff --git a/pkg/nnbd_migration/test/decorated_type_test.dart b/pkg/nnbd_migration/test/decorated_type_test.dart
new file mode 100644
index 0000000..bd63ab4
--- /dev/null
+++ b/pkg/nnbd_migration/test/decorated_type_test.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2019, 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:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'abstract_single_unit.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DecoratedTypeTest);
+  });
+}
+
+@reflectiveTest
+class DecoratedTypeTest extends AbstractSingleUnitTest {
+  final _graph = NullabilityGraph();
+
+  NullabilityNode get always => _graph.always;
+
+  @override
+  void setUp() {
+    NullabilityNode.clearDebugNames();
+    super.setUp();
+  }
+
+  test_toString_named_parameter() async {
+    await resolveTestUnit('''dynamic f({int x}) {}''');
+    var type = findElement.function('f').type;
+    var decoratedType = DecoratedType(type, always,
+        namedParameters: {
+          'x': DecoratedType(type.namedParameterTypes['x'], _node(1))
+        },
+        returnType: DecoratedType(type.returnType, always));
+    expect(decoratedType.toString(), 'dynamic Function({x: int?(type(1))})?');
+  }
+
+  test_toString_normal_and_named_parameter() async {
+    await resolveTestUnit('''dynamic f(int x, {int y}) {}''');
+    var type = findElement.function('f').type;
+    var decoratedType = DecoratedType(type, always,
+        positionalParameters: [
+          DecoratedType(type.normalParameterTypes[0], _node(1))
+        ],
+        namedParameters: {
+          'y': DecoratedType(type.namedParameterTypes['y'], _node(2))
+        },
+        returnType: DecoratedType(type.returnType, always));
+    expect(decoratedType.toString(),
+        'dynamic Function(int?(type(1)), {y: int?(type(2))})?');
+  }
+
+  test_toString_normal_and_optional_parameter() async {
+    await resolveTestUnit('''dynamic f(int x, [int y]) {}''');
+    var type = findElement.function('f').type;
+    var decoratedType = DecoratedType(type, always,
+        positionalParameters: [
+          DecoratedType(type.normalParameterTypes[0], _node(1)),
+          DecoratedType(type.optionalParameterTypes[0], _node(2))
+        ],
+        returnType: DecoratedType(type.returnType, always));
+    expect(decoratedType.toString(),
+        'dynamic Function(int?(type(1)), [int?(type(2))])?');
+  }
+
+  test_toString_normal_parameter() async {
+    await resolveTestUnit('''dynamic f(int x) {}''');
+    var type = findElement.function('f').type;
+    var decoratedType = DecoratedType(type, always,
+        positionalParameters: [
+          DecoratedType(type.normalParameterTypes[0], _node(1))
+        ],
+        returnType: DecoratedType(type.returnType, always));
+    expect(decoratedType.toString(), 'dynamic Function(int?(type(1)))?');
+  }
+
+  test_toString_optional_parameter() async {
+    await resolveTestUnit('''dynamic f([int x]) {}''');
+    var type = findElement.function('f').type;
+    var decoratedType = DecoratedType(type, always,
+        positionalParameters: [
+          DecoratedType(type.optionalParameterTypes[0], _node(1))
+        ],
+        returnType: DecoratedType(type.returnType, always));
+    expect(decoratedType.toString(), 'dynamic Function([int?(type(1))])?');
+  }
+
+  NullabilityNode _node(int offset) =>
+      NullabilityNode.forTypeAnnotation(offset);
+}
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
new file mode 100644
index 0000000..0996ae3
--- /dev/null
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -0,0 +1,2805 @@
+// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/edge_builder.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(EdgeBuilderTest);
+  });
+}
+
+@reflectiveTest
+class EdgeBuilderTest extends MigrationVisitorTestBase {
+  /// Analyzes the given source code, producing constraint variables and
+  /// constraints for it.
+  @override
+  Future<CompilationUnit> analyze(String code) async {
+    var unit = await super.analyze(code);
+    unit.accept(EdgeBuilder(
+        typeProvider, typeSystem, variables, graph, testSource, null));
+    return unit;
+  }
+
+  void assertGLB(
+      NullabilityNode node, NullabilityNode left, NullabilityNode right) {
+    expect(node, isNot(TypeMatcher<NullabilityNodeForLUB>()));
+    assertEdge(left, node, hard: false, guards: [right]);
+    assertEdge(node, left, hard: false);
+    assertEdge(node, right, hard: false);
+  }
+
+  void assertLUB(
+      NullabilityNode node, NullabilityNode left, NullabilityNode right) {
+    var conditionalNode = node as NullabilityNodeForLUB;
+    expect(conditionalNode.left, same(left));
+    expect(conditionalNode.right, same(right));
+  }
+
+  /// Checks that there are no nullability nodes upstream from [node] that could
+  /// cause it to become nullable.
+  void assertNoUpstreamNullability(NullabilityNode node) {
+    // never can never become nullable, even if it has nodes
+    // upstream from it.
+    if (node == never) return;
+
+    for (var edge in graph.getUpstreamEdges(node)) {
+      expect(edge.primarySource, never);
+    }
+  }
+
+  /// Verifies that a null check will occur when the given edge is unsatisfied.
+  ///
+  /// [expressionChecks] is the object tracking whether or not a null check is
+  /// needed.
+  void assertNullCheck(
+      ExpressionChecks expressionChecks, NullabilityEdge expectedEdge) {
+    expect(expressionChecks.edges, contains(expectedEdge));
+  }
+
+  /// Gets the [ExpressionChecks] associated with the expression whose text
+  /// representation is [text], or `null` if the expression has no
+  /// [ExpressionChecks] associated with it.
+  ExpressionChecks checkExpression(String text) {
+    return variables.checkExpression(findNode.expression(text));
+  }
+
+  /// Gets the [DecoratedType] associated with the expression whose text
+  /// representation is [text], or `null` if the expression has no
+  /// [DecoratedType] associated with it.
+  DecoratedType decoratedExpressionType(String text) {
+    return variables.decoratedExpressionType(findNode.expression(text));
+  }
+
+  test_assert_demonstrates_non_null_intent() async {
+    await analyze('''
+void f(int i) {
+  assert(i != null);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+  }
+
+  test_assignmentExpression_field() async {
+    await analyze('''
+class C {
+  int x = 0;
+}
+void f(C c, int i) {
+  c.x = i;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_field_cascaded() async {
+    await analyze('''
+class C {
+  int x = 0;
+}
+void f(C c, int i) {
+  c..x = i;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_field_target_check() async {
+    await analyze('''
+class C {
+  int x = 0;
+}
+void f(C c, int i) {
+  c.x = i;
+}
+''');
+    assertNullCheck(checkExpression('c.x'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_assignmentExpression_field_target_check_cascaded() async {
+    await analyze('''
+class C {
+  int x = 0;
+}
+void f(C c, int i) {
+  c..x = i;
+}
+''');
+    assertNullCheck(checkExpression('c..x'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_assignmentExpression_indexExpression_index() async {
+    await analyze('''
+class C {
+  void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+  c[i] = j;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int a').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_indexExpression_return_value() async {
+    await analyze('''
+class C {
+  void operator[]=(int a, int b) {}
+}
+int f(C c, int i, int j) => c[i] = j;
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int f').node,
+        hard: false);
+  }
+
+  test_assignmentExpression_indexExpression_target_check() async {
+    await analyze('''
+class C {
+  void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+  c[i] = j;
+}
+''');
+    assertNullCheck(checkExpression('c['),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_assignmentExpression_indexExpression_value() async {
+    await analyze('''
+class C {
+  void operator[]=(int a, int b) {}
+}
+void f(C c, int i, int j) {
+  c[i] = j;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int b').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_operands() async {
+    await analyze('''
+void f(int i, int j) {
+  i = j;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int i').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_return_value() async {
+    await analyze('''
+void f(int i, int j) {
+  g(i = j);
+}
+void g(int k) {}
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int k').node,
+        hard: false);
+  }
+
+  test_assignmentExpression_setter() async {
+    await analyze('''
+class C {
+  void set s(int value) {}
+}
+void f(C c, int i) {
+  c.s = i;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int value').node,
+        hard: true);
+  }
+
+  test_assignmentExpression_setter_null_aware() async {
+    await analyze('''
+class C {
+  void set s(int value) {}
+}
+int f(C c, int i) => (c?.s = i);
+''');
+    var lubNode =
+        decoratedExpressionType('(c?.s = i)').node as NullabilityNodeForLUB;
+    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+    expect(lubNode.right, same(decoratedTypeAnnotation('int i').node));
+    assertEdge(lubNode, decoratedTypeAnnotation('int f').node, hard: false);
+  }
+
+  test_assignmentExpression_setter_target_check() async {
+    await analyze('''
+class C {
+  void set s(int value) {}
+}
+void f(C c, int i) {
+  c.s = i;
+}
+''');
+    assertNullCheck(checkExpression('c.s'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  @failingTest
+  test_awaitExpression_future_nonNullable() async {
+    await analyze('''
+Future<void> f() async {
+  int x = await g();
+}
+Future<int> g() async => 3;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  @failingTest
+  test_awaitExpression_future_nullable() async {
+    await analyze('''
+Future<void> f() async {
+  int x = await g();
+}
+Future<int> g() async => null;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_awaitExpression_nonFuture() async {
+    await analyze('''
+Future<void> f() async {
+  int x = await 3;
+}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_binaryExpression_ampersand_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i & j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_ampersandAmpersand() async {
+    await analyze('''
+bool f(bool i, bool j) => i && j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool i').node);
+  }
+
+  test_binaryExpression_bar_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i | j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_barBar() async {
+    await analyze('''
+bool f(bool i, bool j) => i || j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool i').node);
+  }
+
+  test_binaryExpression_caret_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i ^ j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_equal() async {
+    await analyze('''
+bool f(int i, int j) => i == j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_gt_result_not_null() async {
+    await analyze('''
+bool f(int i, int j) => i > j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_gtEq_result_not_null() async {
+    await analyze('''
+bool f(int i, int j) => i >= j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_gtGt_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i >> j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_lt_result_not_null() async {
+    await analyze('''
+bool f(int i, int j) => i < j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_ltEq_result_not_null() async {
+    await analyze('''
+bool f(int i, int j) => i <= j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_ltLt_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i << j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_minus_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i - j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_notEqual() async {
+    await analyze('''
+bool f(int i, int j) => i != j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
+  }
+
+  test_binaryExpression_percent_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i % j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_plus_left_check() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertNullCheck(checkExpression('i +'),
+        assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true));
+  }
+
+  test_binaryExpression_plus_left_check_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j;
+''');
+
+    assertNullCheck(checkExpression('i +'),
+        assertEdge(decoratedTypeAnnotation('Int i').node, never, hard: true));
+  }
+
+  test_binaryExpression_plus_result_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => (i + j);
+''');
+
+    assertNullCheck(
+        checkExpression('(i + j)'),
+        assertEdge(decoratedTypeAnnotation('Int operator+').node,
+            decoratedTypeAnnotation('Int f').node,
+            hard: false));
+  }
+
+  test_binaryExpression_plus_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_plus_right_check() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertNullCheck(checkExpression('j;'),
+        assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true));
+  }
+
+  test_binaryExpression_plus_right_check_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j/*check*/;
+''');
+
+    assertNullCheck(
+        checkExpression('j/*check*/'),
+        assertEdge(decoratedTypeAnnotation('Int j').node,
+            decoratedTypeAnnotation('Int other').node,
+            hard: true));
+  }
+
+  test_binaryExpression_questionQuestion() async {
+    await analyze('''
+int f(int i, int j) => i ?? j;
+''');
+
+    var left = decoratedTypeAnnotation('int i').node;
+    var right = decoratedTypeAnnotation('int j').node;
+    var expression = decoratedExpressionType('??').node;
+    assertEdge(right, expression, guards: [left], hard: false);
+  }
+
+  test_binaryExpression_slash_result_not_null() async {
+    await analyze('''
+double f(int i, int j) => i / j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('double f').node);
+  }
+
+  test_binaryExpression_star_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i * j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_binaryExpression_tildeSlash_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i ~/ j;
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
+  }
+
+  test_boolLiteral() async {
+    await analyze('''
+bool f() {
+  return true;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+  }
+
+  test_cascadeExpression() async {
+    await analyze('''
+class C {
+  int x = 0;
+}
+C f(C c, int i) => c..x = i;
+''');
+    assertEdge(decoratedTypeAnnotation('C c').node,
+        decoratedTypeAnnotation('C f').node,
+        hard: false);
+  }
+
+  test_catch_clause() async {
+    await analyze('''
+foo() => 1;
+main() {
+  try { foo(); } on Exception catch (e) { print(e); }
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_catch_clause_no_type() async {
+    await analyze('''
+foo() => 1;
+main() {
+  try { foo(); } catch (e) { print(e); }
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_class_alias_synthetic_constructor_with_parameters_complex() async {
+    await analyze('''
+class MyList<T> {}
+class C {
+  C(MyList<int>/*1*/ x);
+}
+mixin M {}
+class D = C with M;
+D f(MyList<int>/*2*/ x) => D(x);
+''');
+    var syntheticConstructor = findElement.unnamedConstructor('D');
+    var constructorType = variables.decoratedElementType(syntheticConstructor);
+    var constructorParameterType = constructorType.positionalParameters[0];
+    assertEdge(decoratedTypeAnnotation('MyList<int>/*2*/').node,
+        constructorParameterType.node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int>/*2*/').node,
+        constructorParameterType.typeArguments[0].node,
+        hard: false);
+    assertUnion(constructorParameterType.node,
+        decoratedTypeAnnotation('MyList<int>/*1*/').node);
+    assertUnion(constructorParameterType.typeArguments[0].node,
+        decoratedTypeAnnotation('int>/*1*/').node);
+  }
+
+  test_class_alias_synthetic_constructor_with_parameters_generic() async {
+    await analyze('''
+class C<T> {
+  C(T t);
+}
+mixin M {}
+class D<U> = C<U> with M;
+''');
+    var syntheticConstructor = findElement.unnamedConstructor('D');
+    var constructorType = variables.decoratedElementType(syntheticConstructor);
+    var constructorParameterType = constructorType.positionalParameters[0];
+    assertUnion(
+        constructorParameterType.node, decoratedTypeAnnotation('T t').node);
+  }
+
+  test_class_alias_synthetic_constructor_with_parameters_named() async {
+    await analyze('''
+class C {
+  C({int/*1*/ i});
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i: i);
+''');
+    var syntheticConstructor = findElement.unnamedConstructor('D');
+    var constructorType = variables.decoratedElementType(syntheticConstructor);
+    var constructorParameterType = constructorType.namedParameters['i'];
+    assertEdge(
+        decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+        hard: true);
+    assertUnion(constructorParameterType.node,
+        decoratedTypeAnnotation('int/*1*/').node);
+  }
+
+  test_class_alias_synthetic_constructor_with_parameters_optional() async {
+    await analyze('''
+class C {
+  C([int/*1*/ i]);
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i);
+''');
+    var syntheticConstructor = findElement.unnamedConstructor('D');
+    var constructorType = variables.decoratedElementType(syntheticConstructor);
+    var constructorParameterType = constructorType.positionalParameters[0];
+    assertEdge(
+        decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+        hard: true);
+    assertUnion(constructorParameterType.node,
+        decoratedTypeAnnotation('int/*1*/').node);
+  }
+
+  test_class_alias_synthetic_constructor_with_parameters_required() async {
+    await analyze('''
+class C {
+  C(int/*1*/ i);
+}
+mixin M {}
+class D = C with M;
+D f(int/*2*/ i) => D(i);
+''');
+    var syntheticConstructor = findElement.unnamedConstructor('D');
+    var constructorType = variables.decoratedElementType(syntheticConstructor);
+    var constructorParameterType = constructorType.positionalParameters[0];
+    assertEdge(
+        decoratedTypeAnnotation('int/*2*/').node, constructorParameterType.node,
+        hard: true);
+    assertUnion(constructorParameterType.node,
+        decoratedTypeAnnotation('int/*1*/').node);
+  }
+
+  test_conditionalExpression_condition_check() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  return (b ? i : j);
+}
+''');
+
+    var nullable_b = decoratedTypeAnnotation('bool b').node;
+    var check_b = checkExpression('b ?');
+    assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
+  }
+
+  test_conditionalExpression_functionTyped_namedParameter() async {
+    await analyze('''
+void f(bool b, void Function({int p}) x, void Function({int p}) y) {
+  (b ? x : y);
+}
+''');
+    var xType =
+        decoratedGenericFunctionTypeAnnotation('void Function({int p}) x');
+    var yType =
+        decoratedGenericFunctionTypeAnnotation('void Function({int p}) y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertGLB(resultType.namedParameters['p'].node,
+        xType.namedParameters['p'].node, yType.namedParameters['p'].node);
+  }
+
+  test_conditionalExpression_functionTyped_normalParameter() async {
+    await analyze('''
+void f(bool b, void Function(int) x, void Function(int) y) {
+  (b ? x : y);
+}
+''');
+    var xType = decoratedGenericFunctionTypeAnnotation('void Function(int) x');
+    var yType = decoratedGenericFunctionTypeAnnotation('void Function(int) y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertGLB(resultType.positionalParameters[0].node,
+        xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+  }
+
+  test_conditionalExpression_functionTyped_normalParameters() async {
+    await analyze('''
+void f(bool b, void Function(int, int) x, void Function(int, int) y) {
+  (b ? x : y);
+}
+''');
+    var xType =
+        decoratedGenericFunctionTypeAnnotation('void Function(int, int) x');
+    var yType =
+        decoratedGenericFunctionTypeAnnotation('void Function(int, int) y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertGLB(resultType.positionalParameters[0].node,
+        xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+    assertGLB(resultType.positionalParameters[1].node,
+        xType.positionalParameters[1].node, yType.positionalParameters[1].node);
+  }
+
+  test_conditionalExpression_functionTyped_optionalParameter() async {
+    await analyze('''
+void f(bool b, void Function([int]) x, void Function([int]) y) {
+  (b ? x : y);
+}
+''');
+    var xType =
+        decoratedGenericFunctionTypeAnnotation('void Function([int]) x');
+    var yType =
+        decoratedGenericFunctionTypeAnnotation('void Function([int]) y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertGLB(resultType.positionalParameters[0].node,
+        xType.positionalParameters[0].node, yType.positionalParameters[0].node);
+  }
+
+  test_conditionalExpression_functionTyped_returnType() async {
+    await analyze('''
+void f(bool b, int Function() x, int Function() y) {
+  (b ? x : y);
+}
+''');
+    var xType = decoratedGenericFunctionTypeAnnotation('int Function() x');
+    var yType = decoratedGenericFunctionTypeAnnotation('int Function() y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertLUB(resultType.returnType.node, xType.returnType.node,
+        yType.returnType.node);
+  }
+
+  test_conditionalExpression_functionTyped_returnType_void() async {
+    await analyze('''
+void f(bool b, void Function() x, void Function() y) {
+  (b ? x : y);
+}
+''');
+    var xType = decoratedGenericFunctionTypeAnnotation('void Function() x');
+    var yType = decoratedGenericFunctionTypeAnnotation('void Function() y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    expect(resultType.returnType.node, same(always));
+  }
+
+  test_conditionalExpression_general() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  return (b ? i : j);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    var nullable_conditional = decoratedExpressionType('(b ?').node;
+    assertLUB(nullable_conditional, nullable_i, nullable_j);
+    var nullable_return = decoratedTypeAnnotation('int f').node;
+    assertNullCheck(checkExpression('(b ? i : j)'),
+        assertEdge(nullable_conditional, nullable_return, hard: false));
+  }
+
+  test_conditionalExpression_generic() async {
+    await analyze('''
+void f(bool b, Map<int, String> x, Map<int, String> y) {
+  (b ? x : y);
+}
+''');
+    var xType = decoratedTypeAnnotation('Map<int, String> x');
+    var yType = decoratedTypeAnnotation('Map<int, String> y');
+    var resultType = decoratedExpressionType('(b ?');
+    assertLUB(resultType.node, xType.node, yType.node);
+    assertLUB(resultType.typeArguments[0].node, xType.typeArguments[0].node,
+        yType.typeArguments[0].node);
+    assertLUB(resultType.typeArguments[1].node, xType.typeArguments[1].node,
+        yType.typeArguments[1].node);
+  }
+
+  test_conditionalExpression_left_non_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? (throw i) : i);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_conditional =
+        decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
+    var nullable_throw = nullable_conditional.left;
+    assertNoUpstreamNullability(nullable_throw);
+    assertLUB(nullable_conditional, nullable_throw, nullable_i);
+  }
+
+  test_conditionalExpression_left_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? null : i);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_conditional = decoratedExpressionType('(b ?').node;
+    assertLUB(nullable_conditional, always, nullable_i);
+  }
+
+  test_conditionalExpression_right_non_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? i : (throw i));
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_conditional =
+        decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
+    var nullable_throw = nullable_conditional.right;
+    assertNoUpstreamNullability(nullable_throw);
+    assertLUB(nullable_conditional, nullable_i, nullable_throw);
+  }
+
+  test_conditionalExpression_right_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? i : null);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_conditional = decoratedExpressionType('(b ?').node;
+    assertLUB(nullable_conditional, nullable_i, always);
+  }
+
+  test_constructor_named() async {
+    await analyze('''
+class C {
+  C.named();
+}
+''');
+    // No assertions; just need to make sure that the test doesn't cause an
+    // exception to be thrown.
+  }
+
+  test_constructorDeclaration_returnType_generic() async {
+    await analyze('''
+class C<T, U> {
+  C();
+}
+''');
+    var constructor = findElement.unnamedConstructor('C');
+    var constructorDecoratedType = variables.decoratedElementType(constructor);
+    expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
+    expect(constructorDecoratedType.node, same(never));
+    expect(constructorDecoratedType.typeFormals, isEmpty);
+    expect(constructorDecoratedType.returnType.node, same(never));
+    expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
+    var typeArguments = constructorDecoratedType.returnType.typeArguments;
+    expect(typeArguments, hasLength(2));
+    expect(typeArguments[0].type.toString(), 'T');
+    expect(typeArguments[0].node, same(never));
+    expect(typeArguments[1].type.toString(), 'U');
+    expect(typeArguments[1].node, same(never));
+  }
+
+  test_constructorDeclaration_returnType_generic_implicit() async {
+    await analyze('''
+class C<T, U> {}
+''');
+    var constructor = findElement.unnamedConstructor('C');
+    var constructorDecoratedType = variables.decoratedElementType(constructor);
+    expect(constructorDecoratedType.type.toString(), 'C<T, U> Function()');
+    expect(constructorDecoratedType.node, same(never));
+    expect(constructorDecoratedType.typeFormals, isEmpty);
+    expect(constructorDecoratedType.returnType.node, same(never));
+    expect(constructorDecoratedType.returnType.type.toString(), 'C<T, U>');
+    var typeArguments = constructorDecoratedType.returnType.typeArguments;
+    expect(typeArguments, hasLength(2));
+    expect(typeArguments[0].type.toString(), 'T');
+    expect(typeArguments[0].node, same(never));
+    expect(typeArguments[1].type.toString(), 'U');
+    expect(typeArguments[1].node, same(never));
+  }
+
+  test_constructorDeclaration_returnType_simple() async {
+    await analyze('''
+class C {
+  C();
+}
+''');
+    var constructorDecoratedType =
+        variables.decoratedElementType(findElement.unnamedConstructor('C'));
+    expect(constructorDecoratedType.type.toString(), 'C Function()');
+    expect(constructorDecoratedType.node, same(never));
+    expect(constructorDecoratedType.typeFormals, isEmpty);
+    expect(constructorDecoratedType.returnType.node, same(never));
+    expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
+  }
+
+  test_constructorDeclaration_returnType_simple_implicit() async {
+    await analyze('''
+class C {}
+''');
+    var constructorDecoratedType =
+        variables.decoratedElementType(findElement.unnamedConstructor('C'));
+    expect(constructorDecoratedType.type.toString(), 'C Function()');
+    expect(constructorDecoratedType.node, same(never));
+    expect(constructorDecoratedType.typeFormals, isEmpty);
+    expect(constructorDecoratedType.returnType.node, same(never));
+    expect(constructorDecoratedType.returnType.typeArguments, isEmpty);
+  }
+
+  test_doubleLiteral() async {
+    await analyze('''
+double f() {
+  return 1.0;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
+  }
+
+  test_field_type_inferred() async {
+    await analyze('''
+int f() => 1;
+class C {
+  var x = f();
+}
+''');
+    var xType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+  }
+
+  test_fieldFormalParameter_function_typed() async {
+    await analyze('''
+class C {
+  int Function(int, {int j}) f;
+  C(int this.f(int i, {int j}));
+}
+''');
+    var ctorParamType = variables
+        .decoratedElementType(findElement.unnamedConstructor('C'))
+        .positionalParameters[0];
+    var fieldType = variables.decoratedElementType(findElement.field('f'));
+    assertEdge(ctorParamType.node, fieldType.node, hard: true);
+    assertEdge(ctorParamType.returnType.node, fieldType.returnType.node,
+        hard: true);
+    assertEdge(fieldType.positionalParameters[0].node,
+        ctorParamType.positionalParameters[0].node,
+        hard: true);
+    assertEdge(fieldType.namedParameters['j'].node,
+        ctorParamType.namedParameters['j'].node,
+        hard: true);
+  }
+
+  test_fieldFormalParameter_typed() async {
+    await analyze('''
+class C {
+  int i;
+  C(int this.i);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int this').node,
+        decoratedTypeAnnotation('int i').node,
+        hard: true);
+  }
+
+  test_fieldFormalParameter_untyped() async {
+    await analyze('''
+class C {
+  int i;
+  C.named(this.i);
+}
+''');
+    var decoratedConstructorParamType =
+        decoratedConstructorDeclaration('named').positionalParameters[0];
+    assertUnion(decoratedConstructorParamType.node,
+        decoratedTypeAnnotation('int i').node);
+  }
+
+  test_for_with_declaration() async {
+    await analyze('''
+main() {
+  for (int i in <int>[1, 2, 3]) { print(i); }
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_for_with_var() async {
+    await analyze('''
+main() {
+  for (var i in <int>[1, 2, 3]) { print(i); }
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_function_assignment() async {
+    await analyze('''
+class C {
+  void f1(String message) {}
+  void f2(String message) {}
+}
+foo(C c, bool flag) {
+  Function(String message) out = flag ? c.f1 : c.f2;
+  out('hello');
+}
+bar() {
+  foo(C(), true);
+  foo(C(), false);
+}
+''');
+    var type = decoratedTypeAnnotation('Function(String message)');
+    expect(type.returnType, isNotNull);
+  }
+
+  test_functionDeclaration_expression_body() async {
+    await analyze('''
+int/*1*/ f(int/*2*/ i) => i/*3*/;
+''');
+
+    assertNullCheck(
+        checkExpression('i/*3*/'),
+        assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+            decoratedTypeAnnotation('int/*1*/').node,
+            hard: true));
+  }
+
+  test_functionDeclaration_parameter_named_default_listConst() async {
+    await analyze('''
+void f({List<int/*1*/> i = const <int/*2*/>[]}) {}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('List<int/*1*/>').node);
+    assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+        decoratedTypeAnnotation('int/*1*/').node,
+        hard: false);
+  }
+
+  test_functionDeclaration_parameter_named_default_notNull() async {
+    await analyze('''
+void f({int i = 1}) {}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_functionDeclaration_parameter_named_default_null() async {
+    await analyze('''
+void f({int i = null}) {}
+''');
+
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_functionDeclaration_parameter_named_no_default() async {
+    await analyze('''
+void f({int i}) {}
+''');
+
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_functionDeclaration_parameter_named_no_default_required() async {
+    addMetaPackage();
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
+    await analyze('''
+void f([int i = 1]) {}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_default_null() async {
+    await analyze('''
+void f([int i = null]) {}
+''');
+
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_no_default() async {
+    await analyze('''
+void f([int i]) {}
+''');
+
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_functionDeclaration_resets_unconditional_control_flow() async {
+    await analyze('''
+void f(bool b, int i, int j) {
+  assert(i != null);
+  if (b) return;
+  assert(j != null);
+}
+void g(int k) {
+  assert(k != null);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
+    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
+  }
+
+  test_functionExpressionInvocation_parameterType() async {
+    await analyze('''
+abstract class C {
+  void Function(int) f();
+}
+void g(C c, int i) {
+  c.f()(i);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int)').node,
+        hard: true);
+  }
+
+  test_functionExpressionInvocation_returnType() async {
+    await analyze('''
+abstract class C {
+  int Function() f();
+}
+int g(C c) => c.f()();
+''');
+    assertEdge(decoratedTypeAnnotation('int Function').node,
+        decoratedTypeAnnotation('int g').node,
+        hard: false);
+  }
+
+  test_functionInvocation_parameter_fromLocalParameter() async {
+    await analyze('''
+void f(int/*1*/ i) {}
+void test(int/*2*/ i) {
+  f(i/*3*/);
+}
+''');
+
+    var int_1 = decoratedTypeAnnotation('int/*1*/');
+    var int_2 = decoratedTypeAnnotation('int/*2*/');
+    var i_3 = checkExpression('i/*3*/');
+    assertNullCheck(i_3, assertEdge(int_2.node, int_1.node, hard: true));
+    assertEdge(int_2.node, int_1.node, hard: true);
+  }
+
+  test_functionInvocation_parameter_named() async {
+    await analyze('''
+void f({int i: 0}) {}
+void g(int j) {
+  f(i: j/*check*/);
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    assertNullCheck(checkExpression('j/*check*/'),
+        assertEdge(nullable_j, nullable_i, hard: true));
+  }
+
+  test_functionInvocation_parameter_named_missing() async {
+    await analyze('''
+void f({int i}) {}
+void g() {
+  f();
+}
+''');
+    var optional_i = possiblyOptionalParameter('int i');
+    expect(getEdges(always, optional_i), isNotEmpty);
+  }
+
+  test_functionInvocation_parameter_named_missing_required() async {
+    addMetaPackage();
+    verifyNoTestUnitErrors = false;
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+void g() {
+  f();
+}
+''');
+    // The call at `f()` is presumed to be in error; no constraint is recorded.
+    var optional_i = possiblyOptionalParameter('int i');
+    expect(optional_i, isNull);
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    assertNoUpstreamNullability(nullable_i);
+  }
+
+  test_functionInvocation_parameter_null() async {
+    await analyze('''
+void f(int i) {}
+void test() {
+  f(null);
+}
+''');
+
+    assertNullCheck(checkExpression('null'),
+        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+  }
+
+  test_functionInvocation_return() async {
+    await analyze('''
+int/*1*/ f() => 0;
+int/*2*/ g() {
+  return (f());
+}
+''');
+
+    assertNullCheck(
+        checkExpression('(f())'),
+        assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+            decoratedTypeAnnotation('int/*2*/').node,
+            hard: false));
+  }
+
+  test_if_condition() async {
+    await analyze('''
+void f(bool b) {
+  if (b) {}
+}
+''');
+
+    assertNullCheck(checkExpression('b) {}'),
+        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
+  }
+
+  test_if_conditional_control_flow_after() async {
+    // Asserts after ifs don't demonstrate non-null intent.
+    // TODO(paulberry): if both branches complete normally, they should.
+    await analyze('''
+void f(bool b, int i) {
+  if (b) return;
+  assert(i != null);
+}
+''');
+
+    assertNoEdge(always, decoratedTypeAnnotation('int i').node);
+  }
+
+  test_if_conditional_control_flow_within() async {
+    // Asserts inside ifs don't demonstrate non-null intent.
+    await analyze('''
+void f(bool b, int i) {
+  if (b) {
+    assert(i != null);
+  } else {
+    assert(i != null);
+  }
+}
+''');
+
+    assertNoEdge(always, decoratedTypeAnnotation('int i').node);
+  }
+
+  test_if_guard_equals_null() async {
+    await analyze('''
+int f(int i, int j, int k) {
+  if (i == null) {
+    return j/*check*/;
+  } else {
+    return k/*check*/;
+  }
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    var nullable_k = decoratedTypeAnnotation('int k').node;
+    var nullable_return = decoratedTypeAnnotation('int f').node;
+    assertNullCheck(
+        checkExpression('j/*check*/'),
+        assertEdge(nullable_j, nullable_return,
+            guards: [nullable_i], hard: false));
+    assertNullCheck(checkExpression('k/*check*/'),
+        assertEdge(nullable_k, nullable_return, hard: false));
+    var discard = statementDiscard('if (i == null)');
+    expect(discard.trueGuard, same(nullable_i));
+    expect(discard.falseGuard, null);
+    expect(discard.pureCondition, true);
+  }
+
+  test_if_simple() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  if (b) {
+    return i/*check*/;
+  } else {
+    return j/*check*/;
+  }
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    var nullable_return = decoratedTypeAnnotation('int f').node;
+    assertNullCheck(checkExpression('i/*check*/'),
+        assertEdge(nullable_i, nullable_return, hard: false));
+    assertNullCheck(checkExpression('j/*check*/'),
+        assertEdge(nullable_j, nullable_return, hard: false));
+  }
+
+  test_if_without_else() async {
+    await analyze('''
+int f(bool b, int i) {
+  if (b) {
+    return i/*check*/;
+  }
+  return 0;
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_return = decoratedTypeAnnotation('int f').node;
+    assertNullCheck(checkExpression('i/*check*/'),
+        assertEdge(nullable_i, nullable_return, hard: false));
+  }
+
+  test_indexExpression_index() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+int f(C c, int j) => c[j];
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int i').node,
+        hard: true);
+  }
+
+  test_indexExpression_index_cascaded() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+C f(C c, int j) => c..[j];
+''');
+    assertEdge(decoratedTypeAnnotation('int j').node,
+        decoratedTypeAnnotation('int i').node,
+        hard: true);
+  }
+
+  test_indexExpression_return_type() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+    assertEdge(decoratedTypeAnnotation('int operator').node,
+        decoratedTypeAnnotation('int f').node,
+        hard: false);
+  }
+
+  test_indexExpression_target_check() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+    assertNullCheck(checkExpression('c['),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_indexExpression_target_check_cascaded() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+C f(C c) => c..[0];
+''');
+    assertNullCheck(checkExpression('c..['),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_indexExpression_target_demonstrates_non_null_intent() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+int f(C c) => c[0];
+''');
+    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+  }
+
+  test_indexExpression_target_demonstrates_non_null_intent_cascaded() async {
+    await analyze('''
+class C {
+  int operator[](int i) => 1;
+}
+C f(C c) => c..[0];
+''');
+    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+  }
+
+  test_instanceCreation_generic() async {
+    await analyze('''
+class C<T> {}
+C<int> f() => C<int>();
+''');
+    assertEdge(decoratedTypeAnnotation('int>(').node,
+        decoratedTypeAnnotation('int> f').node,
+        hard: false);
+  }
+
+  test_instanceCreation_generic_parameter() async {
+    await analyze('''
+class C<T> {
+  C(T t);
+}
+f(int i) => C<int>(i/*check*/);
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
+    var nullable_t = decoratedTypeAnnotation('T t').node;
+    var check_i = checkExpression('i/*check*/');
+    var nullable_c_t_or_nullable_t =
+        check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
+    expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
+    assertNullCheck(check_i,
+        assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
+  }
+
+  test_instanceCreation_parameter_named_optional() async {
+    await analyze('''
+class C {
+  C({int x = 0});
+}
+void f(int y) {
+  C(x: y);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int y').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_instanceCreation_parameter_positional_optional() async {
+    await analyze('''
+class C {
+  C([int x]);
+}
+void f(int y) {
+  C(y);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int y').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_instanceCreation_parameter_positional_required() async {
+    await analyze('''
+class C {
+  C(int x);
+}
+void f(int y) {
+  C(y);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int y').node,
+        decoratedTypeAnnotation('int x').node,
+        hard: true);
+  }
+
+  test_integerLiteral() async {
+    await analyze('''
+int f() {
+  return 0;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  @failingTest
+  test_isExpression_genericFunctionType() async {
+    await analyze('''
+bool f(a) => a is int Function(String);
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+  }
+
+  test_isExpression_typeName_noTypeArguments() async {
+    await analyze('''
+bool f(a) => a is String;
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+  }
+
+  @failingTest
+  test_isExpression_typeName_typeArguments() async {
+    await analyze('''
+bool f(a) => a is List<int>;
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
+  }
+
+  test_libraryDirective() async {
+    await analyze('''
+library foo;
+''');
+    // Passes if no exceptions are thrown.
+  }
+
+  @failingTest
+  test_listLiteral_noTypeArgument_noNullableElements() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+List<String> f() {
+  return ['a', 'b'];
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+    // TODO(brianwilkerson) Add an assertion that there is an edge from the list
+    //  literal's fake type argument to the return type's type argument.
+  }
+
+  @failingTest
+  test_listLiteral_noTypeArgument_nullableElement() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+List<String> f() {
+  return ['a', null, 'c'];
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+  }
+
+  test_listLiteral_typeArgument_noNullableElements() async {
+    await analyze('''
+List<String> f() {
+  return <String>['a', 'b'];
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+    var typeArgForLiteral = decoratedTypeAnnotation('String>[').node;
+    var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
+    assertNoUpstreamNullability(typeArgForLiteral);
+    assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
+  }
+
+  test_listLiteral_typeArgument_nullableElement() async {
+    await analyze('''
+List<String> f() {
+  return <String>['a', null, 'c'];
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
+    assertEdge(always, decoratedTypeAnnotation('String>[').node, hard: false);
+  }
+
+  test_localVariable_type_inferred() async {
+    await analyze('''
+int f() => 1;
+main() {
+  var x = f();
+}
+''');
+    var xType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+  }
+
+  test_method_parameterType_inferred() async {
+    await analyze('''
+class B {
+  void f/*B*/(int x) {}
+}
+class C extends B {
+  void f/*C*/(x) {}
+}
+''');
+    var bReturnType = decoratedMethodType('f/*B*/').positionalParameters[0];
+    var cReturnType = decoratedMethodType('f/*C*/').positionalParameters[0];
+    assertUnion(bReturnType.node, cReturnType.node);
+  }
+
+  test_method_parameterType_inferred_named() async {
+    await analyze('''
+class B {
+  void f/*B*/({int x = 0}) {}
+}
+class C extends B {
+  void f/*C*/({x = 0}) {}
+}
+''');
+    var bReturnType = decoratedMethodType('f/*B*/').namedParameters['x'];
+    var cReturnType = decoratedMethodType('f/*C*/').namedParameters['x'];
+    assertUnion(bReturnType.node, cReturnType.node);
+  }
+
+  test_method_returnType_inferred() async {
+    await analyze('''
+class B {
+  int f/*B*/() => 1;
+}
+class C extends B {
+  f/*C*/() => 1;
+}
+''');
+    var bReturnType = decoratedMethodType('f/*B*/').returnType;
+    var cReturnType = decoratedMethodType('f/*C*/').returnType;
+    assertUnion(bReturnType.node, cReturnType.node);
+  }
+
+  test_methodDeclaration_resets_unconditional_control_flow() async {
+    await analyze('''
+class C {
+  void f(bool b, int i, int j) {
+    assert(i != null);
+    if (b) return;
+    assert(j != null);
+  }
+  void g(int k) {
+    assert(k != null);
+  }
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
+    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
+    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
+  }
+
+  test_methodInvocation_parameter_contravariant() async {
+    await analyze('''
+class C<T> {
+  void f(T t) {}
+}
+void g(C<int> c, int i) {
+  c.f(i/*check*/);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
+    var nullable_t = decoratedTypeAnnotation('T t').node;
+    var check_i = checkExpression('i/*check*/');
+    var nullable_c_t_or_nullable_t =
+        check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
+    expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
+    assertNullCheck(check_i,
+        assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
+  }
+
+  test_methodInvocation_parameter_contravariant_from_migrated_class() async {
+    await analyze('''
+void f(List<int> x, int i) {
+  x.add(i/*check*/);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_list_t =
+        decoratedTypeAnnotation('List<int>').typeArguments[0].node;
+    var addMethod = findNode.methodInvocation('x.add').methodName.staticElement
+        as MethodMember;
+    var nullable_t = variables
+        .decoratedElementType(addMethod.baseElement)
+        .positionalParameters[0]
+        .node;
+    expect(nullable_t, same(never));
+    var check_i = checkExpression('i/*check*/');
+    var nullable_list_t_or_nullable_t =
+        check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_list_t_or_nullable_t.innerNode, same(nullable_list_t));
+    expect(nullable_list_t_or_nullable_t.outerNode, same(nullable_t));
+    assertNullCheck(check_i,
+        assertEdge(nullable_i, nullable_list_t_or_nullable_t, hard: true));
+  }
+
+  test_methodInvocation_parameter_contravariant_function() async {
+    await analyze('''
+void f<T>(T t) {}
+void g(int i) {
+  f<int>(i/*check*/);
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_f_t = decoratedTypeAnnotation('int>').node;
+    var nullable_t = decoratedTypeAnnotation('T t').node;
+    var check_i = checkExpression('i/*check*/');
+    var nullable_f_t_or_nullable_t =
+        check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
+    expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
+    assertNullCheck(check_i,
+        assertEdge(nullable_i, nullable_f_t_or_nullable_t, hard: true));
+  }
+
+  test_methodInvocation_parameter_generic() async {
+    await analyze('''
+class C<T> {}
+void f(C<int/*1*/>/*2*/ c) {}
+void g(C<int/*3*/>/*4*/ c) {
+  f(c/*check*/);
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int/*3*/').node,
+        decoratedTypeAnnotation('int/*1*/').node,
+        hard: false);
+    assertNullCheck(
+        checkExpression('c/*check*/'),
+        assertEdge(decoratedTypeAnnotation('C<int/*3*/>/*4*/').node,
+            decoratedTypeAnnotation('C<int/*1*/>/*2*/').node,
+            hard: true));
+  }
+
+  test_methodInvocation_parameter_named() async {
+    await analyze('''
+class C {
+  void f({int i: 0}) {}
+}
+void g(C c, int j) {
+  c.f(i: j/*check*/);
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').node;
+    var nullable_j = decoratedTypeAnnotation('int j').node;
+    assertNullCheck(checkExpression('j/*check*/'),
+        assertEdge(nullable_j, nullable_i, hard: true));
+  }
+
+  test_methodInvocation_parameter_named_differentPackage() async {
+    addPackageFile('pkgC', 'c.dart', '''
+class C {
+  void f({int i}) {}
+}
+''');
+    await analyze('''
+import "package:pkgC/c.dart";
+void g(C c, int j) {
+  c.f(i: j/*check*/);
+}
+''');
+    var nullable_j = decoratedTypeAnnotation('int j');
+    assertNullCheck(checkExpression('j/*check*/'),
+        assertEdge(nullable_j.node, never, hard: true));
+  }
+
+  test_methodInvocation_resolves_to_getter() async {
+    await analyze('''
+abstract class C {
+  int/*1*/ Function(int/*2*/ i) get f;
+}
+int/*3*/ g(C c, int/*4*/ i) => c.f(i);
+''');
+    assertEdge(decoratedTypeAnnotation('int/*4*/').node,
+        decoratedTypeAnnotation('int/*2*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+        decoratedTypeAnnotation('int/*3*/').node,
+        hard: false);
+  }
+
+  test_methodInvocation_return_type() async {
+    await analyze('''
+class C {
+  bool m() => true;
+}
+bool f(C c) => c.m();
+''');
+    assertEdge(decoratedTypeAnnotation('bool m').node,
+        decoratedTypeAnnotation('bool f').node,
+        hard: false);
+  }
+
+  test_methodInvocation_return_type_generic_function() async {
+    await analyze('''
+T f<T>(T t) => t;
+int g() => (f<int>(1));
+''');
+    var check_i = checkExpression('(f<int>(1))');
+    var nullable_f_t = decoratedTypeAnnotation('int>').node;
+    var nullable_f_t_or_nullable_t =
+        check_i.edges.single.primarySource as NullabilityNodeForSubstitution;
+    var nullable_t = decoratedTypeAnnotation('T f').node;
+    expect(nullable_f_t_or_nullable_t.innerNode, same(nullable_f_t));
+    expect(nullable_f_t_or_nullable_t.outerNode, same(nullable_t));
+    var nullable_return = decoratedTypeAnnotation('int g').node;
+    assertNullCheck(check_i,
+        assertEdge(nullable_f_t_or_nullable_t, nullable_return, hard: false));
+  }
+
+  test_methodInvocation_return_type_null_aware() async {
+    await analyze('''
+class C {
+  bool m() => true;
+}
+bool f(C c) => (c?.m());
+''');
+    var lubNode =
+        decoratedExpressionType('(c?.m())').node as NullabilityNodeForLUB;
+    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+    expect(lubNode.right, same(decoratedTypeAnnotation('bool m').node));
+    assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
+  }
+
+  test_methodInvocation_target_check() async {
+    await analyze('''
+class C {
+  void m() {}
+}
+void test(C c) {
+  c.m();
+}
+''');
+
+    assertNullCheck(checkExpression('c.m'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_methodInvocation_target_check_cascaded() async {
+    await analyze('''
+class C {
+  void m() {}
+}
+void test(C c) {
+  c..m();
+}
+''');
+
+    assertNullCheck(checkExpression('c..m'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_methodInvocation_target_demonstrates_non_null_intent() async {
+    await analyze('''
+class C {
+  void m() {}
+}
+void test(C c) {
+  c.m();
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+  }
+
+  test_methodInvocation_target_demonstrates_non_null_intent_cascaded() async {
+    await analyze('''
+class C {
+  void m() {}
+}
+void test(C c) {
+  c..m();
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+  }
+
+  test_never() async {
+    await analyze('');
+
+    expect(never.isNullable, isFalse);
+  }
+
+  test_override_parameter_type_named() async {
+    await analyze('''
+abstract class Base {
+  void f({int/*1*/ i});
+}
+class Derived extends Base {
+  void f({int/*2*/ i}) {}
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int1.node, int2.node, hard: true);
+  }
+
+  test_override_parameter_type_named_over_none() async {
+    await analyze('''
+abstract class Base {
+  void f();
+}
+class Derived extends Base {
+  void f({int i}) {}
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_override_parameter_type_operator() async {
+    await analyze('''
+abstract class Base {
+  Base operator+(Base/*1*/ b);
+}
+class Derived extends Base {
+  Base operator+(Base/*2*/ b) => this;
+}
+''');
+    var base1 = decoratedTypeAnnotation('Base/*1*/');
+    var base2 = decoratedTypeAnnotation('Base/*2*/');
+    assertEdge(base1.node, base2.node, hard: true);
+  }
+
+  test_override_parameter_type_optional() async {
+    await analyze('''
+abstract class Base {
+  void f([int/*1*/ i]);
+}
+class Derived extends Base {
+  void f([int/*2*/ i]) {}
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int1.node, int2.node, hard: true);
+  }
+
+  test_override_parameter_type_optional_over_none() async {
+    await analyze('''
+abstract class Base {
+  void f();
+}
+class Derived extends Base {
+  void f([int i]) {}
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_override_parameter_type_optional_over_required() async {
+    await analyze('''
+abstract class Base {
+  void f(int/*1*/ i);
+}
+class Derived extends Base {
+  void f([int/*2*/ i]) {}
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int1.node, int2.node, hard: true);
+  }
+
+  test_override_parameter_type_required() async {
+    await analyze('''
+abstract class Base {
+  void f(int/*1*/ i);
+}
+class Derived extends Base {
+  void f(int/*2*/ i) {}
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int1.node, int2.node, hard: true);
+  }
+
+  test_override_parameter_type_setter() async {
+    await analyze('''
+abstract class Base {
+  void set x(int/*1*/ value);
+}
+class Derived extends Base {
+  void set x(int/*2*/ value) {}
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int1.node, int2.node, hard: true);
+  }
+
+  test_override_return_type_getter() async {
+    await analyze('''
+abstract class Base {
+  int/*1*/ get x;
+}
+class Derived extends Base {
+  int/*2*/ get x => null;
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int2.node, int1.node, hard: true);
+  }
+
+  test_override_return_type_method() async {
+    await analyze('''
+abstract class Base {
+  int/*1*/ f();
+}
+class Derived extends Base {
+  int/*2*/ f() => null;
+}
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int2.node, int1.node, hard: true);
+  }
+
+  test_override_return_type_operator() async {
+    await analyze('''
+abstract class Base {
+  Base/*1*/ operator-();
+}
+class Derived extends Base {
+  Derived/*2*/ operator-() => null;
+}
+''');
+    var base1 = decoratedTypeAnnotation('Base/*1*/');
+    var derived2 = decoratedTypeAnnotation('Derived/*2*/');
+    assertEdge(derived2.node, base1.node, hard: true);
+  }
+
+  test_parenthesizedExpression() async {
+    await analyze('''
+int f() {
+  return (null);
+}
+''');
+
+    assertNullCheck(checkExpression('(null)'),
+        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+  }
+
+  test_postfixExpression_minusMinus() async {
+    await analyze('''
+int f(int i) {
+  return i--;
+}
+''');
+
+    var declaration = decoratedTypeAnnotation('int i').node;
+    var use = checkExpression('i--');
+    assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+    var returnType = decoratedTypeAnnotation('int f').node;
+    assertEdge(never, returnType, hard: false);
+  }
+
+  test_postfixExpression_plusPlus() async {
+    await analyze('''
+int f(int i) {
+  return i++;
+}
+''');
+
+    var declaration = decoratedTypeAnnotation('int i').node;
+    var use = checkExpression('i++');
+    assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+    var returnType = decoratedTypeAnnotation('int f').node;
+    assertEdge(never, returnType, hard: false);
+  }
+
+  test_prefixedIdentifier_field_type() async {
+    await analyze('''
+class C {
+  bool b = true;
+}
+bool f(C c) => c.b;
+''');
+    assertEdge(decoratedTypeAnnotation('bool b').node,
+        decoratedTypeAnnotation('bool f').node,
+        hard: false);
+  }
+
+  test_prefixedIdentifier_getter_type() async {
+    await analyze('''
+class C {
+  bool get b => true;
+}
+bool f(C c) => c.b;
+''');
+    assertEdge(decoratedTypeAnnotation('bool get').node,
+        decoratedTypeAnnotation('bool f').node,
+        hard: false);
+  }
+
+  test_prefixedIdentifier_target_check() async {
+    await analyze('''
+class C {
+  int get x => 1;
+}
+void test(C c) {
+  c.x;
+}
+''');
+
+    assertNullCheck(checkExpression('c.x'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_prefixedIdentifier_target_demonstrates_non_null_intent() async {
+    await analyze('''
+class C {
+  int get x => 1;
+}
+void test(C c) {
+  c.x;
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
+  }
+
+  test_prefixedIdentifier_tearoff() async {
+    await analyze('''
+abstract class C {
+  int f(int i);
+}
+int Function(int) g(C c) => c.f;
+''');
+    var fType = variables.decoratedElementType(findElement.method('f'));
+    var gReturnType =
+        variables.decoratedElementType(findElement.function('g')).returnType;
+    assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+    assertEdge(gReturnType.positionalParameters[0].node,
+        fType.positionalParameters[0].node,
+        hard: false);
+  }
+
+  test_prefixExpression_bang() async {
+    await analyze('''
+bool f(bool b) {
+  return !b;
+}
+''');
+
+    var nullable_b = decoratedTypeAnnotation('bool b').node;
+    var check_b = checkExpression('b;');
+    assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
+
+    var return_f = decoratedTypeAnnotation('bool f').node;
+    assertEdge(never, return_f, hard: false);
+  }
+
+  test_prefixExpression_minus() async {
+    await analyze('''
+abstract class C {
+  C operator-();
+}
+C test(C c) => -c/*check*/;
+''');
+    assertEdge(decoratedTypeAnnotation('C operator').node,
+        decoratedTypeAnnotation('C test').node,
+        hard: false);
+    assertNullCheck(checkExpression('c/*check*/'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_prefixExpression_minusMinus() async {
+    await analyze('''
+int f(int i) {
+  return --i;
+}
+''');
+
+    var declaration = decoratedTypeAnnotation('int i').node;
+    var use = checkExpression('i;');
+    assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+    var returnType = decoratedTypeAnnotation('int f').node;
+    assertEdge(never, returnType, hard: false);
+  }
+
+  test_prefixExpression_plusPlus() async {
+    await analyze('''
+int f(int i) {
+  return ++i;
+}
+''');
+
+    var declaration = decoratedTypeAnnotation('int i').node;
+    var use = checkExpression('i;');
+    assertNullCheck(use, assertEdge(declaration, never, hard: true));
+
+    var returnType = decoratedTypeAnnotation('int f').node;
+    assertEdge(never, returnType, hard: false);
+  }
+
+  test_propertyAccess_return_type() async {
+    await analyze('''
+class C {
+  bool get b => true;
+}
+bool f(C c) => (c).b;
+''');
+    assertEdge(decoratedTypeAnnotation('bool get').node,
+        decoratedTypeAnnotation('bool f').node,
+        hard: false);
+  }
+
+  test_propertyAccess_return_type_null_aware() async {
+    await analyze('''
+class C {
+  bool get b => true;
+}
+bool f(C c) => (c?.b);
+''');
+    var lubNode =
+        decoratedExpressionType('(c?.b)').node as NullabilityNodeForLUB;
+    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
+    expect(lubNode.right, same(decoratedTypeAnnotation('bool get b').node));
+    assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
+  }
+
+  test_propertyAccess_target_check() async {
+    await analyze('''
+class C {
+  int get x => 1;
+}
+void test(C c) {
+  (c).x;
+}
+''');
+
+    assertNullCheck(checkExpression('c).x'),
+        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
+  }
+
+  test_redirecting_constructor_factory() async {
+    await analyze('''
+class C {
+  factory C(int/*1*/ i, {int/*2*/ j}) = D;
+}
+class D implements C {
+  D(int/*3*/ i, {int/*4*/ j});
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+        decoratedTypeAnnotation('int/*3*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+        decoratedTypeAnnotation('int/*4*/').node,
+        hard: true);
+  }
+
+  test_redirecting_constructor_factory_from_generic_to_generic() async {
+    await analyze('''
+class C<T> {
+  factory C(T/*1*/ t) = D<T/*2*/>;
+}
+class D<U> implements C<U> {
+  D(U/*3*/ u);
+}
+''');
+    var nullable_t1 = decoratedTypeAnnotation('T/*1*/').node;
+    var nullable_t2 = decoratedTypeAnnotation('T/*2*/').node;
+    var nullable_u3 = decoratedTypeAnnotation('U/*3*/').node;
+    var nullable_t2_or_nullable_u3 = graph
+        .getDownstreamEdges(nullable_t1)
+        .single
+        .destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_t2_or_nullable_u3.innerNode, same(nullable_t2));
+    expect(nullable_t2_or_nullable_u3.outerNode, same(nullable_u3));
+    assertEdge(nullable_t1, nullable_t2_or_nullable_u3, hard: true);
+  }
+
+  test_redirecting_constructor_factory_to_generic() async {
+    await analyze('''
+class C {
+  factory C(int/*1*/ i) = D<int/*2*/>;
+}
+class D<T> implements C {
+  D(T/*3*/ i);
+}
+''');
+    var nullable_i1 = decoratedTypeAnnotation('int/*1*/').node;
+    var nullable_i2 = decoratedTypeAnnotation('int/*2*/').node;
+    var nullable_t3 = decoratedTypeAnnotation('T/*3*/').node;
+    var nullable_i2_or_nullable_t3 = graph
+        .getDownstreamEdges(nullable_i1)
+        .single
+        .destinationNode as NullabilityNodeForSubstitution;
+    expect(nullable_i2_or_nullable_t3.innerNode, same(nullable_i2));
+    expect(nullable_i2_or_nullable_t3.outerNode, same(nullable_t3));
+    assertEdge(nullable_i1, nullable_i2_or_nullable_t3, hard: true);
+  }
+
+  test_redirecting_constructor_ordinary() async {
+    await analyze('''
+class C {
+  C(int/*1*/ i, int/*2*/ j) : this.named(j, i);
+  C.named(int/*3*/ j, int/*4*/ i);
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int/*1*/').node,
+        decoratedTypeAnnotation('int/*4*/').node,
+        hard: true);
+    assertEdge(decoratedTypeAnnotation('int/*2*/').node,
+        decoratedTypeAnnotation('int/*3*/').node,
+        hard: true);
+  }
+
+  test_return_from_async_future() async {
+    await analyze('''
+Future<int> f() async {
+  return g();
+}
+int g() => 1;
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_return_from_async_futureOr() async {
+    await analyze('''
+import 'dart:async';
+FutureOr<int> f() async {
+  return g();
+}
+int g() => 1;
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
+  test_return_function_type_simple() async {
+    await analyze('''
+int/*1*/ Function() f(int/*2*/ Function() x) => x;
+''');
+    var int1 = decoratedTypeAnnotation('int/*1*/');
+    var int2 = decoratedTypeAnnotation('int/*2*/');
+    assertEdge(int2.node, int1.node, hard: true);
+  }
+
+  test_return_implicit_null() async {
+    verifyNoTestUnitErrors = false;
+    await analyze('''
+int f() {
+  return;
+}
+''');
+
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_return_null() async {
+    await analyze('''
+int f() {
+  return null;
+}
+''');
+
+    assertNullCheck(checkExpression('null'),
+        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
+  }
+
+  test_return_null_generic() async {
+    await analyze('''
+class C<T> {
+  T f() {
+    return null;
+  }
+}
+''');
+    var tNode = decoratedTypeAnnotation('T f').node;
+    assertEdge(always, tNode, hard: false);
+    assertNullCheck(
+        checkExpression('null'), assertEdge(always, tNode, hard: false));
+  }
+
+  @failingTest
+  test_setOrMapLiteral_map_noTypeArgument_noNullableKeysAndValues() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Map<String, int> f() {
+  return {'a' : 1, 'b' : 2};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    // TODO(brianwilkerson) Add an assertion that there is an edge from the set
+    //  literal's fake type argument to the return type's type argument.
+  }
+
+  @failingTest
+  test_setOrMapLiteral_map_noTypeArgument_nullableKey() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Map<String, int> f() {
+  return {'a' : 1, null : 2, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  @failingTest
+  test_setOrMapLiteral_map_noTypeArgument_nullableKeyAndValue() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Map<String, int> f() {
+  return {'a' : 1, null : null, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  @failingTest
+  test_setOrMapLiteral_map_noTypeArgument_nullableValue() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Map<String, int> f() {
+  return {'a' : 1, 'b' : null, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_setOrMapLiteral_map_typeArguments_noNullableKeysAndValues() async {
+    await analyze('''
+Map<String, int> f() {
+  return <String, int>{'a' : 1, 'b' : 2};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+
+    var keyForLiteral = decoratedTypeAnnotation('String, int>{').node;
+    var keyForReturnType = decoratedTypeAnnotation('String, int> ').node;
+    assertNoUpstreamNullability(keyForLiteral);
+    assertEdge(keyForLiteral, keyForReturnType, hard: false);
+
+    var valueForLiteral = decoratedTypeAnnotation('int>{').node;
+    var valueForReturnType = decoratedTypeAnnotation('int> ').node;
+    assertNoUpstreamNullability(valueForLiteral);
+    assertEdge(valueForLiteral, valueForReturnType, hard: false);
+  }
+
+  test_setOrMapLiteral_map_typeArguments_nullableKey() async {
+    await analyze('''
+Map<String, int> f() {
+  return <String, int>{'a' : 1, null : 2, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
+        hard: false);
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int>{').node);
+  }
+
+  test_setOrMapLiteral_map_typeArguments_nullableKeyAndValue() async {
+    await analyze('''
+Map<String, int> f() {
+  return <String, int>{'a' : 1, null : null, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
+        hard: false);
+    assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
+  }
+
+  test_setOrMapLiteral_map_typeArguments_nullableValue() async {
+    await analyze('''
+Map<String, int> f() {
+  return <String, int>{'a' : 1, 'b' : null, 'c' : 3};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
+    assertNoUpstreamNullability(decoratedTypeAnnotation('String, int>{').node);
+    assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
+  }
+
+  @failingTest
+  test_setOrMapLiteral_set_noTypeArgument_noNullableElements() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Set<String> f() {
+  return {'a', 'b'};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+    // TODO(brianwilkerson) Add an assertion that there is an edge from the set
+    //  literal's fake type argument to the return type's type argument.
+  }
+
+  @failingTest
+  test_setOrMapLiteral_set_noTypeArgument_nullableElement() async {
+    // Failing because we're not yet handling collection literals without a
+    // type argument.
+    await analyze('''
+Set<String> f() {
+  return {'a', null, 'c'};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
+  }
+
+  test_setOrMapLiteral_set_typeArgument_noNullableElements() async {
+    await analyze('''
+Set<String> f() {
+  return <String>{'a', 'b'};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+    var typeArgForLiteral = decoratedTypeAnnotation('String>{').node;
+    var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
+    assertNoUpstreamNullability(typeArgForLiteral);
+    assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
+  }
+
+  test_setOrMapLiteral_set_typeArgument_nullableElement() async {
+    await analyze('''
+Set<String> f() {
+  return <String>{'a', null, 'c'};
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
+    assertEdge(always, decoratedTypeAnnotation('String>{').node, hard: false);
+  }
+
+  test_simpleIdentifier_function() async {
+    await analyze('''
+int f() => null;
+main() {
+  int Function() g = f;
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int f').node,
+        decoratedTypeAnnotation('int Function').node,
+        hard: false);
+  }
+
+  test_simpleIdentifier_local() async {
+    await analyze('''
+main() {
+  int i = 0;
+  int j = i;
+}
+''');
+
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int j').node,
+        hard: true);
+  }
+
+  test_simpleIdentifier_tearoff_function() async {
+    await analyze('''
+int f(int i) => 0;
+int Function(int) g() => f;
+''');
+    var fType = variables.decoratedElementType(findElement.function('f'));
+    var gReturnType =
+        variables.decoratedElementType(findElement.function('g')).returnType;
+    assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+    assertEdge(gReturnType.positionalParameters[0].node,
+        fType.positionalParameters[0].node,
+        hard: false);
+  }
+
+  test_simpleIdentifier_tearoff_method() async {
+    await analyze('''
+abstract class C {
+  int f(int i);
+  int Function(int) g() => f;
+}
+''');
+    var fType = variables.decoratedElementType(findElement.method('f'));
+    var gReturnType =
+        variables.decoratedElementType(findElement.method('g')).returnType;
+    assertEdge(fType.returnType.node, gReturnType.returnType.node, hard: false);
+    assertEdge(gReturnType.positionalParameters[0].node,
+        fType.positionalParameters[0].node,
+        hard: false);
+  }
+
+  test_skipDirectives() async {
+    await analyze('''
+import "dart:core" as one;
+main() {}
+''');
+    // No test expectations.
+    // Just verifying that the test passes
+  }
+
+  test_soft_edge_for_non_variable_reference() async {
+    // Edges originating in things other than variable references should be
+    // soft.
+    await analyze('''
+int f() => null;
+''');
+    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
+  }
+
+  test_stringLiteral() async {
+    // TODO(paulberry): also test string interpolations
+    await analyze('''
+String f() {
+  return 'x';
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
+  }
+
+  test_superExpression() async {
+    await analyze('''
+class C {
+  C f() => super;
+}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
+  }
+
+  test_symbolLiteral() async {
+    await analyze('''
+Symbol f() {
+  return #symbol;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Symbol').node);
+  }
+
+  test_thisExpression() async {
+    await analyze('''
+class C {
+  C f() => this;
+}
+''');
+
+    assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
+  }
+
+  test_throwExpression() async {
+    await analyze('''
+int f() {
+  return throw null;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
+  }
+
+  test_topLevelSetter() async {
+    await analyze('''
+void set x(int value) {}
+main() { x = 1; }
+''');
+    var setXType = decoratedTypeAnnotation('int value');
+    assertEdge(never, setXType.node, hard: false);
+  }
+
+  test_topLevelSetter_nullable() async {
+    await analyze('''
+void set x(int value) {}
+main() { x = null; }
+''');
+    var setXType = decoratedTypeAnnotation('int value');
+    assertEdge(always, setXType.node, hard: false);
+  }
+
+  test_topLevelVar_reference() async {
+    await analyze('''
+double pi = 3.1415;
+double get myPi => pi;
+''');
+    var piType = decoratedTypeAnnotation('double pi');
+    var myPiType = decoratedTypeAnnotation('double get');
+    assertEdge(piType.node, myPiType.node, hard: false);
+  }
+
+  test_topLevelVar_reference_differentPackage() async {
+    addPackageFile('pkgPi', 'piConst.dart', '''
+double pi = 3.1415;
+''');
+    await analyze('''
+import "package:pkgPi/piConst.dart";
+double get myPi => pi;
+''');
+    var myPiType = decoratedTypeAnnotation('double get');
+    assertEdge(never, myPiType.node, hard: false);
+  }
+
+  test_topLevelVariable_type_inferred() async {
+    await analyze('''
+int f() => 1;
+var x = f();
+''');
+    var xType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    assertUnion(xType.node, decoratedTypeAnnotation('int').node);
+  }
+
+  test_type_argument_explicit_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+void f(C<int> c) {}
+''');
+    assertEdge(decoratedTypeAnnotation('int>').node,
+        decoratedTypeAnnotation('Object>').node,
+        hard: true);
+  }
+
+  test_type_parameterized_migrated_bound_class() async {
+    await analyze('''
+import 'dart:math';
+void f(Point<int> x) {}
+''');
+    var pointClass =
+        findNode.typeName('Point').name.staticElement as ClassElement;
+    var pointBound =
+        variables.decoratedElementType(pointClass.typeParameters[0]);
+    expect(pointBound.type.toString(), 'num');
+    assertEdge(decoratedTypeAnnotation('int>').node, pointBound.node,
+        hard: true);
+  }
+
+  test_type_parameterized_migrated_bound_dynamic() async {
+    await analyze('''
+void f(List<int> x) {}
+''');
+    var listClass = typeProvider.listType.element;
+    var listBound = variables.decoratedElementType(listClass.typeParameters[0]);
+    expect(listBound.type.toString(), 'dynamic');
+    assertEdge(decoratedTypeAnnotation('int>').node, listBound.node,
+        hard: true);
+  }
+
+  test_typeName() async {
+    await analyze('''
+Type f() {
+  return int;
+}
+''');
+    assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
+  }
+
+  test_typeName_union_with_bound() async {
+    await analyze('''
+class C<T extends Object> {}
+void f(C c) {}
+''');
+    var cType = decoratedTypeAnnotation('C c');
+    var cBound = decoratedTypeAnnotation('Object');
+    assertUnion(cType.typeArguments[0].node, cBound.node);
+  }
+
+  test_typeName_union_with_bound_function_type() async {
+    await analyze('''
+class C<T extends int Function()> {}
+void f(C c) {}
+''');
+    var cType = decoratedTypeAnnotation('C c');
+    var cBound = decoratedGenericFunctionTypeAnnotation('int Function()');
+    assertUnion(cType.typeArguments[0].node, cBound.node);
+    assertUnion(cType.typeArguments[0].returnType.node, cBound.returnType.node);
+  }
+
+  test_typeName_union_with_bounds() async {
+    await analyze('''
+class C<T extends Object, U extends Object> {}
+void f(C c) {}
+''');
+    var cType = decoratedTypeAnnotation('C c');
+    var tBound = decoratedTypeAnnotation('Object,');
+    var uBound = decoratedTypeAnnotation('Object>');
+    assertUnion(cType.typeArguments[0].node, tBound.node);
+    assertUnion(cType.typeArguments[1].node, uBound.node);
+  }
+
+  test_variableDeclaration() async {
+    await analyze('''
+void f(int i) {
+  int j = i;
+}
+''');
+    assertEdge(decoratedTypeAnnotation('int i').node,
+        decoratedTypeAnnotation('int j').node,
+        hard: true);
+  }
+}
diff --git a/pkg/nnbd_migration/test/graph_builder_test.dart b/pkg/nnbd_migration/test/graph_builder_test.dart
deleted file mode 100644
index f3a938e..0000000
--- a/pkg/nnbd_migration/test/graph_builder_test.dart
+++ /dev/null
@@ -1,1706 +0,0 @@
-// Copyright (c) 2019, 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:analyzer/dart/ast/ast.dart';
-import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/graph_builder.dart';
-import 'package:nnbd_migration/src/nullability_node.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'migration_visitor_test_base.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(GraphBuilderTest);
-  });
-}
-
-@reflectiveTest
-class GraphBuilderTest extends MigrationVisitorTestBase {
-  /// Analyzes the given source code, producing constraint variables and
-  /// constraints for it.
-  @override
-  Future<CompilationUnit> analyze(String code) async {
-    var unit = await super.analyze(code);
-    unit.accept(GraphBuilder(typeProvider, variables, graph, testSource, null));
-    return unit;
-  }
-
-  void assertConditional(
-      NullabilityNode node, NullabilityNode left, NullabilityNode right) {
-    var conditionalNode = node as NullabilityNodeForLUB;
-    expect(conditionalNode.left, same(left));
-    expect(conditionalNode.right, same(right));
-  }
-
-  /// Checks that there are no nullability nodes upstream from [node] that could
-  /// cause it to become nullable.
-  void assertNoUpstreamNullability(NullabilityNode node) {
-    // never can never become nullable, even if it has nodes
-    // upstream from it.
-    if (node == never) return;
-
-    for (var edge in graph.getUpstreamEdges(node)) {
-      expect(edge.primarySource, never);
-    }
-  }
-
-  /// Verifies that a null check will occur when the given edge is unsatisfied.
-  ///
-  /// [expressionChecks] is the object tracking whether or not a null check is
-  /// needed.
-  void assertNullCheck(
-      ExpressionChecks expressionChecks, NullabilityEdge expectedEdge) {
-    expect(expressionChecks.edges, contains(expectedEdge));
-  }
-
-  /// Gets the [ExpressionChecks] associated with the expression whose text
-  /// representation is [text], or `null` if the expression has no
-  /// [ExpressionChecks] associated with it.
-  ExpressionChecks checkExpression(String text) {
-    return variables.checkExpression(findNode.expression(text));
-  }
-
-  /// Gets the [DecoratedType] associated with the expression whose text
-  /// representation is [text], or `null` if the expression has no
-  /// [DecoratedType] associated with it.
-  DecoratedType decoratedExpressionType(String text) {
-    return variables.decoratedExpressionType(findNode.expression(text));
-  }
-
-  test_assert_demonstrates_non_null_intent() async {
-    await analyze('''
-void f(int i) {
-  assert(i != null);
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
-  }
-
-  test_assignmentExpression_field() async {
-    await analyze('''
-class C {
-  int x = 0;
-}
-void f(C c, int i) {
-  c.x = i;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int x').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_field_cascaded() async {
-    await analyze('''
-class C {
-  int x = 0;
-}
-void f(C c, int i) {
-  c..x = i;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int x').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_field_target_check() async {
-    await analyze('''
-class C {
-  int x = 0;
-}
-void f(C c, int i) {
-  c.x = i;
-}
-''');
-    assertNullCheck(checkExpression('c.x'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_assignmentExpression_field_target_check_cascaded() async {
-    await analyze('''
-class C {
-  int x = 0;
-}
-void f(C c, int i) {
-  c..x = i;
-}
-''');
-    assertNullCheck(checkExpression('c..x'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_assignmentExpression_indexExpression_index() async {
-    await analyze('''
-class C {
-  void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
-  c[i] = j;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int a').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_indexExpression_return_value() async {
-    await analyze('''
-class C {
-  void operator[]=(int a, int b) {}
-}
-int f(C c, int i, int j) => c[i] = j;
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int f').node,
-        hard: false);
-  }
-
-  test_assignmentExpression_indexExpression_target_check() async {
-    await analyze('''
-class C {
-  void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
-  c[i] = j;
-}
-''');
-    assertNullCheck(checkExpression('c['),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_assignmentExpression_indexExpression_value() async {
-    await analyze('''
-class C {
-  void operator[]=(int a, int b) {}
-}
-void f(C c, int i, int j) {
-  c[i] = j;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int b').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_operands() async {
-    await analyze('''
-void f(int i, int j) {
-  i = j;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int i').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_return_value() async {
-    await analyze('''
-void f(int i, int j) {
-  g(i = j);
-}
-void g(int k) {}
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int k').node,
-        hard: false);
-  }
-
-  test_assignmentExpression_setter() async {
-    await analyze('''
-class C {
-  void set s(int value) {}
-}
-void f(C c, int i) {
-  c.s = i;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int value').node,
-        hard: true);
-  }
-
-  test_assignmentExpression_setter_null_aware() async {
-    await analyze('''
-class C {
-  void set s(int value) {}
-}
-int f(C c, int i) => (c?.s = i);
-''');
-    var lubNode =
-        decoratedExpressionType('(c?.s = i)').node as NullabilityNodeForLUB;
-    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
-    expect(lubNode.right, same(decoratedTypeAnnotation('int i').node));
-    assertEdge(lubNode, decoratedTypeAnnotation('int f').node, hard: false);
-  }
-
-  test_assignmentExpression_setter_target_check() async {
-    await analyze('''
-class C {
-  void set s(int value) {}
-}
-void f(C c, int i) {
-  c.s = i;
-}
-''');
-    assertNullCheck(checkExpression('c.s'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  @failingTest
-  test_awaitExpression_future_nonNullable() async {
-    await analyze('''
-Future<void> f() async {
-  int x = await g();
-}
-Future<int> g() async => 3;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  @failingTest
-  test_awaitExpression_future_nullable() async {
-    await analyze('''
-Future<void> f() async {
-  int x = await g();
-}
-Future<int> g() async => null;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_awaitExpression_nonFuture() async {
-    await analyze('''
-Future<void> f() async {
-  int x = await 3;
-}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_binaryExpression_ampersand_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i & j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_bar_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i | j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_caret_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i ^ j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_equal() async {
-    await analyze('''
-bool f(int i, int j) => i == j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_gt_result_not_null() async {
-    await analyze('''
-bool f(int i, int j) => i > j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_gtEq_result_not_null() async {
-    await analyze('''
-bool f(int i, int j) => i >= j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_gtGt_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i >> j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_lt_result_not_null() async {
-    await analyze('''
-bool f(int i, int j) => i < j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_ltEq_result_not_null() async {
-    await analyze('''
-bool f(int i, int j) => i <= j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_ltLt_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i << j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_minus_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i - j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_notEqual() async {
-    await analyze('''
-bool f(int i, int j) => i != j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool f').node);
-  }
-
-  test_binaryExpression_percent_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i % j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_plus_left_check() async {
-    await analyze('''
-int f(int i, int j) => i + j;
-''');
-
-    assertNullCheck(checkExpression('i +'),
-        assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true));
-  }
-
-  test_binaryExpression_plus_left_check_custom() async {
-    await analyze('''
-class Int {
-  Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => i + j;
-''');
-
-    assertNullCheck(checkExpression('i +'),
-        assertEdge(decoratedTypeAnnotation('Int i').node, never, hard: true));
-  }
-
-  test_binaryExpression_plus_result_custom() async {
-    await analyze('''
-class Int {
-  Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => (i + j);
-''');
-
-    assertNullCheck(
-        checkExpression('(i + j)'),
-        assertEdge(decoratedTypeAnnotation('Int operator+').node,
-            decoratedTypeAnnotation('Int f').node,
-            hard: false));
-  }
-
-  test_binaryExpression_plus_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i + j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_plus_right_check() async {
-    await analyze('''
-int f(int i, int j) => i + j;
-''');
-
-    assertNullCheck(checkExpression('j;'),
-        assertEdge(decoratedTypeAnnotation('int j').node, never, hard: true));
-  }
-
-  test_binaryExpression_plus_right_check_custom() async {
-    await analyze('''
-class Int {
-  Int operator+(Int other) => this;
-}
-Int f(Int i, Int j) => i + j/*check*/;
-''');
-
-    assertNullCheck(
-        checkExpression('j/*check*/'),
-        assertEdge(decoratedTypeAnnotation('Int j').node,
-            decoratedTypeAnnotation('Int other').node,
-            hard: true));
-  }
-
-  test_binaryExpression_slash_result_not_null() async {
-    await analyze('''
-double f(int i, int j) => i / j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('double f').node);
-  }
-
-  test_binaryExpression_star_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i * j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_binaryExpression_tildeSlash_result_not_null() async {
-    await analyze('''
-int f(int i, int j) => i ~/ j;
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int f').node);
-  }
-
-  test_boolLiteral() async {
-    await analyze('''
-bool f() {
-  return true;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
-  }
-
-  test_cascadeExpression() async {
-    await analyze('''
-class C {
-  int x = 0;
-}
-C f(C c, int i) => c..x = i;
-''');
-    assertEdge(decoratedTypeAnnotation('C c').node,
-        decoratedTypeAnnotation('C f').node,
-        hard: false);
-  }
-
-  test_conditionalExpression_condition_check() async {
-    await analyze('''
-int f(bool b, int i, int j) {
-  return (b ? i : j);
-}
-''');
-
-    var nullable_b = decoratedTypeAnnotation('bool b').node;
-    var check_b = checkExpression('b ?');
-    assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
-  }
-
-  test_conditionalExpression_general() async {
-    await analyze('''
-int f(bool b, int i, int j) {
-  return (b ? i : j);
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_j = decoratedTypeAnnotation('int j').node;
-    var nullable_conditional = decoratedExpressionType('(b ?').node;
-    assertConditional(nullable_conditional, nullable_i, nullable_j);
-    var nullable_return = decoratedTypeAnnotation('int f').node;
-    assertNullCheck(checkExpression('(b ? i : j)'),
-        assertEdge(nullable_conditional, nullable_return, hard: false));
-  }
-
-  test_conditionalExpression_left_non_null() async {
-    await analyze('''
-int f(bool b, int i) {
-  return (b ? (throw i) : i);
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_conditional =
-        decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
-    var nullable_throw = nullable_conditional.left;
-    assertNoUpstreamNullability(nullable_throw);
-    assertConditional(nullable_conditional, nullable_throw, nullable_i);
-  }
-
-  test_conditionalExpression_left_null() async {
-    await analyze('''
-int f(bool b, int i) {
-  return (b ? null : i);
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_conditional = decoratedExpressionType('(b ?').node;
-    assertConditional(nullable_conditional, always, nullable_i);
-  }
-
-  test_conditionalExpression_right_non_null() async {
-    await analyze('''
-int f(bool b, int i) {
-  return (b ? i : (throw i));
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_conditional =
-        decoratedExpressionType('(b ?').node as NullabilityNodeForLUB;
-    var nullable_throw = nullable_conditional.right;
-    assertNoUpstreamNullability(nullable_throw);
-    assertConditional(nullable_conditional, nullable_i, nullable_throw);
-  }
-
-  test_conditionalExpression_right_null() async {
-    await analyze('''
-int f(bool b, int i) {
-  return (b ? i : null);
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_conditional = decoratedExpressionType('(b ?').node;
-    assertConditional(nullable_conditional, nullable_i, always);
-  }
-
-  test_doubleLiteral() async {
-    await analyze('''
-double f() {
-  return 1.0;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('double').node);
-  }
-
-  test_functionDeclaration_expression_body() async {
-    await analyze('''
-int/*1*/ f(int/*2*/ i) => i/*3*/;
-''');
-
-    assertNullCheck(
-        checkExpression('i/*3*/'),
-        assertEdge(decoratedTypeAnnotation('int/*2*/').node,
-            decoratedTypeAnnotation('int/*1*/').node,
-            hard: true));
-  }
-
-  test_functionDeclaration_parameter_named_default_notNull() async {
-    await analyze('''
-void f({int i = 1}) {}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_functionDeclaration_parameter_named_default_null() async {
-    await analyze('''
-void f({int i = null}) {}
-''');
-
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_functionDeclaration_parameter_named_no_default() async {
-    await analyze('''
-void f({int i}) {}
-''');
-
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_functionDeclaration_parameter_named_no_default_required() async {
-    addMetaPackage();
-    await analyze('''
-import 'package:meta/meta.dart';
-void f({@required int i}) {}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
-    await analyze('''
-void f([int i = 1]) {}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_functionDeclaration_parameter_positionalOptional_default_null() async {
-    await analyze('''
-void f([int i = null]) {}
-''');
-
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_functionDeclaration_parameter_positionalOptional_no_default() async {
-    await analyze('''
-void f([int i]) {}
-''');
-
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_functionDeclaration_resets_unconditional_control_flow() async {
-    await analyze('''
-void f(bool b, int i, int j) {
-  assert(i != null);
-  if (b) return;
-  assert(j != null);
-}
-void g(int k) {
-  assert(k != null);
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
-    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
-    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
-  }
-
-  test_functionInvocation_parameter_fromLocalParameter() async {
-    await analyze('''
-void f(int/*1*/ i) {}
-void test(int/*2*/ i) {
-  f(i/*3*/);
-}
-''');
-
-    var int_1 = decoratedTypeAnnotation('int/*1*/');
-    var int_2 = decoratedTypeAnnotation('int/*2*/');
-    var i_3 = checkExpression('i/*3*/');
-    assertNullCheck(i_3, assertEdge(int_2.node, int_1.node, hard: true));
-    assertEdge(int_2.node, int_1.node, hard: true);
-  }
-
-  test_functionInvocation_parameter_named() async {
-    await analyze('''
-void f({int i: 0}) {}
-void g(int j) {
-  f(i: j/*check*/);
-}
-''');
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_j = decoratedTypeAnnotation('int j').node;
-    assertNullCheck(checkExpression('j/*check*/'),
-        assertEdge(nullable_j, nullable_i, hard: true));
-  }
-
-  test_functionInvocation_parameter_named_missing() async {
-    await analyze('''
-void f({int i}) {}
-void g() {
-  f();
-}
-''');
-    var optional_i = possiblyOptionalParameter('int i');
-    expect(getEdges(always, optional_i), isNotEmpty);
-  }
-
-  test_functionInvocation_parameter_named_missing_required() async {
-    addMetaPackage();
-    verifyNoTestUnitErrors = false;
-    await analyze('''
-import 'package:meta/meta.dart';
-void f({@required int i}) {}
-void g() {
-  f();
-}
-''');
-    // The call at `f()` is presumed to be in error; no constraint is recorded.
-    var optional_i = possiblyOptionalParameter('int i');
-    expect(optional_i, isNull);
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    assertNoUpstreamNullability(nullable_i);
-  }
-
-  test_functionInvocation_parameter_null() async {
-    await analyze('''
-void f(int i) {}
-void test() {
-  f(null);
-}
-''');
-
-    assertNullCheck(checkExpression('null'),
-        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
-  }
-
-  test_functionInvocation_return() async {
-    await analyze('''
-int/*1*/ f() => 0;
-int/*2*/ g() {
-  return (f());
-}
-''');
-
-    assertNullCheck(
-        checkExpression('(f())'),
-        assertEdge(decoratedTypeAnnotation('int/*1*/').node,
-            decoratedTypeAnnotation('int/*2*/').node,
-            hard: false));
-  }
-
-  test_if_condition() async {
-    await analyze('''
-void f(bool b) {
-  if (b) {}
-}
-''');
-
-    assertNullCheck(checkExpression('b) {}'),
-        assertEdge(decoratedTypeAnnotation('bool b').node, never, hard: true));
-  }
-
-  test_if_conditional_control_flow_after() async {
-    // Asserts after ifs don't demonstrate non-null intent.
-    // TODO(paulberry): if both branches complete normally, they should.
-    await analyze('''
-void f(bool b, int i) {
-  if (b) return;
-  assert(i != null);
-}
-''');
-
-    assertNoEdge(always, decoratedTypeAnnotation('int i').node);
-  }
-
-  test_if_conditional_control_flow_within() async {
-    // Asserts inside ifs don't demonstrate non-null intent.
-    await analyze('''
-void f(bool b, int i) {
-  if (b) {
-    assert(i != null);
-  } else {
-    assert(i != null);
-  }
-}
-''');
-
-    assertNoEdge(always, decoratedTypeAnnotation('int i').node);
-  }
-
-  test_if_guard_equals_null() async {
-    await analyze('''
-int f(int i, int j, int k) {
-  if (i == null) {
-    return j/*check*/;
-  } else {
-    return k/*check*/;
-  }
-}
-''');
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_j = decoratedTypeAnnotation('int j').node;
-    var nullable_k = decoratedTypeAnnotation('int k').node;
-    var nullable_return = decoratedTypeAnnotation('int f').node;
-    assertNullCheck(
-        checkExpression('j/*check*/'),
-        assertEdge(nullable_j, nullable_return,
-            guards: [nullable_i], hard: false));
-    assertNullCheck(checkExpression('k/*check*/'),
-        assertEdge(nullable_k, nullable_return, hard: false));
-    var discard = statementDiscard('if (i == null)');
-    expect(discard.trueGuard, same(nullable_i));
-    expect(discard.falseGuard, null);
-    expect(discard.pureCondition, true);
-  }
-
-  test_if_simple() async {
-    await analyze('''
-int f(bool b, int i, int j) {
-  if (b) {
-    return i/*check*/;
-  } else {
-    return j/*check*/;
-  }
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_j = decoratedTypeAnnotation('int j').node;
-    var nullable_return = decoratedTypeAnnotation('int f').node;
-    assertNullCheck(checkExpression('i/*check*/'),
-        assertEdge(nullable_i, nullable_return, hard: false));
-    assertNullCheck(checkExpression('j/*check*/'),
-        assertEdge(nullable_j, nullable_return, hard: false));
-  }
-
-  test_if_without_else() async {
-    await analyze('''
-int f(bool b, int i) {
-  if (b) {
-    return i/*check*/;
-  }
-  return 0;
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_return = decoratedTypeAnnotation('int f').node;
-    assertNullCheck(checkExpression('i/*check*/'),
-        assertEdge(nullable_i, nullable_return, hard: false));
-  }
-
-  test_indexExpression_index() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-int f(C c, int j) => c[j];
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int i').node,
-        hard: true);
-  }
-
-  test_indexExpression_index_cascaded() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-C f(C c, int j) => c..[j];
-''');
-    assertEdge(decoratedTypeAnnotation('int j').node,
-        decoratedTypeAnnotation('int i').node,
-        hard: true);
-  }
-
-  test_indexExpression_return_type() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
-    assertEdge(decoratedTypeAnnotation('int operator').node,
-        decoratedTypeAnnotation('int f').node,
-        hard: false);
-  }
-
-  test_indexExpression_target_check() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
-    assertNullCheck(checkExpression('c['),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_indexExpression_target_check_cascaded() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-C f(C c) => c..[0];
-''');
-    assertNullCheck(checkExpression('c..['),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_indexExpression_target_demonstrates_non_null_intent() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-int f(C c) => c[0];
-''');
-    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
-  }
-
-  test_indexExpression_target_demonstrates_non_null_intent_cascaded() async {
-    await analyze('''
-class C {
-  int operator[](int i) => 1;
-}
-C f(C c) => c..[0];
-''');
-    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
-  }
-
-  test_instanceCreation_parameter_named_optional() async {
-    await analyze('''
-class C {
-  C({int x = 0});
-}
-void f(int y) {
-  C(x: y);
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int y').node,
-        decoratedTypeAnnotation('int x').node,
-        hard: true);
-  }
-
-  test_instanceCreation_parameter_positional_optional() async {
-    await analyze('''
-class C {
-  C([int x]);
-}
-void f(int y) {
-  C(y);
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int y').node,
-        decoratedTypeAnnotation('int x').node,
-        hard: true);
-  }
-
-  test_instanceCreation_parameter_positional_required() async {
-    await analyze('''
-class C {
-  C(int x);
-}
-void f(int y) {
-  C(y);
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int y').node,
-        decoratedTypeAnnotation('int x').node,
-        hard: true);
-  }
-
-  test_integerLiteral() async {
-    await analyze('''
-int f() {
-  return 0;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  @failingTest
-  test_isExpression_genericFunctionType() async {
-    await analyze('''
-bool f(a) => a is int Function(String);
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
-  }
-
-  test_isExpression_typeName_noTypeArguments() async {
-    await analyze('''
-bool f(a) => a is String;
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
-  }
-
-  @failingTest
-  test_isExpression_typeName_typeArguments() async {
-    await analyze('''
-bool f(a) => a is List<int>;
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('bool').node);
-  }
-
-  @failingTest
-  test_listLiteral_noTypeArgument_noNullableElements() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-List<String> f() {
-  return ['a', 'b'];
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
-    // TODO(brianwilkerson) Add an assertion that there is an edge from the list
-    //  literal's fake type argument to the return type's type argument.
-  }
-
-  @failingTest
-  test_listLiteral_noTypeArgument_nullableElement() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-List<String> f() {
-  return ['a', null, 'c'];
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
-    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
-  }
-
-  test_listLiteral_typeArgument_noNullableElements() async {
-    await analyze('''
-List<String> f() {
-  return <String>['a', 'b'];
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
-    var typeArgForLiteral = decoratedTypeAnnotation('String>[').node;
-    var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
-    assertNoUpstreamNullability(typeArgForLiteral);
-    assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
-  }
-
-  test_listLiteral_typeArgument_nullableElement() async {
-    await analyze('''
-List<String> f() {
-  return <String>['a', null, 'c'];
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('List').node);
-    assertEdge(always, decoratedTypeAnnotation('String>[').node, hard: false);
-  }
-
-  test_methodDeclaration_resets_unconditional_control_flow() async {
-    await analyze('''
-class C {
-  void f(bool b, int i, int j) {
-    assert(i != null);
-    if (b) return;
-    assert(j != null);
-  }
-  void g(int k) {
-    assert(k != null);
-  }
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
-    assertNoEdge(always, decoratedTypeAnnotation('int j').node);
-    assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
-  }
-
-  test_methodInvocation_parameter_contravariant() async {
-    await analyze('''
-class C<T> {
-  void f(T t) {}
-}
-void g(C<int> c, int i) {
-  c.f(i/*check*/);
-}
-''');
-
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_c_t = decoratedTypeAnnotation('C<int>').typeArguments[0].node;
-    var nullable_t = decoratedTypeAnnotation('T t').node;
-    var check_i = checkExpression('i/*check*/');
-    var nullable_c_t_or_nullable_t =
-        check_i.edges.single.destinationNode as NullabilityNodeForSubstitution;
-    expect(nullable_c_t_or_nullable_t.innerNode, same(nullable_c_t));
-    expect(nullable_c_t_or_nullable_t.outerNode, same(nullable_t));
-    assertNullCheck(check_i,
-        assertEdge(nullable_i, nullable_c_t_or_nullable_t, hard: true));
-  }
-
-  test_methodInvocation_parameter_generic() async {
-    await analyze('''
-class C<T> {}
-void f(C<int/*1*/>/*2*/ c) {}
-void g(C<int/*3*/>/*4*/ c) {
-  f(c/*check*/);
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int/*3*/').node,
-        decoratedTypeAnnotation('int/*1*/').node,
-        hard: false);
-    assertNullCheck(
-        checkExpression('c/*check*/'),
-        assertEdge(decoratedTypeAnnotation('C<int/*3*/>/*4*/').node,
-            decoratedTypeAnnotation('C<int/*1*/>/*2*/').node,
-            hard: true));
-  }
-
-  test_methodInvocation_parameter_named() async {
-    await analyze('''
-class C {
-  void f({int i: 0}) {}
-}
-void g(C c, int j) {
-  c.f(i: j/*check*/);
-}
-''');
-    var nullable_i = decoratedTypeAnnotation('int i').node;
-    var nullable_j = decoratedTypeAnnotation('int j').node;
-    assertNullCheck(checkExpression('j/*check*/'),
-        assertEdge(nullable_j, nullable_i, hard: true));
-  }
-
-  test_methodInvocation_parameter_named_differentPackage() async {
-    addPackageFile('pkgC', 'c.dart', '''
-class C {
-  void f({int i}) {}
-}
-''');
-    await analyze('''
-import "package:pkgC/c.dart";
-void g(C c, int j) {
-  c.f(i: j/*check*/);
-}
-''');
-    var nullable_j = decoratedTypeAnnotation('int j');
-    assertNullCheck(checkExpression('j/*check*/'),
-        assertEdge(nullable_j.node, never, hard: true));
-  }
-
-  test_methodInvocation_return_type() async {
-    await analyze('''
-class C {
-  bool m() => true;
-}
-bool f(C c) => c.m();
-''');
-    assertEdge(decoratedTypeAnnotation('bool m').node,
-        decoratedTypeAnnotation('bool f').node,
-        hard: false);
-  }
-
-  test_methodInvocation_return_type_null_aware() async {
-    await analyze('''
-class C {
-  bool m() => true;
-}
-bool f(C c) => (c?.m());
-''');
-    var lubNode =
-        decoratedExpressionType('(c?.m())').node as NullabilityNodeForLUB;
-    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
-    expect(lubNode.right, same(decoratedTypeAnnotation('bool m').node));
-    assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
-  }
-
-  test_methodInvocation_target_check() async {
-    await analyze('''
-class C {
-  void m() {}
-}
-void test(C c) {
-  c.m();
-}
-''');
-
-    assertNullCheck(checkExpression('c.m'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_methodInvocation_target_check_cascaded() async {
-    await analyze('''
-class C {
-  void m() {}
-}
-void test(C c) {
-  c..m();
-}
-''');
-
-    assertNullCheck(checkExpression('c..m'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_methodInvocation_target_demonstrates_non_null_intent() async {
-    await analyze('''
-class C {
-  void m() {}
-}
-void test(C c) {
-  c.m();
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
-  }
-
-  test_methodInvocation_target_demonstrates_non_null_intent_cascaded() async {
-    await analyze('''
-class C {
-  void m() {}
-}
-void test(C c) {
-  c..m();
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
-  }
-
-  test_never() async {
-    await analyze('');
-
-    expect(never.isNullable, isFalse);
-  }
-
-  test_parenthesizedExpression() async {
-    await analyze('''
-int f() {
-  return (null);
-}
-''');
-
-    assertNullCheck(checkExpression('(null)'),
-        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
-  }
-
-  test_prefixedIdentifier_field_type() async {
-    await analyze('''
-class C {
-  bool b = true;
-}
-bool f(C c) => c.b;
-''');
-    assertEdge(decoratedTypeAnnotation('bool b').node,
-        decoratedTypeAnnotation('bool f').node,
-        hard: false);
-  }
-
-  test_prefixedIdentifier_getter_type() async {
-    await analyze('''
-class C {
-  bool get b => true;
-}
-bool f(C c) => c.b;
-''');
-    assertEdge(decoratedTypeAnnotation('bool get').node,
-        decoratedTypeAnnotation('bool f').node,
-        hard: false);
-  }
-
-  test_prefixedIdentifier_target_check() async {
-    await analyze('''
-class C {
-  int get x => 1;
-}
-void test(C c) {
-  c.x;
-}
-''');
-
-    assertNullCheck(checkExpression('c.x'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_prefixedIdentifier_target_demonstrates_non_null_intent() async {
-    await analyze('''
-class C {
-  int get x => 1;
-}
-void test(C c) {
-  c.x;
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true);
-  }
-
-  test_prefixExpression_bang2() async {
-    await analyze('''
-bool f(bool b) {
-  return !b;
-}
-''');
-
-    var nullable_b = decoratedTypeAnnotation('bool b').node;
-    var check_b = checkExpression('b;');
-    assertNullCheck(check_b, assertEdge(nullable_b, never, hard: true));
-
-    var return_f = decoratedTypeAnnotation('bool f').node;
-    assertEdge(never, return_f, hard: false);
-  }
-
-  test_propertyAccess_return_type() async {
-    await analyze('''
-class C {
-  bool get b => true;
-}
-bool f(C c) => (c).b;
-''');
-    assertEdge(decoratedTypeAnnotation('bool get').node,
-        decoratedTypeAnnotation('bool f').node,
-        hard: false);
-  }
-
-  test_propertyAccess_return_type_null_aware() async {
-    await analyze('''
-class C {
-  bool get b => true;
-}
-bool f(C c) => (c?.b);
-''');
-    var lubNode =
-        decoratedExpressionType('(c?.b)').node as NullabilityNodeForLUB;
-    expect(lubNode.left, same(decoratedTypeAnnotation('C c').node));
-    expect(lubNode.right, same(decoratedTypeAnnotation('bool get b').node));
-    assertEdge(lubNode, decoratedTypeAnnotation('bool f').node, hard: false);
-  }
-
-  test_propertyAccess_target_check() async {
-    await analyze('''
-class C {
-  int get x => 1;
-}
-void test(C c) {
-  (c).x;
-}
-''');
-
-    assertNullCheck(checkExpression('c).x'),
-        assertEdge(decoratedTypeAnnotation('C c').node, never, hard: true));
-  }
-
-  test_return_implicit_null() async {
-    verifyNoTestUnitErrors = false;
-    await analyze('''
-int f() {
-  return;
-}
-''');
-
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_return_null() async {
-    await analyze('''
-int f() {
-  return null;
-}
-''');
-
-    assertNullCheck(checkExpression('null'),
-        assertEdge(always, decoratedTypeAnnotation('int').node, hard: false));
-  }
-
-  test_return_null_generic() async {
-    await analyze('''
-class C<T> {
-  T f() {
-    return null;
-  }
-}
-''');
-    var tNode = decoratedTypeAnnotation('T f').node;
-    assertEdge(always, tNode, hard: false);
-    assertNullCheck(
-        checkExpression('null'), assertEdge(always, tNode, hard: false));
-  }
-
-  @failingTest
-  test_setOrMapLiteral_map_noTypeArgument_noNullableKeysAndValues() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Map<String, int> f() {
-  return {'a' : 1, 'b' : 2};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    // TODO(brianwilkerson) Add an assertion that there is an edge from the set
-    //  literal's fake type argument to the return type's type argument.
-  }
-
-  @failingTest
-  test_setOrMapLiteral_map_noTypeArgument_nullableKey() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Map<String, int> f() {
-  return {'a' : 1, null : 2, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  @failingTest
-  test_setOrMapLiteral_map_noTypeArgument_nullableKeyAndValue() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Map<String, int> f() {
-  return {'a' : 1, null : null, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  @failingTest
-  test_setOrMapLiteral_map_noTypeArgument_nullableValue() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Map<String, int> f() {
-  return {'a' : 1, 'b' : null, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_setOrMapLiteral_map_typeArguments_noNullableKeysAndValues() async {
-    await analyze('''
-Map<String, int> f() {
-  return <String, int>{'a' : 1, 'b' : 2};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-
-    var keyForLiteral = decoratedTypeAnnotation('String, int>{').node;
-    var keyForReturnType = decoratedTypeAnnotation('String, int> ').node;
-    assertNoUpstreamNullability(keyForLiteral);
-    assertEdge(keyForLiteral, keyForReturnType, hard: false);
-
-    var valueForLiteral = decoratedTypeAnnotation('int>{').node;
-    var valueForReturnType = decoratedTypeAnnotation('int> ').node;
-    assertNoUpstreamNullability(valueForLiteral);
-    assertEdge(valueForLiteral, valueForReturnType, hard: false);
-  }
-
-  test_setOrMapLiteral_map_typeArguments_nullableKey() async {
-    await analyze('''
-Map<String, int> f() {
-  return <String, int>{'a' : 1, null : 2, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
-        hard: false);
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int>{').node);
-  }
-
-  test_setOrMapLiteral_map_typeArguments_nullableKeyAndValue() async {
-    await analyze('''
-Map<String, int> f() {
-  return <String, int>{'a' : 1, null : null, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertEdge(always, decoratedTypeAnnotation('String, int>{').node,
-        hard: false);
-    assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
-  }
-
-  test_setOrMapLiteral_map_typeArguments_nullableValue() async {
-    await analyze('''
-Map<String, int> f() {
-  return <String, int>{'a' : 1, 'b' : null, 'c' : 3};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Map').node);
-    assertNoUpstreamNullability(decoratedTypeAnnotation('String, int>{').node);
-    assertEdge(always, decoratedTypeAnnotation('int>{').node, hard: false);
-  }
-
-  @failingTest
-  test_setOrMapLiteral_set_noTypeArgument_noNullableElements() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Set<String> f() {
-  return {'a', 'b'};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
-    // TODO(brianwilkerson) Add an assertion that there is an edge from the set
-    //  literal's fake type argument to the return type's type argument.
-  }
-
-  @failingTest
-  test_setOrMapLiteral_set_noTypeArgument_nullableElement() async {
-    // Failing because we're not yet handling collection literals without a
-    // type argument.
-    await analyze('''
-Set<String> f() {
-  return {'a', null, 'c'};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
-    assertEdge(always, decoratedTypeAnnotation('String').node, hard: false);
-  }
-
-  test_setOrMapLiteral_set_typeArgument_noNullableElements() async {
-    await analyze('''
-Set<String> f() {
-  return <String>{'a', 'b'};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
-    var typeArgForLiteral = decoratedTypeAnnotation('String>{').node;
-    var typeArgForReturnType = decoratedTypeAnnotation('String> ').node;
-    assertNoUpstreamNullability(typeArgForLiteral);
-    assertEdge(typeArgForLiteral, typeArgForReturnType, hard: false);
-  }
-
-  test_setOrMapLiteral_set_typeArgument_nullableElement() async {
-    await analyze('''
-Set<String> f() {
-  return <String>{'a', null, 'c'};
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Set').node);
-    assertEdge(always, decoratedTypeAnnotation('String>{').node, hard: false);
-  }
-
-  test_simpleIdentifier_local() async {
-    await analyze('''
-main() {
-  int i = 0;
-  int j = i;
-}
-''');
-
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int j').node,
-        hard: true);
-  }
-
-  test_skipDirectives() async {
-    await analyze('''
-import "dart:core" as one;
-main() {}
-''');
-    // No test expectations.
-    // Just verifying that the test passes
-  }
-
-  test_soft_edge_for_non_variable_reference() async {
-    // Edges originating in things other than variable references should be
-    // soft.
-    await analyze('''
-int f() => null;
-''');
-    assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
-  }
-
-  test_stringLiteral() async {
-    // TODO(paulberry): also test string interpolations
-    await analyze('''
-String f() {
-  return 'x';
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('String').node);
-  }
-
-  test_superExpression() async {
-    await analyze('''
-class C {
-  C f() => super;
-}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
-  }
-
-  test_symbolLiteral() async {
-    await analyze('''
-Symbol f() {
-  return #symbol;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Symbol').node);
-  }
-
-  test_thisExpression() async {
-    await analyze('''
-class C {
-  C f() => this;
-}
-''');
-
-    assertNoUpstreamNullability(decoratedTypeAnnotation('C f').node);
-  }
-
-  test_throwExpression() async {
-    await analyze('''
-int f() {
-  return throw null;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('int').node);
-  }
-
-  test_topLevelVar_reference() async {
-    await analyze('''
-double pi = 3.1415;
-double get myPi => pi;
-''');
-    var pi = findNode.topLevelVariableDeclaration('double pi');
-    var piType =
-        variables.decoratedTypeAnnotation(testSource, pi.variables.type);
-    var myPi = findNode.any('myPi').parent as FunctionDeclaration;
-    var myPiType =
-        variables.decoratedTypeAnnotation(testSource, myPi.returnType);
-    assertEdge(piType.node, myPiType.node, hard: false);
-  }
-
-  test_type_argument_explicit_bound() async {
-    await analyze('''
-class C<T extends Object> {}
-void f(C<int> c) {}
-''');
-    assertEdge(decoratedTypeAnnotation('int>').node,
-        decoratedTypeAnnotation('Object>').node,
-        hard: true);
-  }
-
-  test_typeName() async {
-    await analyze('''
-Type f() {
-  return int;
-}
-''');
-    assertNoUpstreamNullability(decoratedTypeAnnotation('Type').node);
-  }
-
-  test_typeName_union_with_bound() async {
-    await analyze('''
-class C<T extends Object> {}
-void f(C c) {}
-''');
-    var cType = decoratedTypeAnnotation('C c');
-    var cBound = decoratedTypeAnnotation('Object');
-    assertUnion(cType.typeArguments[0].node, cBound.node);
-  }
-
-  test_typeName_union_with_bounds() async {
-    await analyze('''
-class C<T extends Object, U extends Object> {}
-void f(C c) {}
-''');
-    var cType = decoratedTypeAnnotation('C c');
-    var tBound = decoratedTypeAnnotation('Object,');
-    var uBound = decoratedTypeAnnotation('Object>');
-    assertUnion(cType.typeArguments[0].node, tBound.node);
-    assertUnion(cType.typeArguments[1].node, uBound.node);
-  }
-
-  test_variableDeclaration() async {
-    await analyze('''
-void f(int i) {
-  int j = i;
-}
-''');
-    assertEdge(decoratedTypeAnnotation('int i').node,
-        decoratedTypeAnnotation('int j').node,
-        hard: true);
-  }
-}
diff --git a/pkg/nnbd_migration/test/migration_visitor_test_base.dart b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
index 2e2e9d1..f1c70ba 100644
--- a/pkg/nnbd_migration/test/migration_visitor_test_base.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test_base.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:meta/meta.dart';
@@ -96,6 +97,8 @@
 
   TypeProvider get typeProvider => testAnalysisResult.typeProvider;
 
+  TypeSystem get typeSystem => testAnalysisResult.typeSystem;
+
   Future<CompilationUnit> analyze(String code) async {
     await resolveTestUnit(code);
     testUnit
@@ -137,6 +140,15 @@
     fail('Expected union between $x and $y, not found');
   }
 
+  /// Gets the [DecoratedType] associated with the constructor declaration whose
+  /// name matches [search].
+  DecoratedType decoratedConstructorDeclaration(String search) => variables
+      .decoratedElementType(findNode.constructor(search).declaredElement);
+
+  Map<ClassElement, DecoratedType> decoratedDirectSupertypes(String name) {
+    return variables.decoratedDirectSupertypes(findElement.classOrMixin(name));
+  }
+
   /// Gets the [DecoratedType] associated with the generic function type
   /// annotation whose text is [text].
   DecoratedType decoratedGenericFunctionTypeAnnotation(String text) {
@@ -144,6 +156,11 @@
         testSource, findNode.genericFunctionType(text));
   }
 
+  /// Gets the [DecoratedType] associated with the method declaration whose
+  /// name matches [search].
+  DecoratedType decoratedMethodType(String search) => variables
+      .decoratedElementType(findNode.methodDeclaration(search).declaredElement);
+
   /// Gets the [DecoratedType] associated with the type annotation whose text
   /// is [text].
   DecoratedType decoratedTypeAnnotation(String text) {
diff --git a/pkg/nnbd_migration/test/node_builder_test.dart b/pkg/nnbd_migration/test/node_builder_test.dart
index ef4476f..fbfab3b 100644
--- a/pkg/nnbd_migration/test/node_builder_test.dart
+++ b/pkg/nnbd_migration/test/node_builder_test.dart
@@ -17,11 +17,6 @@
 
 @reflectiveTest
 class NodeBuilderTest extends MigrationVisitorTestBase {
-  /// Gets the [DecoratedType] associated with the constructor declaration whose
-  /// name matches [search].
-  DecoratedType decoratedConstructorDeclaration(String search) => variables
-      .decoratedElementType(findNode.constructor(search).declaredElement);
-
   /// Gets the [DecoratedType] associated with the function declaration whose
   /// name matches [search].
   DecoratedType decoratedFunctionType(String search) =>
@@ -31,6 +26,171 @@
   DecoratedType decoratedTypeParameterBound(String search) => variables
       .decoratedElementType(findNode.typeParameter(search).declaredElement);
 
+  test_class_alias_synthetic_constructors_no_parameters() async {
+    await analyze('''
+class C {
+  C.a();
+  C.b();
+}
+mixin M {}
+class D = C with M;
+''');
+    var constructors = findElement.class_('D').constructors;
+    expect(constructors, hasLength(2));
+    var a = findElement.constructor('a', of: 'D');
+    var aType = variables.decoratedElementType(a);
+    expect(aType.type.toString(), 'D Function()');
+    expect(aType.node, same(never));
+    expect(aType.typeArguments, isEmpty);
+    expect(aType.returnType.type.toString(), 'D');
+    expect(aType.returnType.node, same(never));
+    var b = findElement.constructor('b', of: 'D');
+    var bType = variables.decoratedElementType(b);
+    expect(bType.type.toString(), 'D Function()');
+    expect(bType.node, same(never));
+    expect(bType.typeArguments, isEmpty);
+    expect(bType.returnType.type.toString(), 'D');
+    expect(bType.returnType.node, same(never));
+  }
+
+  test_class_alias_synthetic_constructors_with_parameters() async {
+    await analyze('''
+class C {
+  C.a(int i);
+  C.b([int i]);
+  C.c({int i});
+  C.d(List<int> x);
+}
+mixin M {}
+class D = C with M;
+''');
+    var constructors = findElement.class_('D').constructors;
+    expect(constructors, hasLength(4));
+    var a = findElement.constructor('a', of: 'D');
+    var aType = variables.decoratedElementType(a);
+    expect(aType.type.toString(), 'D Function(int)');
+    expect(aType.node, same(never));
+    expect(aType.typeArguments, isEmpty);
+    expect(aType.returnType.type.toString(), 'D');
+    expect(aType.returnType.node, same(never));
+    expect(aType.positionalParameters, hasLength(1));
+    expect(aType.positionalParameters[0].type.toString(), 'int');
+    expect(aType.positionalParameters[0].node,
+        TypeMatcher<NullabilityNodeMutable>());
+    expect(aType.namedParameters, isEmpty);
+    var b = findElement.constructor('b', of: 'D');
+    var bType = variables.decoratedElementType(b);
+    expect(bType.type.toString(), 'D Function([int])');
+    expect(bType.node, same(never));
+    expect(bType.typeArguments, isEmpty);
+    expect(bType.returnType.type.toString(), 'D');
+    expect(bType.returnType.node, same(never));
+    expect(bType.positionalParameters, hasLength(1));
+    expect(bType.positionalParameters[0].type.toString(), 'int');
+    expect(bType.positionalParameters[0].node,
+        TypeMatcher<NullabilityNodeMutable>());
+    expect(bType.namedParameters, isEmpty);
+    var c = findElement.constructor('c', of: 'D');
+    var cType = variables.decoratedElementType(c);
+    expect(cType.type.toString(), 'D Function({i: int})');
+    expect(cType.node, same(never));
+    expect(cType.typeArguments, isEmpty);
+    expect(cType.returnType.type.toString(), 'D');
+    expect(cType.returnType.node, same(never));
+    expect(cType.positionalParameters, isEmpty);
+    expect(cType.namedParameters, hasLength(1));
+    expect(cType.namedParameters, contains('i'));
+    expect(cType.namedParameters['i'].type.toString(), 'int');
+    expect(
+        cType.namedParameters['i'].node, TypeMatcher<NullabilityNodeMutable>());
+    var d = findElement.constructor('d', of: 'D');
+    var dType = variables.decoratedElementType(d);
+    expect(dType.type.toString(), 'D Function(List<int>)');
+    expect(dType.node, same(never));
+    expect(dType.typeArguments, isEmpty);
+    expect(dType.returnType.type.toString(), 'D');
+    expect(dType.returnType.node, same(never));
+    expect(dType.positionalParameters, hasLength(1));
+    expect(dType.positionalParameters[0].type.toString(), 'List<int>');
+    expect(dType.positionalParameters[0].node,
+        TypeMatcher<NullabilityNodeMutable>());
+    expect(dType.positionalParameters[0].typeArguments, hasLength(1));
+    expect(
+        dType.positionalParameters[0].typeArguments[0].type.toString(), 'int');
+    expect(dType.positionalParameters[0].typeArguments[0].node,
+        TypeMatcher<NullabilityNodeMutable>());
+    expect(dType.namedParameters, isEmpty);
+  }
+
+  test_class_alias_synthetic_constructors_with_parameters_generic() async {
+    await analyze('''
+class C<T> {
+  C(T t);
+}
+mixin M {}
+class D<U> = C<U> with M;
+''');
+    var dConstructor = findElement.unnamedConstructor('D');
+    var dConstructorType = variables.decoratedElementType(dConstructor);
+    expect(dConstructorType.type.toString(), 'D<U> Function(U)');
+    expect(dConstructorType.node, same(never));
+    expect(dConstructorType.typeFormals, isEmpty);
+    expect(dConstructorType.returnType.type.toString(), 'D<U>');
+    expect(dConstructorType.returnType.node, same(never));
+    var typeArguments = dConstructorType.returnType.typeArguments;
+    expect(typeArguments, hasLength(1));
+    expect(typeArguments[0].type.toString(), 'U');
+    expect(typeArguments[0].node, same(never));
+    var dParams = dConstructorType.positionalParameters;
+    expect(dParams, hasLength(1));
+    expect(dParams[0].type.toString(), 'U');
+    expect(dParams[0].node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_class_with_default_constructor() async {
+    await analyze('''
+class C {}
+''');
+    var defaultConstructor = findElement.class_('C').constructors.single;
+    var decoratedConstructorType =
+        variables.decoratedElementType(defaultConstructor);
+    expect(decoratedConstructorType.type.toString(), 'C Function()');
+    expect(decoratedConstructorType.node, same(never));
+    expect(decoratedConstructorType.returnType.type.toString(), 'C');
+    expect(decoratedConstructorType.returnType.node, same(never));
+  }
+
+  test_class_with_default_constructor_generic() async {
+    await analyze('''
+class C<T, U> {}
+''');
+    var defaultConstructor = findElement.class_('C').constructors.single;
+    var decoratedConstructorType =
+        variables.decoratedElementType(defaultConstructor);
+    expect(decoratedConstructorType.type.toString(), 'C<T, U> Function()');
+    expect(decoratedConstructorType.node, same(never));
+    expect(decoratedConstructorType.typeArguments, isEmpty);
+    var returnType = decoratedConstructorType.returnType;
+    expect(returnType.type.toString(), 'C<T, U>');
+    expect(returnType.node, same(never));
+    expect(returnType.typeArguments, hasLength(2));
+    expect(returnType.typeArguments[0].type.toString(), 'T');
+    expect(returnType.typeArguments[0].node, same(never));
+    expect(returnType.typeArguments[1].type.toString(), 'U');
+    expect(returnType.typeArguments[1].node, same(never));
+  }
+
+  test_constructor_factory() async {
+    await analyze('''
+class C {
+  C._();
+  factory C() => C._();
+}
+''');
+    var decoratedType = decoratedConstructorDeclaration('C(').returnType;
+    expect(decoratedType.node, same(never));
+  }
+
   test_constructor_returnType_implicit_dynamic() async {
     await analyze('''
 class C {
@@ -41,6 +201,158 @@
     expect(decoratedType.node, same(never));
   }
 
+  test_directSupertypes_class_extends() async {
+    await analyze('''
+class C<T, U> {}
+class D<V> extends C<int, V> {}
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> {').node));
+  }
+
+  test_directSupertypes_class_extends_default() async {
+    await analyze('''
+class C<T, U> {}
+''');
+    var types = decoratedDirectSupertypes('C');
+    var decorated = types[typeProvider.objectType.element];
+    expect(decorated.type.toString(), 'Object');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, isEmpty);
+  }
+
+  test_directSupertypes_class_implements() async {
+    await analyze('''
+class C<T, U> {}
+class D<V> implements C<int, V> {}
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> {').node));
+  }
+
+  test_directSupertypes_class_with() async {
+    await analyze('''
+class C<T, U> {}
+class D<V> extends Object with C<int, V> {}
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> {').node));
+  }
+
+  test_directSupertypes_classAlias_extends() async {
+    await analyze('''
+class M {}
+class C<T, U> {}
+class D<V> = C<int, V> with M;
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> w').node));
+  }
+
+  test_directSupertypes_classAlias_implements() async {
+    await analyze('''
+class M {}
+class C<T, U> {}
+class D<V> = Object with M implements C<int, V>;
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V>;').node));
+  }
+
+  test_directSupertypes_classAlias_with() async {
+    await analyze('''
+class C<T, U> {}
+class D<V> = Object with C<int, V>;
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V>;').node));
+  }
+
+  test_directSupertypes_mixin_extends_default() async {
+    await analyze('''
+mixin C<T, U> {}
+''');
+    var types = decoratedDirectSupertypes('C');
+    var decorated = types[typeProvider.objectType.element];
+    expect(decorated.type.toString(), 'Object');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, isEmpty);
+  }
+
+  test_directSupertypes_mixin_implements() async {
+    await analyze('''
+class C<T, U> {}
+mixin D<V> implements C<int, V> {}
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> {').node));
+  }
+
+  test_directSupertypes_mixin_on() async {
+    await analyze('''
+class C<T, U> {}
+mixin D<V> on C<int, V> {}
+''');
+    var types = decoratedDirectSupertypes('D');
+    var decorated = types[findElement.class_('C')];
+    expect(decorated.type.toString(), 'C<int, V>');
+    expect(decorated.node, same(never));
+    expect(decorated.typeArguments, hasLength(2));
+    expect(decorated.typeArguments[0].node,
+        same(decoratedTypeAnnotation('int').node));
+    expect(decorated.typeArguments[1].node,
+        same(decoratedTypeAnnotation('V> {').node));
+  }
+
   test_dynamic_type() async {
     await analyze('''
 dynamic f() {}
@@ -50,6 +362,40 @@
     assertEdge(always, decoratedType.node, hard: false);
   }
 
+  test_field_type_implicit_dynamic() async {
+    await analyze('''
+class C {
+  var x;
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
+  test_field_type_inferred() async {
+    await analyze('''
+class C {
+  var x = 1;
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_field_type_inferred_dynamic() async {
+    await analyze('''
+dynamic f() {}
+class C {
+  var x = f();
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
   test_field_type_simple() async {
     await analyze('''
 class C {
@@ -64,6 +410,235 @@
         same(decoratedType));
   }
 
+  test_fieldFormalParameter_function_namedParameter_typed() async {
+    await analyze('''
+class C {
+  Object f;
+  C(void this.f({int i}));
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.namedParameters['i'],
+        same(decoratedTypeAnnotation('int')));
+  }
+
+  test_fieldFormalParameter_function_namedParameter_untyped() async {
+    await analyze('''
+class C {
+  Object f;
+  C(void this.f({i}));
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.namedParameters['i'].type.toString(), 'dynamic');
+    expect(ctorParamType.namedParameters['i'].node, same(always));
+  }
+
+  test_fieldFormalParameter_function_positionalParameter_typed() async {
+    await analyze('''
+class C {
+  Object f;
+  C(void this.f(int i));
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.positionalParameters[0],
+        same(decoratedTypeAnnotation('int')));
+  }
+
+  test_fieldFormalParameter_function_positionalParameter_untyped() async {
+    await analyze('''
+class C {
+  Object f;
+  C(void this.f(i));
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.positionalParameters[0].type.toString(), 'dynamic');
+    expect(ctorParamType.positionalParameters[0].node, same(always));
+  }
+
+  test_fieldFormalParameter_function_return_typed() async {
+    await analyze('''
+class C {
+  Object f;
+  C(int this.f());
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.returnType, same(decoratedTypeAnnotation('int')));
+  }
+
+  test_fieldFormalParameter_function_return_untyped() async {
+    await analyze('''
+class C {
+  Object f;
+  C(this.f()) {}
+}
+''');
+    var ctor = findElement.unnamedConstructor('C');
+    var ctorParam = ctor.parameters[0];
+    var ctorType = variables.decoratedElementType(ctor);
+    var ctorParamType = variables.decoratedElementType(ctorParam);
+    expect(ctorType.positionalParameters[0], same(ctorParamType));
+    expect(ctorParamType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(ctorParamType.returnType.type.toString(), 'dynamic');
+    expect(ctorParamType.returnType.node, same(always));
+  }
+
+  test_fieldFormalParameter_typed() async {
+    await analyze('''
+class C {
+  int i;
+  C.named(int this.i);
+}
+''');
+    var decoratedConstructorParamType =
+        decoratedConstructorDeclaration('named').positionalParameters[0];
+    expect(decoratedTypeAnnotation('int this'),
+        same(decoratedConstructorParamType));
+    expect(decoratedConstructorParamType.type.toString(), 'int');
+    expect(decoratedConstructorParamType.node,
+        TypeMatcher<NullabilityNodeMutable>());
+    // Note: the edge builder will connect this node to the node for the type of
+    // the field.
+  }
+
+  test_fieldFormalParameter_untyped() async {
+    await analyze('''
+class C {
+  int i;
+  C.named(this.i);
+}
+''');
+    var decoratedConstructorParamType =
+        decoratedConstructorDeclaration('named').positionalParameters[0];
+    expect(decoratedConstructorParamType.type.toString(), 'int');
+    expect(decoratedConstructorParamType.node,
+        TypeMatcher<NullabilityNodeMutable>());
+    // Note: the edge builder will unify this implicit type with the type of the
+    // field.
+  }
+
+  test_functionTypedFormalParameter_namedParameter_typed() async {
+    await analyze('''
+void f(void g({int i})) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.namedParameters['i'], same(decoratedTypeAnnotation('int')));
+  }
+
+  test_functionTypedFormalParameter_namedParameter_untyped() async {
+    await analyze('''
+void f(void g({i})) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.namedParameters['i'].type.toString(), 'dynamic');
+    expect(gType.namedParameters['i'].node, same(always));
+  }
+
+  test_functionTypedFormalParameter_positionalParameter_typed() async {
+    await analyze('''
+void f(void g(int i)) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.positionalParameters[0], same(decoratedTypeAnnotation('int')));
+  }
+
+  test_functionTypedFormalParameter_positionalParameter_untyped() async {
+    await analyze('''
+void f(void g(i)) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.positionalParameters[0].type.toString(), 'dynamic');
+    expect(gType.positionalParameters[0].node, same(always));
+  }
+
+  test_functionTypedFormalParameter_return_typed() async {
+    await analyze('''
+void f(int g()) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.returnType, same(decoratedTypeAnnotation('int')));
+  }
+
+  test_functionTypedFormalParameter_return_untyped() async {
+    await analyze('''
+void f(g()) {}
+''');
+    var f = findElement.function('f');
+    var g = f.parameters[0];
+    var fType = variables.decoratedElementType(f);
+    var gType = variables.decoratedElementType(g);
+    expect(fType.positionalParameters[0], same(gType));
+    expect(gType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(gType.returnType.type.toString(), 'dynamic');
+    expect(gType.returnType.node, same(always));
+  }
+
+  test_generic_function_type_syntax_inferred_dynamic_return() async {
+    await analyze('''
+abstract class C {
+  Function() f();
+}
+''');
+    var decoratedFType = decoratedMethodType('f');
+    var decoratedFReturnType = decoratedFType.returnType;
+    var decoratedFReturnReturnType = decoratedFReturnType.returnType;
+    expect(decoratedFReturnReturnType.type.toString(), 'dynamic');
+    expect(decoratedFReturnReturnType.node, same(always));
+  }
+
   test_genericFunctionType_namedParameterType() async {
     await analyze('''
 void f(void Function({int y}) x) {}
@@ -122,18 +697,54 @@
     expect(decoratedArgType.node, same(always));
   }
 
+  test_interfaceType_generic_instantiate_to_function_type() async {
+    await analyze('''
+class C<T extends int Function()> {}
+void f(C x) {}
+''');
+    var decoratedCType = decoratedTypeAnnotation('C x');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedCType));
+    expect(decoratedCType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedCType.typeArguments, hasLength(1));
+    var decoratedArgType = decoratedCType.typeArguments[0];
+    expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedArgType.typeArguments, isEmpty);
+    var decoratedArgReturnType = decoratedArgType.returnType;
+    expect(decoratedArgReturnType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedArgReturnType.typeArguments, isEmpty);
+  }
+
+  test_interfaceType_generic_instantiate_to_function_type_void() async {
+    await analyze('''
+class C<T extends void Function()> {}
+void f(C x) {}
+''');
+    var decoratedCType = decoratedTypeAnnotation('C x');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedCType));
+    expect(decoratedCType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedCType.typeArguments, hasLength(1));
+    var decoratedArgType = decoratedCType.typeArguments[0];
+    expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedArgType.typeArguments, isEmpty);
+    var decoratedArgReturnType = decoratedArgType.returnType;
+    expect(decoratedArgReturnType.node, same(always));
+    expect(decoratedArgReturnType.typeArguments, isEmpty);
+  }
+
   test_interfaceType_generic_instantiate_to_generic_type() async {
     await analyze('''
 class C<T> {}
 class D<T extends C<int>> {}
 void f(D x) {}
 ''');
-    var decoratedListType = decoratedTypeAnnotation('D x');
+    var decoratedDType = decoratedTypeAnnotation('D x');
     expect(decoratedFunctionType('f').positionalParameters[0],
-        same(decoratedListType));
-    expect(decoratedListType.node, TypeMatcher<NullabilityNodeMutable>());
-    expect(decoratedListType.typeArguments, hasLength(1));
-    var decoratedArgType = decoratedListType.typeArguments[0];
+        same(decoratedDType));
+    expect(decoratedDType.node, TypeMatcher<NullabilityNodeMutable>());
+    expect(decoratedDType.typeArguments, hasLength(1));
+    var decoratedArgType = decoratedDType.typeArguments[0];
     expect(decoratedArgType.node, TypeMatcher<NullabilityNodeMutable>());
     expect(decoratedArgType.typeArguments, hasLength(1));
     var decoratedArgArgType = decoratedArgType.typeArguments[0];
@@ -202,6 +813,157 @@
     expect(decoratedIntType.node, isNot(never));
   }
 
+  test_localVariable_type_implicit_dynamic() async {
+    await analyze('''
+main() {
+  var x;
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
+  test_localVariable_type_inferred() async {
+    await analyze('''
+main() {
+  var x = 1;
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_localVariable_type_inferred_dynamic() async {
+    await analyze('''
+dynamic f() {}
+main() {
+  var x = f();
+}
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_parameterType_implicit_dynamic() async {
+    await analyze('''
+class C {
+  void f(x) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f').positionalParameters[0];
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_parameterType_implicit_dynamic_named() async {
+    await analyze('''
+class C {
+  void f({x}) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f').namedParameters['x'];
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_parameterType_inferred() async {
+    await analyze('''
+class B {
+  void f(int x) {}
+}
+class C extends B {
+  void f/*C*/(x) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').positionalParameters[0];
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_method_parameterType_inferred_dynamic() async {
+    await analyze('''
+class B {
+  void f(dynamic x) {}
+}
+class C extends B {
+  void f/*C*/(x) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').positionalParameters[0];
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_parameterType_inferred_dynamic_named() async {
+    await analyze('''
+class B {
+  void f({dynamic x = 0}) {}
+}
+class C extends B {
+  void f/*C*/({x = 0}) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').namedParameters['x'];
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_parameterType_inferred_named() async {
+    await analyze('''
+class B {
+  void f({int x = 0}) {}
+}
+class C extends B {
+  void f/*C*/({x = 0}) {}
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').namedParameters['x'];
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_method_returnType_implicit_dynamic() async {
+    await analyze('''
+class C {
+  f() => 1;
+}
+''');
+    var decoratedType = decoratedMethodType('f').returnType;
+    expect(decoratedType.node, same(always));
+  }
+
+  test_method_returnType_inferred() async {
+    await analyze('''
+class B {
+  int f() => 1;
+}
+class C extends B {
+  f/*C*/() => 1;
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').returnType;
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_method_returnType_inferred_dynamic() async {
+    await analyze('''
+class B {
+  dynamic f() => 1;
+}
+class C extends B {
+  f/*C*/() => 1;
+}
+''');
+    var decoratedType = decoratedMethodType('f/*C*/').returnType;
+    expect(decoratedType.node, same(always));
+  }
+
+  test_parameters() async {
+    await analyze('''
+void foo({List<int> values})  {
+  values.where((i) => true);
+}
+''');
+    // No assertions; just checking that it doesn't crash.
+  }
+
   test_topLevelFunction_parameterType_implicit_dynamic() async {
     await analyze('''
 void f(x) {}
@@ -211,7 +973,6 @@
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
     expect(decoratedType.type.isDynamic, isTrue);
-    assertUnion(always, decoratedType.node);
   }
 
   test_topLevelFunction_parameterType_named_no_default() async {
@@ -282,7 +1043,6 @@
 ''');
     var decoratedType = decoratedFunctionType('f').returnType;
     expect(decoratedType.type.isDynamic, isTrue);
-    assertUnion(always, decoratedType.node);
   }
 
   test_topLevelFunction_returnType_simple() async {
@@ -295,6 +1055,34 @@
     expect(decoratedType.node, isNot(never));
   }
 
+  test_topLevelVariable_type_implicit_dynamic() async {
+    await analyze('''
+var x;
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
+  test_topLevelVariable_type_inferred() async {
+    await analyze('''
+var x = 1;
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
+  test_topLevelVariable_type_inferred_dynamic() async {
+    await analyze('''
+dynamic f() {}
+var x = f();
+''');
+    var decoratedType =
+        variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedType.node, same(always));
+  }
+
   test_type_comment_bang() async {
     await analyze('''
 void f(int/*!*/ i) {}
@@ -341,6 +1129,17 @@
     expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
   }
 
+  test_variableDeclaration_visit_initializer() async {
+    await analyze('''
+class C<T> {}
+void f(C<dynamic> c) {
+  var x = c as C<int>;
+}
+''');
+    var decoratedType = decoratedTypeAnnotation('int');
+    expect(decoratedType.node, TypeMatcher<NullabilityNodeMutable>());
+  }
+
   test_void_type() async {
     await analyze('''
 void f() {}
diff --git a/pkg/nnbd_migration/test/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
index 4241cf2..e8b5c72 100644
--- a/pkg/nnbd_migration/test/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -5,14 +5,18 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'api_test.dart' as api_test;
-import 'graph_builder_test.dart' as graph_builder_test;
+import 'decorated_class_hierarchy_test.dart' as decorated_class_hierarchy_test;
+import 'decorated_type_test.dart' as decorated_type_test;
+import 'edge_builder_test.dart' as edge_builder_test;
 import 'node_builder_test.dart' as node_builder_test;
 import 'nullability_node_test.dart' as nullability_node_test;
 
 main() {
   defineReflectiveSuite(() {
     api_test.main();
-    graph_builder_test.main();
+    decorated_class_hierarchy_test.main();
+    decorated_type_test.main();
+    edge_builder_test.main();
     node_builder_test.main();
     nullability_node_test.main();
   });
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index 9fc946a..eb79e61 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -303,7 +303,7 @@
 
   final bool isCsp;
 
-  // TODO(rnystrom): Remove this when Dart 1.0 is no longer supported.
+  /// Enables asserts in the dart2js compiler.
   final bool isHostChecked;
 
   final bool isMinified;
@@ -585,13 +585,11 @@
 
 class Compiler extends NamedEnum {
   static const none = const Compiler._('none');
-  static const precompiler = const Compiler._('precompiler');
   static const dart2js = const Compiler._('dart2js');
   static const dart2analyzer = const Compiler._('dart2analyzer');
   static const compareAnalyzerCfe = const Compiler._('compare_analyzer_cfe');
   static const dartdevc = const Compiler._('dartdevc');
   static const dartdevk = const Compiler._('dartdevk');
-  static const appJit = const Compiler._('app_jit');
   static const appJitk = const Compiler._('app_jitk');
   static const dartk = const Compiler._('dartk');
   static const dartkp = const Compiler._('dartkp');
@@ -603,13 +601,11 @@
 
   static final _all = new Map<String, Compiler>.fromIterable([
     none,
-    precompiler,
     dart2js,
     dart2analyzer,
     compareAnalyzerCfe,
     dartdevc,
     dartdevk,
-    appJit,
     appJitk,
     dartk,
     dartkp,
@@ -664,12 +660,10 @@
       case Compiler.dart2analyzer:
       case Compiler.compareAnalyzerCfe:
         return const [Runtime.none];
-      case Compiler.appJit:
       case Compiler.appJitk:
       case Compiler.dartk:
       case Compiler.dartkb:
         return const [Runtime.vm, Runtime.selfCheck];
-      case Compiler.precompiler:
       case Compiler.dartkp:
         return const [Runtime.dartPrecompiled];
       case Compiler.specParser:
@@ -695,12 +689,10 @@
       case Compiler.dart2analyzer:
       case Compiler.compareAnalyzerCfe:
         return Runtime.none;
-      case Compiler.appJit:
       case Compiler.appJitk:
       case Compiler.dartk:
       case Compiler.dartkb:
         return Runtime.vm;
-      case Compiler.precompiler:
       case Compiler.dartkp:
         return Runtime.dartPrecompiled;
       case Compiler.specParser:
@@ -828,7 +820,7 @@
         return Compiler.none;
 
       case dartPrecompiled:
-        return Compiler.precompiler;
+        return Compiler.dartkp;
 
       case d8:
       case jsshell:
diff --git a/pkg/sourcemap_testing/README.md b/pkg/sourcemap_testing/README.md
index fa8ea7a..11167b4 100644
--- a/pkg/sourcemap_testing/README.md
+++ b/pkg/sourcemap_testing/README.md
@@ -112,8 +112,7 @@
 ### Technical details
 
 Some of the logic comes from https://github.com/ChromeDevTools/devtools-frontend/, for instance see
-https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/
-front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
+https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
 for how a line breakpoint is resolved:
 Basically the line asked to break on in user code (e.g. in dart code) is asked for first and last
 javascript positions; these are then used to get possible breakpoints in that part. If there are
diff --git a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
index 2e2f18b..505b951 100644
--- a/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stacktrace_helper.dart
@@ -7,13 +7,12 @@
 import 'dart:convert' show jsonDecode;
 
 import 'package:expect/expect.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 import 'package:source_maps/source_maps.dart';
 import 'package:source_maps/src/utils.dart';
 import 'package:source_span/source_span.dart';
 import 'package:dart2js_tools/src/dart2js_mapping.dart';
 
-import 'annotated_code_helper.dart';
-
 const String INPUT_FILE_NAME = 'input.dart';
 
 class Test {
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index 7cd8a6b..d001fd6 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -1,11 +1,10 @@
 import 'dart:io';
 
 import 'package:expect/minitest.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 import 'package:path/path.dart' as path;
 import 'package:source_maps/source_maps.dart';
 
-import 'annotated_code_helper.dart';
-
 /**
  * Runs D8 and steps as the AnnotatedCode dictates.
  *
diff --git a/pkg/sourcemap_testing/pubspec.yaml b/pkg/sourcemap_testing/pubspec.yaml
index a7ee40e..070ea67 100644
--- a/pkg/sourcemap_testing/pubspec.yaml
+++ b/pkg/sourcemap_testing/pubspec.yaml
@@ -8,3 +8,4 @@
 dependencies:
   package_config: '>=0.1.1 <2.0.0'
   pub_semver: ^1.2.1
+  front_end: ^0.1.20
diff --git a/pkg/status_file/test/data/lib_2_app_jit.status b/pkg/status_file/test/data/lib_2_app_jit.status
deleted file mode 100644
index a2a86f3..0000000
--- a/pkg/status_file/test/data/lib_2_app_jit.status
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) 2017, 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.
-
-[ $compiler == app_jit ]
-mirrors/*: Skip # Issue 27929: Triage
diff --git a/pkg/status_file/test/data/standalone_2_vm.status b/pkg/status_file/test/data/standalone_2_vm.status
index 8c521ab..2b85902 100644
--- a/pkg/status_file/test/data/standalone_2_vm.status
+++ b/pkg/status_file/test/data/standalone_2_vm.status
@@ -43,13 +43,6 @@
 [ $system == windows && $compiler != dart2analyzer ]
 io/platform_resolved_executable_test/06: RuntimeError  # Issue 23641
 
-[ $compiler == app_jit ]
-io/test_extension_test: Skip # Platform.executable
-io/test_extension_fail_test: Skip # Platform.executable
-io/platform_test: Skip # Platform.executable
-full_coverage_test: Skip # Platform.executable
-regress_26031_test: Skip # Platform.resolvedExecutable
-
 [ $system == android ]
 io/process_exit_test: Skip # Issue 29578
 io/process_path_test: Skip # Issue 26376
diff --git a/pkg/status_file/test/data/vm.status b/pkg/status_file/test/data/vm.status
index bf2543f..5cb581d 100644
--- a/pkg/status_file/test/data/vm.status
+++ b/pkg/status_file/test/data/vm.status
@@ -126,9 +126,6 @@
 [ $compiler == dart2analyzer && $strong ]
 *: Skip # Issue 28649
 
-[ $compiler == app_jit ]
-dart/snapshot_version_test: Fail,OK # Expects to find script snapshot relative to Dart source.
-
 [ $runtime != vm ]
 dart/snapshot_version_test: SkipByDesign  # Spawns processes
 dart/spawn_infinite_loop_test: Skip  # VM shutdown test
@@ -156,18 +153,12 @@
 cc/IsolateReload_TypeIdentityGeneric: Fail # Issue 28349
 cc/IsolateReload_TypeIdentityParameter: Fail # Issue 28349
 
-[ $compiler == precompiler ]
-dart/byte_array_test: Skip # Incompatible flag --disable_alloc_stubs_after_gc
-
-[ $compiler == precompiler || $mode == product ]
+[ $mode == product ]
 dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
 cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
 cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
 cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
 
-[ $compiler == app_jit ]
-dart/optimized_stacktrace_line_and_column_test: RuntimeError,OK # app-jit lacks column information
-
 [ $runtime == dart_precompiled ]
 dart/optimized_stacktrace_line_and_column_test: RuntimeError,OK # AOT lacks column information
 dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
diff --git a/pkg/telemetry/lib/telemetry.dart b/pkg/telemetry/lib/telemetry.dart
index 6340cd2..ef3491f 100644
--- a/pkg/telemetry/lib/telemetry.dart
+++ b/pkg/telemetry/lib/telemetry.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io';
 
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 import 'package:usage/src/usage_impl.dart';
 import 'package:usage/src/usage_impl_io.dart';
@@ -52,14 +53,26 @@
 ///
 /// This analytics instance will share a common enablement state with the rest
 /// of the Dart SDK tools.
-_TelemetryAnalytics createAnalyticsInstance(
+Analytics createAnalyticsInstance(
   String trackingId,
   String applicationName, {
   bool disableForSession: false,
 }) {
   Directory dir = getDartStorageDirectory();
+  if (dir == null) {
+    // Some systems don't support user home directories; for those, fail
+    // gracefully by returning a disabled analytics object.
+    return new _DisabledAnalytics(trackingId, applicationName);
+  }
+
   if (!dir.existsSync()) {
-    dir.createSync();
+    try {
+      dir.createSync();
+    } catch (e) {
+      // If we can't create the directory for the analytics settings, fail
+      // gracefully by returning a disabled analytics object.
+      return new _DisabledAnalytics(trackingId, applicationName);
+    }
   }
 
   File file = new File(path.join(dir.path, _settingsFileName));
@@ -71,8 +84,15 @@
 ///
 /// Typically, the directory is `~/.dart/` (and the settings file is
 /// `analytics.json`).
+///
+/// This can return null under some conditions, including when the user's home
+/// directory does not exist.
+@visibleForTesting
 Directory getDartStorageDirectory() {
-  return new Directory(path.join(userHomeDir(), _dartDirectoryName));
+  Directory homeDirectory = new Directory(userHomeDir());
+  if (!homeDirectory.existsSync()) return null;
+
+  return new Directory(path.join(homeDirectory.path, _dartDirectoryName));
 }
 
 /// Return the version of the Dart SDK.
@@ -111,6 +131,23 @@
   }
 }
 
+class _DisabledAnalytics extends AnalyticsMock {
+  @override
+  final String trackingId;
+  @override
+  final String applicationName;
+
+  _DisabledAnalytics(this.trackingId, this.applicationName);
+
+  @override
+  bool get enabled => false;
+}
+
+/// Detect whether we're running on a bot or in a continuous testing
+/// environment.
+///
+/// We should periodically keep this code up to date with
+/// https://github.com/flutter/flutter/blob/master/packages/flutter_tools/lib/src/base/utils.dart#L20.
 bool isRunningOnBot() {
   final Map<String, String> env = Platform.environment;
 
diff --git a/pkg/telemetry/pubspec.yaml b/pkg/telemetry/pubspec.yaml
index 15dc588..8084a84 100644
--- a/pkg/telemetry/pubspec.yaml
+++ b/pkg/telemetry/pubspec.yaml
@@ -8,6 +8,7 @@
 
 dependencies:
   http: ^0.12.0
+  meta: ^1.0.2
   path: ^1.4.0
   stack_trace: ^1.7.0
   usage: ^3.2.0+1
diff --git a/pkg/test_runner/lib/src/browser_controller.dart b/pkg/test_runner/lib/src/browser_controller.dart
index dd67eef..afd23cb 100644
--- a/pkg/test_runner/lib/src/browser_controller.dart
+++ b/pkg/test_runner/lib/src/browser_controller.dart
@@ -1194,7 +1194,7 @@
     errorReportingServer = server;
     void errorReportingHandler(HttpRequest request) {
       var buffer = StringBuffer();
-      request.transform(utf8.decoder).listen((data) {
+      request.cast<List<int>>().transform(utf8.decoder).listen((data) {
         buffer.write(data);
       }, onDone: () {
         var back = buffer.toString();
@@ -1285,7 +1285,7 @@
   void handleReport(HttpRequest request, String browserId, int testId,
       {bool isStatusUpdate}) {
     var buffer = StringBuffer();
-    request.transform(utf8.decoder).listen((data) {
+    request.cast<List<int>>().transform(utf8.decoder).listen((data) {
       buffer.write(data);
     }, onDone: () {
       var back = buffer.toString();
@@ -1306,7 +1306,7 @@
     // If an error occurs while receiving the data from the request stream,
     // we don't handle it specially. We can safely ignore it, since the started
     // events are not crucial.
-    request.transform(utf8.decoder).listen((data) {
+    request.cast<List<int>>().transform(utf8.decoder).listen((data) {
       buffer.write(data);
     }, onDone: () {
       var back = buffer.toString();
diff --git a/pkg/test_runner/lib/src/command.dart b/pkg/test_runner/lib/src/command.dart
index e6ea871..d8707ab 100644
--- a/pkg/test_runner/lib/src/command.dart
+++ b/pkg/test_runner/lib/src/command.dart
@@ -76,20 +76,21 @@
   }
 
   static Command adbPrecompiled(
-      String precompiledRunner,
+      String buildPath,
       String processTest,
       String testDirectory,
       List<String> arguments,
       bool useBlobs,
-      bool useElf) {
-    return AdbPrecompilationCommand._(precompiledRunner, processTest,
-        testDirectory, arguments, useBlobs, useElf);
+      bool useElf,
+      List<String> extraLibs) {
+    return AdbPrecompilationCommand._(buildPath, processTest, testDirectory,
+        arguments, useBlobs, useElf, extraLibs);
   }
 
-  static Command adbDartk(String precompiledRunner, String processTest,
-      String script, List<String> arguments, List<String> extraLibraries) {
+  static Command adbDartk(String buildPath, String processTest, String script,
+      List<String> arguments, List<String> extraLibraries) {
     return AdbDartkCommand._(
-        precompiledRunner, processTest, script, arguments, extraLibraries);
+        buildPath, processTest, script, arguments, extraLibraries);
   }
 
   static Command jsCommandLine(
@@ -587,54 +588,72 @@
   }
 }
 
-class AdbPrecompilationCommand extends Command {
-  final String precompiledRunnerFilename;
+abstract class AdbCommand {
+  String get buildPath;
+  List<String> get extraLibraries;
+}
+
+class AdbPrecompilationCommand extends Command implements AdbCommand {
+  final String buildPath; // Path to the output directory of the build.
   final String processTestFilename;
   final String precompiledTestDirectory;
   final List<String> arguments;
   final bool useBlobs;
   final bool useElf;
+  final List<String> extraLibraries;
 
   AdbPrecompilationCommand._(
-      this.precompiledRunnerFilename,
+      this.buildPath,
       this.processTestFilename,
       this.precompiledTestDirectory,
       this.arguments,
       this.useBlobs,
       this.useElf,
+      this.extraLibraries,
       {int index = 0})
       : super._("adb_precompilation", index: index);
 
   AdbPrecompilationCommand indexedCopy(int index) => AdbPrecompilationCommand._(
-      precompiledRunnerFilename,
+      buildPath,
       processTestFilename,
       precompiledTestDirectory,
       arguments,
       useBlobs,
       useElf,
+      extraLibraries,
       index: index);
   _buildHashCode(HashCodeBuilder builder) {
     super._buildHashCode(builder);
-    builder.add(precompiledRunnerFilename);
+    builder.add(buildPath);
     builder.add(precompiledTestDirectory);
     builder.add(arguments);
     builder.add(useBlobs);
     builder.add(useElf);
+    extraLibraries.forEach(builder.add);
+  }
+
+  static bool _listEquals(List<String> x, List<String> y) {
+    if (x.length != y.length) return false;
+    for (int i = 0; i < x.length; ++i) {
+      if (x[i] != y[i]) return false;
+    }
+    return true;
   }
 
   bool _equal(AdbPrecompilationCommand other) =>
       super._equal(other) &&
-      precompiledRunnerFilename == other.precompiledRunnerFilename &&
+      buildPath == other.buildPath &&
       useBlobs == other.useBlobs &&
       useElf == other.useElf &&
       arguments == other.arguments &&
-      precompiledTestDirectory == other.precompiledTestDirectory;
+      precompiledTestDirectory == other.precompiledTestDirectory &&
+      _listEquals(extraLibraries, other.extraLibraries);
 
   String toString() => 'Steps to push precompiled runner and precompiled code '
       'to an attached device. Uses (and requires) adb.';
 }
 
-class AdbDartkCommand extends Command {
+class AdbDartkCommand extends Command implements AdbCommand {
   final String buildPath;
   final String processTestFilename;
   final String kernelFile;
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 8a5ee37..3758033 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -9,7 +9,7 @@
 import 'path.dart';
 import 'repository.dart';
 import 'runtime_configuration.dart';
-import 'test_suite.dart';
+import 'test_file.dart';
 import 'utils.dart';
 
 List<String> _replaceDartFiles(List<String> list, String replacement) {
@@ -67,16 +67,9 @@
       case Compiler.dartdevk:
         return DevCompilerConfiguration(configuration);
 
-      case Compiler.appJit:
-        return AppJitCompilerConfiguration(configuration, previewDart2: false);
-
       case Compiler.appJitk:
         return AppJitCompilerConfiguration(configuration);
 
-      case Compiler.precompiler:
-        return PrecompilerCompilerConfiguration(configuration,
-            previewDart2: false);
-
       case Compiler.dartk:
       case Compiler.dartkb:
         if (configuration.architecture == Architecture.simdbc64 ||
@@ -141,17 +134,13 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> args) {
-    return sharedOptions.toList()
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(args);
+    return [...sharedOptions, ..._configuration.sharedOptions, ...args];
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
     return [artifact.filename];
@@ -167,32 +156,26 @@
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    var args = <String>[];
-    if (_isDebug) {
-      // Temporarily disable background compilation to avoid flaky crashes
-      // (see http://dartbug.com/30016 for details).
-      args.add('--no-background-compilation');
-    }
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
-    if (_configuration.hotReload) {
-      args.add('--hot-reload-test-mode');
-    } else if (_configuration.hotReloadRollback) {
-      args.add('--hot-reload-rollback-test-mode');
-    }
-    return args
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(originalArguments)
-      ..addAll(dartOptions);
+    return [
+      if (_isDebug)
+        // Temporarily disable background compilation to avoid flaky crashes
+        // (see http://dartbug.com/30016 for details).
+        '--no-background-compilation',
+      if (_useEnableAsserts) '--enable_asserts',
+      if (_configuration.hotReload)
+        '--hot-reload-test-mode'
+      else if (_configuration.hotReloadRollback)
+        '--hot-reload-rollback-test-mode',
+      ...vmOptions,
+      ...testFile.sharedOptions,
+      ..._configuration.sharedOptions,
+      ...originalArguments,
+      ...testFile.dartOptions
+    ];
   }
 }
 
@@ -233,41 +216,39 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> args) {
-    return sharedOptions.toList()
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(vmOptions)
-      ..addAll(args);
+    return [
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...vmOptions,
+      ...args
+    ];
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    var args = <String>[];
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
-    if (_configuration.hotReload) {
-      args.add('--hot-reload-test-mode');
-    } else if (_configuration.hotReloadRollback) {
-      args.add('--hot-reload-rollback-test-mode');
-    }
     var filename = artifact.filename;
     if (runtimeConfiguration is DartkAdbRuntimeConfiguration) {
       // On Android the Dill file will be pushed to a different directory on the
       // device. Use that one instead.
       filename = "${DartkAdbRuntimeConfiguration.DeviceTestDir}/out.dill";
     }
-    return args
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(_replaceDartFiles(originalArguments, filename))
-      ..addAll(dartOptions);
+
+    return [
+      if (_useEnableAsserts) '--enable_asserts',
+      if (_configuration.hotReload)
+        '--hot-reload-test-mode'
+      else if (_configuration.hotReloadRollback)
+        '--hot-reload-rollback-test-mode',
+      ...vmOptions,
+      ...testFile.sharedOptions,
+      ..._configuration.sharedOptions,
+      ..._replaceDartFiles(originalArguments, filename),
+      ...testFile.dartOptions
+    ];
   }
 }
 
@@ -358,31 +339,24 @@
       List<String> args) {
     // The result will be passed as an input to [extractArguments]
     // (i.e. the arguments to the [PipelineCommand]).
-    return <String>[]
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(args);
+    return [
+      ...vmOptions,
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...args
+    ];
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
     CompilerConfiguration lastCompilerConfiguration =
         pipelineCommands.last.compilerConfiguration;
     return lastCompilerConfiguration.computeRuntimeArguments(
-        runtimeConfiguration,
-        info,
-        vmOptions,
-        sharedOptions,
-        dartOptions,
-        originalArguments,
-        artifact);
+        runtimeConfiguration, testFile, vmOptions, originalArguments, artifact);
   }
 }
 
@@ -445,14 +419,6 @@
   Dart2jsCompilerConfiguration(TestConfiguration configuration)
       : super('dart2js', configuration);
 
-  int get timeoutMultiplier {
-    var multiplier = 1;
-    if (_isDebug) multiplier *= 4;
-    if (_isChecked) multiplier *= 2;
-    if (_isHostChecked) multiplier *= 16;
-    return multiplier;
-  }
-
   List<String> computeCompilerArguments(
       List<String> vmOptions,
       List<String> sharedOptions,
@@ -460,19 +426,18 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> args) {
-    return <String>[]
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(dart2jsOptions)
-      ..addAll(args);
+    return [
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...dart2jsOptions,
+      ...args
+    ];
   }
 
   CommandArtifact computeCompilationArtifact(String tempDir,
       List<String> arguments, Map<String, String> environmentOverrides) {
-    var compilerArguments = arguments.toList()
-      ..addAll(_configuration.dart2jsOptions);
+    var compilerArguments = [...arguments, ..._configuration.dart2jsOptions];
 
-    var commands = <Command>[];
     // TODO(athom): input filename extraction is copied from DDC. Maybe this
     // should be passed to computeCompilationArtifact, instead?
     var inputFile = arguments.last;
@@ -483,22 +448,19 @@
     if (babel != null && babel.isNotEmpty) {
       out = out.replaceAll('.js', '.raw.js');
     }
-    commands.add(computeCompilationCommand(
-        out, compilerArguments, environmentOverrides));
-
-    if (babel != null && babel.isNotEmpty) {
-      commands.add(computeBabelCommand(out, babelOut, babel));
-    }
+    var commands = [
+      computeCompilationCommand(out, compilerArguments, environmentOverrides),
+      if (babel != null && babel.isNotEmpty)
+        computeBabelCommand(out, babelOut, babel)
+    ];
 
     return CommandArtifact(commands, babelOut, 'application/javascript');
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
     Uri sdk = _useSdk
@@ -545,13 +507,13 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> args) {
-    var result = sharedOptions.toList()
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(ddcOptions);
-    // The file being compiled is the last argument.
-    result.add(args.last);
-
-    return result;
+    return [
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...ddcOptions,
+      // The file being compiled is the last argument.
+      args.last
+    ];
   }
 
   Command _createCommand(String inputFile, String outputFile,
@@ -653,8 +615,6 @@
 
 class PrecompilerCompilerConfiguration extends CompilerConfiguration
     with VMKernelCompilerMixin {
-  final bool previewDart2;
-
   bool get _isAndroid => _configuration.system == System.android;
 
   bool get _isArm => _configuration.architecture == Architecture.arm;
@@ -663,8 +623,7 @@
 
   bool get _isAot => true;
 
-  PrecompilerCompilerConfiguration(TestConfiguration configuration,
-      {this.previewDart2 = true})
+  PrecompilerCompilerConfiguration(TestConfiguration configuration)
       : super._subclass(configuration);
 
   int get timeoutMultiplier {
@@ -714,10 +673,10 @@
 
     if (Platform.isWindows) {
       exec = 'cmd.exe';
-      args = <String>['/c', 'del', tempKernelFile(tempDir)];
+      args = ['/c', 'del', tempKernelFile(tempDir)];
     } else {
       exec = 'rm';
-      args = <String>[tempKernelFile(tempDir)];
+      args = [tempKernelFile(tempDir)];
     }
 
     return Command.compilation('remove_kernel_file', tempDir,
@@ -728,7 +687,7 @@
   Command computeDartBootstrapCommand(String tempDir, List<String> arguments,
       Map<String, String> environmentOverrides) {
     var buildDir = _configuration.buildDirectory;
-    String exec = _configuration.genSnapshotPath;
+    var exec = _configuration.genSnapshotPath;
     if (exec == null) {
       if (_isAndroid) {
         if (_isArm) {
@@ -741,27 +700,21 @@
       }
     }
 
-    final args = <String>[];
-    if (_configuration.useBlobs) {
-      args.add("--snapshot-kind=app-aot-blobs");
-      args.add("--blobs_container_filename=$tempDir/out.aotsnapshot");
-    } else if (_configuration.useElf) {
-      args.add("--snapshot-kind=app-aot-elf");
-      args.add("--elf=$tempDir/out.aotsnapshot");
-    } else {
-      args.add("--snapshot-kind=app-aot-assembly");
-      args.add("--assembly=$tempDir/out.S");
-    }
-
-    if (_isAndroid && _isArm) {
-      args.add('--no-sim-use-hardfp');
-    }
-
-    if (_configuration.isMinified) {
-      args.add('--obfuscate');
-    }
-
-    args.addAll(_replaceDartFiles(arguments, tempKernelFile(tempDir)));
+    var args = [
+      if (_configuration.useBlobs) ...[
+        "--snapshot-kind=app-aot-blobs",
+        "--blobs_container_filename=$tempDir/out.aotsnapshot"
+      ] else if (_configuration.useElf) ...[
+        "--snapshot-kind=app-aot-elf",
+        "--elf=$tempDir/out.aotsnapshot"
+      ] else ...[
+        "--snapshot-kind=app-aot-assembly",
+        "--assembly=$tempDir/out.S"
+      ],
+      if (_isAndroid && _isArm) '--no-sim-use-hardfp',
+      if (_configuration.isMinified) '--obfuscate',
+      ..._replaceDartFiles(arguments, tempKernelFile(tempDir))
+    ];
 
     return Command.compilation('precompiler', tempDir, bootstrapDependencies(),
         exec, args, environmentOverrides,
@@ -815,18 +768,18 @@
         throw "Architecture not supported: ${_configuration.architecture.name}";
     }
 
-    var exec = cc;
-    var args = <String>[];
-    if (ccFlags != null) args.add(ccFlags);
-    if (ldFlags != null) args.add(ldFlags);
-    args.add(shared);
-    args.add('-nostdlib');
-    args.add('-o');
-    args.add('$tempDir/out.aotsnapshot');
-    args.add('$tempDir/out.S');
+    var args = [
+      if (ccFlags != null) ccFlags,
+      if (ldFlags != null) ldFlags,
+      shared,
+      '-nostdlib',
+      '-o',
+      '$tempDir/out.aotsnapshot',
+      '$tempDir/out.S'
+    ];
 
-    return Command.compilation('assemble', tempDir, bootstrapDependencies(),
-        exec, args, environmentOverrides,
+    return Command.compilation('assemble', tempDir, bootstrapDependencies(), cc,
+        args, environmentOverrides,
         alwaysCompile: !_useSdk);
   }
 
@@ -839,11 +792,8 @@
   /// almost identical configurations are tested simultaneously.
   Command computeRemoveAssemblyCommand(String tempDir, List arguments,
       Map<String, String> environmentOverrides) {
-    var exec = 'rm';
-    var args = ['$tempDir/out.S'];
-
     return Command.compilation('remove_assembly', tempDir,
-        bootstrapDependencies(), exec, args, environmentOverrides,
+        bootstrapDependencies(), 'rm', ['$tempDir/out.S'], environmentOverrides,
         alwaysCompile: !_useSdk);
   }
 
@@ -863,29 +813,21 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> originalArguments) {
-    List<String> args = [];
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
-    return args
-      ..addAll(filterVmOptions(vmOptions))
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(originalArguments);
+    return [
+      if (_useEnableAsserts) '--enable_asserts',
+      ...filterVmOptions(vmOptions),
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...originalArguments
+    ];
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    var args = <String>[];
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
     var dir = artifact.filename;
     if (runtimeConfiguration is DartPrecompiledAdbRuntimeConfiguration) {
       // On android the precompiled snapshot will be pushed to a different
@@ -895,20 +837,19 @@
     originalArguments =
         _replaceDartFiles(originalArguments, "$dir/out.aotsnapshot");
 
-    return args
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(originalArguments)
-      ..addAll(dartOptions);
+    return [
+      if (_useEnableAsserts) '--enable_asserts',
+      ...vmOptions,
+      ...testFile.sharedOptions,
+      ..._configuration.sharedOptions,
+      ...originalArguments,
+      ...testFile.dartOptions
+    ];
   }
 }
 
 class AppJitCompilerConfiguration extends CompilerConfiguration {
-  final bool previewDart2;
-
-  AppJitCompilerConfiguration(TestConfiguration configuration,
-      {this.previewDart2 = true})
+  AppJitCompilerConfiguration(TestConfiguration configuration)
       : super._subclass(configuration);
 
   int get timeoutMultiplier {
@@ -929,13 +870,14 @@
 
   Command computeCompilationCommand(String tempDir, List<String> arguments,
       Map<String, String> environmentOverrides) {
-    var exec = "${_configuration.buildDirectory}/dart";
     var snapshot = "$tempDir/out.jitsnapshot";
-    var args = ["--snapshot=$snapshot", "--snapshot-kind=app-jit"];
-    args.addAll(arguments);
-
-    return Command.compilation('app_jit', tempDir, bootstrapDependencies(),
-        exec, args, environmentOverrides,
+    return Command.compilation(
+        'app_jit',
+        tempDir,
+        bootstrapDependencies(),
+        "${_configuration.buildDirectory}/dart",
+        ["--snapshot=$snapshot", "--snapshot-kind=app-jit", ...arguments],
+        environmentOverrides,
         alwaysCompile: !_useSdk);
   }
 
@@ -946,36 +888,30 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> originalArguments) {
-    var args = <String>[];
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
-    return args
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(originalArguments)
-      ..addAll(dartOptions);
+    return [
+      if (_useEnableAsserts) '--enable_asserts',
+      ...vmOptions,
+      ...sharedOptions,
+      ..._configuration.sharedOptions,
+      ...originalArguments,
+      ...dartOptions
+    ];
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    var args = <String>[];
-    if (_useEnableAsserts) {
-      args.add('--enable_asserts');
-    }
-    return args
-      ..addAll(vmOptions)
-      ..addAll(sharedOptions)
-      ..addAll(_configuration.sharedOptions)
-      ..addAll(_replaceDartFiles(originalArguments, artifact.filename))
-      ..addAll(dartOptions);
+    return [
+      if (_useEnableAsserts) '--enable_asserts',
+      ...vmOptions,
+      ...testFile.sharedOptions,
+      ..._configuration.sharedOptions,
+      ..._replaceDartFiles(originalArguments, artifact.filename),
+      ...testFile.dartOptions
+    ];
   }
 }
 
@@ -988,7 +924,7 @@
 
   String computeCompilerPath() {
     var prefix = 'sdk/bin';
-    String suffix = executableScriptSuffix;
+    var suffix = executableScriptSuffix;
     if (_isHostChecked) {
       if (_useSdk) {
         throw "--host-checked and --use-sdk cannot be used together";
@@ -1006,32 +942,30 @@
 
   CommandArtifact computeCompilationArtifact(String tempDir,
       List<String> arguments, Map<String, String> environmentOverrides) {
-    arguments = arguments.toList();
     if (!previewDart2) {
       throw ArgumentError('--no-preview-dart-2 not supported');
     }
-    if (_configuration.useAnalyzerCfe) {
-      arguments.add('--use-cfe');
-    }
-    if (_configuration.useAnalyzerFastaParser) {
-      arguments.add('--use-fasta-parser');
-    }
+
+    var args = [
+      ...arguments,
+      if (_configuration.useAnalyzerCfe) '--use-cfe',
+      if (_configuration.useAnalyzerFastaParser) '--use-fasta-parser',
+    ];
 
     // Since this is not a real compilation, no artifacts are produced.
-    return CommandArtifact([
-      Command.analysis(computeCompilerPath(), arguments, environmentOverrides)
-    ], null, null);
+    return CommandArtifact(
+        [Command.analysis(computeCompilerPath(), args, environmentOverrides)],
+        null,
+        null);
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    return <String>[];
+    return [];
   }
 }
 
@@ -1052,7 +986,6 @@
 
   CommandArtifact computeCompilationArtifact(String tempDir,
       List<String> arguments, Map<String, String> environmentOverrides) {
-    arguments = arguments.toList();
     if (!previewDart2) {
       throw ArgumentError('--no-preview-dart-2 not supported');
     }
@@ -1060,19 +993,17 @@
     // Since this is not a real compilation, no artifacts are produced.
     return CommandArtifact([
       Command.compareAnalyzerCfe(
-          computeCompilerPath(), arguments, environmentOverrides)
+          computeCompilerPath(), arguments.toList(), environmentOverrides)
     ], null, null);
   }
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    return <String>[];
+    return [];
   }
 }
 
@@ -1095,13 +1026,11 @@
 
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    return <String>[];
+    return [];
   }
 }
 
@@ -1141,44 +1070,35 @@
       kernelBinariesFolder += '/dart-sdk/lib/_internal';
     }
 
-    final vmPlatform = '$kernelBinariesFolder/vm_platform_strong.dill';
+    var vmPlatform = '$kernelBinariesFolder/vm_platform_strong.dill';
 
-    final dillFile = tempKernelFile(tempDir);
+    var dillFile = tempKernelFile(tempDir);
 
-    final args = [
+    var causalAsyncStacks = !arguments.any(noCausalAsyncStacksRegExp.hasMatch);
+
+    var args = [
       _isAot ? '--aot' : '--no-aot',
       '--platform=$vmPlatform',
       '-o',
       dillFile,
+      arguments.where((name) => name.endsWith('.dart')).single,
+      ...arguments.where((name) =>
+          name.startsWith('-D') ||
+          name.startsWith('--packages=') ||
+          name.startsWith('--enable-experiment=')),
+      '-Ddart.developer.causal_async_stacks=$causalAsyncStacks',
+      if (_useEnableAsserts ||
+          arguments.contains('--enable-asserts') ||
+          arguments.contains('--enable_asserts'))
+        '--enable-asserts',
+      if (_configuration.useKernelBytecode) ...[
+        '--gen-bytecode',
+        '--drop-ast',
+        '--bytecode-options=source-positions,local-var-info'
+      ]
     ];
 
-    final batchArgs = <String>[];
-    if (useAbiVersion != null) {
-      batchArgs.add(useAbiVersion);
-    }
-
-    args.add(arguments.where((name) => name.endsWith('.dart')).single);
-    args.addAll(arguments.where((name) =>
-        name.startsWith('-D') ||
-        name.startsWith('--packages=') ||
-        name.startsWith('--enable-experiment=')));
-
-    final bool causalAsyncStacks =
-        !arguments.any((String arg) => noCausalAsyncStacksRegExp.hasMatch(arg));
-    args.add('-Ddart.developer.causal_async_stacks=$causalAsyncStacks');
-
-    if (_useEnableAsserts ||
-        arguments.contains('--enable-asserts') ||
-        arguments.contains('--enable_asserts')) {
-      args.add('--enable-asserts');
-    }
-
-    if (_configuration.useKernelBytecode) {
-      args.add('--gen-bytecode');
-      args.add('--drop-ast');
-      args.add('--emit-bytecode-source-positions');
-      args.add('--emit-bytecode-local-var-info');
-    }
+    var batchArgs = [if (useAbiVersion != null) useAbiVersion];
 
     return Command.vmKernelCompilation(dillFile, true, bootstrapDependencies(),
         genKernel, args, environmentOverrides, batchArgs);
@@ -1230,14 +1150,15 @@
         Uri.base.resolveUri(Uri.directory(tempDir)).resolve("out.dill");
     var outputFileName = output.toFilePath();
 
-    var compilerArguments = <String>['--verify'];
-    if (_isLegacy) {
-      compilerArguments.add("--legacy-mode");
-    }
-
-    compilerArguments.addAll(
-        ["-o", outputFileName, "--platform", _platformDill.toFilePath()]);
-    compilerArguments.addAll(arguments);
+    var compilerArguments = [
+      '--verify',
+      if (_isLegacy) "--legacy-mode",
+      "-o",
+      outputFileName,
+      "--platform",
+      _platformDill.toFilePath(),
+      ...arguments
+    ];
 
     return CommandArtifact([
       Command.fasta(
@@ -1259,9 +1180,8 @@
       List<String> dart2jsOptions,
       List<String> ddcOptions,
       List<String> args) {
-    List<String> arguments = List<String>.from(sharedOptions);
-    arguments.addAll(_configuration.sharedOptions);
-    for (String argument in args) {
+    var arguments = [...sharedOptions, ..._configuration.sharedOptions];
+    for (var argument in args) {
       if (argument == "--ignore-unrecognized-flags") continue;
       arguments.add(argument);
       if (!argument.startsWith("-")) {
@@ -1277,16 +1197,14 @@
   @override
   List<String> computeRuntimeArguments(
       RuntimeConfiguration runtimeConfiguration,
-      TestInformation info,
+      TestFile testFile,
       List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> dartOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
     if (runtimeConfiguration is! NoneRuntimeConfiguration) {
       throw "--compiler=fasta only supports --runtime=none";
     }
 
-    return <String>[];
+    return [];
   }
 }
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index 987af25..ec1a0cf 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -73,7 +73,7 @@
 import "dart:io";
 
 import "path.dart";
-import "test_suite.dart";
+import "test_file.dart";
 import "utils.dart";
 
 /// Until legacy multitests are ported we need to support both /// and //#
@@ -90,7 +90,7 @@
   'checked mode compile-time error' // This is now a no-op
 ].toSet();
 
-void extractTestsFromMultitest(Path filePath, Map<String, String> tests,
+void _generateTestsFromMultitest(Path filePath, Map<String, String> tests,
     Map<String, Set<String>> outcomes) {
   var contents = File(filePath.toNativePath()).readAsStringSync();
 
@@ -162,31 +162,26 @@
   }
 }
 
-Future doMultitest(Path filePath, String outputDir, Path suiteDir,
-    CreateTest doTest, bool hotReload) {
-  void writeFile(String filepath, String content) {
-    var file = File(filepath);
-    if (file.existsSync()) {
-      var oldContent = file.readAsStringSync();
-      if (oldContent == content) {
-        // Don't write to the file if the content is the same
-        return;
-      }
-    }
-    file.writeAsStringSync(content);
-  }
-
-  // Each new test is a single String value in the Map tests.
+/// Split the given [multitest] into a series of separate tests for each
+/// section.
+///
+/// Writes the resulting tests to [outputDir] and returns a list of [TestFile]s
+/// for each of those generated tests.
+Future<List<TestFile>> splitMultitest(
+    TestFile multitest, String outputDir, Path suiteDir,
+    {bool hotReload}) async {
+  // Each key in the map tests is a multitest tag or "none", and the texts of
+  // the generated test is its value.
   var tests = <String, String>{};
   var outcomes = <String, Set<String>>{};
-  extractTestsFromMultitest(filePath, tests, outcomes);
+  _generateTestsFromMultitest(multitest.path, tests, outcomes);
 
-  var sourceDir = filePath.directoryPath;
+  var sourceDir = multitest.path.directoryPath;
   var targetDir = _createMultitestDirectory(outputDir, suiteDir, sourceDir);
   assert(targetDir != null);
 
   // Copy all the relative imports of the multitest.
-  var importsToCopy = _findAllRelativeImports(filePath);
+  var importsToCopy = _findAllRelativeImports(multitest.path);
   var futureCopies = <Future>[];
   for (var relativeImport in importsToCopy) {
     var importPath = Path(relativeImport);
@@ -200,39 +195,56 @@
     // want to copy the permissions, so we create the copy by writing.
     final source = File(sourceDir.join(importPath).toNativePath()).openRead();
     final target = File(targetDir.join(importPath).toNativePath()).openWrite();
-    futureCopies.add(source.pipe(target));
+    futureCopies.add(source.cast<List<int>>().pipe(target));
   }
 
   // Wait until all imports are copied before scheduling test cases.
-  return Future.wait(futureCopies).then((_) {
-    var baseFilename = filePath.filenameWithoutExtension;
-    for (var key in tests.keys) {
-      var multitestFilename = targetDir.append('${baseFilename}_$key.dart');
-      writeFile(multitestFilename.toNativePath(), tests[key]);
+  await Future.wait(futureCopies);
 
-      var outcome = outcomes[key];
-      var hasStaticWarning = outcome.contains('static type warning');
-      var hasRuntimeError = outcome.contains('runtime error');
-      var hasSyntaxError = outcome.contains('syntax error');
-      var hasCompileError =
-          hasSyntaxError || outcome.contains('compile-time error');
+  var baseFilename = multitest.path.filenameWithoutExtension;
 
-      if (hotReload && hasCompileError) {
-        // Running a test that expects a compilation error with hot reloading
-        // is redundant with a regular run of the test.
-        continue;
-      }
+  var testFiles = <TestFile>[];
+  for (var test in tests.keys) {
+    var sectionFilePath = targetDir.append('${baseFilename}_$test.dart');
+    _writeFile(sectionFilePath.toNativePath(), tests[test]);
 
-      doTest(multitestFilename, filePath,
-          hasSyntaxError: hasSyntaxError,
-          hasCompileError: hasCompileError,
-          hasRuntimeError: hasRuntimeError,
-          hasStaticWarning: hasStaticWarning,
-          multitestKey: key);
+    var outcome = outcomes[test];
+    var hasStaticWarning = outcome.contains('static type warning');
+    var hasRuntimeError = outcome.contains('runtime error');
+    var hasSyntaxError = outcome.contains('syntax error');
+    var hasCompileError =
+        hasSyntaxError || outcome.contains('compile-time error');
+
+    if (hotReload && hasCompileError) {
+      // Running a test that expects a compilation error with hot reloading
+      // is redundant with a regular run of the test.
+      continue;
     }
 
-    return null;
-  });
+    // Create a [TestFile] for each split out section test.
+    testFiles.add(multitest.split(sectionFilePath, test, tests[test],
+        hasSyntaxError: hasSyntaxError,
+        hasCompileError: hasCompileError,
+        hasRuntimeError: hasRuntimeError,
+        hasStaticWarning: hasStaticWarning));
+  }
+
+  return testFiles;
+}
+
+/// Writes [content] to [filePath] unless there is already a file at that path
+/// with the same content.
+void _writeFile(String filePath, String content) {
+  var file = File(filePath);
+
+  // Don't overwrite the file if the contents are the same. This way build
+  // systems don't think it has been modified.
+  if (file.existsSync()) {
+    var oldContent = file.readAsStringSync();
+    if (oldContent == content) return;
+  }
+
+  file.writeAsStringSync(content);
 }
 
 /// A multitest annotation in the special `//#` comment.
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index 0d5c77c..9df9cb5 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -19,6 +19,7 @@
 import 'output_log.dart';
 import 'runtime_configuration.dart';
 import 'test_case.dart';
+import 'test_file.dart';
 import 'test_progress.dart';
 import 'test_suite.dart';
 import 'utils.dart';
@@ -236,7 +237,7 @@
     // Cache information about test cases per test suite. For multiple
     // configurations there is no need to repeatedly search the file
     // system, generate tests, and search test files for options.
-    var testCache = <String, List<TestInformation>>{};
+    var testCache = <String, List<TestFile>>{};
 
     var iterator = testSuites.iterator;
     void enqueueNextSuite() {
@@ -628,9 +629,23 @@
     }
   }
 
+  List<_StepFunction> _pushLibraries(AdbCommand command, AdbDevice device,
+      String deviceDir, String deviceTestDir) {
+    final List<_StepFunction> steps = [];
+    for (var lib in command.extraLibraries) {
+      var libName = "lib${lib}.so";
+      steps.add(() => device.runAdbCommand([
+            'push',
+            '${command.buildPath}/$libName',
+            '$deviceTestDir/$libName'
+          ]));
+    }
+    return steps;
+  }
+
   Future<CommandOutput> _runAdbPrecompilationCommand(
       AdbDevice device, AdbPrecompilationCommand command, int timeout) async {
-    var runner = command.precompiledRunnerFilename;
+    final String buildPath = command.buildPath;
     var processTest = command.processTestFilename;
     var testdir = command.precompiledTestDirectory;
     var arguments = command.arguments;
@@ -651,8 +666,8 @@
 
     steps.add(() => device.runAdbShellCommand(['rm', '-Rf', deviceTestDir]));
     steps.add(() => device.runAdbShellCommand(['mkdir', '-p', deviceTestDir]));
-    steps.add(() =>
-        device.pushCachedData(runner, '$devicedir/dart_precompiled_runtime'));
+    steps.add(() => device.pushCachedData('$buildPath/dart_precompiled_runtime',
+        '$devicedir/dart_precompiled_runtime'));
     steps.add(
         () => device.pushCachedData(processTest, '$devicedir/process_test'));
     steps.add(() => device.runAdbShellCommand([
@@ -661,6 +676,8 @@
           '$devicedir/dart_precompiled_runtime $devicedir/process_test'
         ]));
 
+    steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
+
     for (var file in files) {
       steps.add(() => device
           .runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file']));
@@ -668,7 +685,8 @@
 
     steps.add(() => device.runAdbShellCommand(
         [
-          '$devicedir/dart_precompiled_runtime',
+          'export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$deviceTestDir;'
+              '$devicedir/dart_precompiled_runtime',
         ]..addAll(arguments),
         timeout: timeoutDuration));
 
@@ -722,11 +740,7 @@
     steps.add(() => device
         .runAdbCommand(['push', hostKernelFile, '$deviceTestDir/out.dill']));
 
-    for (var lib in command.extraLibraries) {
-      var libName = "lib${lib}.so";
-      steps.add(() => device.runAdbCommand(
-          ['push', '${buildPath}/$libName', '$deviceTestDir/$libName']));
-    }
+    steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
 
     steps.add(() => device.runAdbShellCommand(
         [
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 16690f8..fa26f2d 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -369,11 +369,10 @@
       throw "dart_precompiled cannot run files of type '$type'.";
     }
 
-    String precompiledRunner = dartPrecompiledBinaryFileName;
     String processTest = processTestBinaryFileName;
     return [
       Command.adbPrecompiled(
-          precompiledRunner, processTest, script, arguments, useBlobs, useElf)
+          buildDir, processTest, script, arguments, useBlobs, useElf, extraLibs)
     ];
   }
 }
diff --git a/pkg/test_runner/lib/src/test_case.dart b/pkg/test_runner/lib/src/test_case.dart
index 6d1aa4e..af02960 100644
--- a/pkg/test_runner/lib/src/test_case.dart
+++ b/pkg/test_runner/lib/src/test_case.dart
@@ -15,7 +15,7 @@
 import 'output_log.dart';
 import 'process_queue.dart';
 import 'repository.dart';
-import 'test_suite.dart';
+import 'test_file.dart';
 import 'utils.dart';
 
 const _slowTimeoutMultiplier = 4;
@@ -71,27 +71,27 @@
 
   TestCase(this.displayName, this.commands, this.configuration,
       this.expectedOutcomes,
-      {TestInformation info}) {
+      {TestFile testFile}) {
     // A test case should do something.
     assert(commands.isNotEmpty);
 
-    if (info != null) {
-      _setExpectations(info);
-      hash = (info?.originTestPath?.relativeTo(Repository.dir)?.toString())
+    if (testFile != null) {
+      _setExpectations(testFile);
+      hash = (testFile.originPath?.relativeTo(Repository.dir)?.toString())
           .hashCode;
     }
   }
 
-  void _setExpectations(TestInformation info) {
+  void _setExpectations(TestFile testFile) {
     // We don't want to keep the entire (large) TestInformation structure,
     // so we copy the needed bools into flags set in a single integer.
-    if (info.hasRuntimeError) _expectations |= _hasRuntimeError;
-    if (info.hasSyntaxError) _expectations |= _hasSyntaxError;
-    if (info.hasCrash) _expectations |= _hasCrash;
-    if (info.hasCompileError || info.hasSyntaxError) {
+    if (testFile.hasRuntimeError) _expectations |= _hasRuntimeError;
+    if (testFile.hasSyntaxError) _expectations |= _hasSyntaxError;
+    if (testFile.hasCrash) _expectations |= _hasCrash;
+    if (testFile.hasCompileError || testFile.hasSyntaxError) {
       _expectations |= _hasCompileError;
     }
-    if (info.hasStaticWarning) _expectations |= _hasStaticWarning;
+    if (testFile.hasStaticWarning) _expectations |= _hasStaticWarning;
   }
 
   TestCase indexedCopy(int index) {
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
new file mode 100644
index 0000000..4279b8e
--- /dev/null
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -0,0 +1,675 @@
+// Copyright (c) 2019, 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 'dart:io';
+
+import 'path.dart';
+
+final _multiHtmlTestGroupRegExp = RegExp(r"\s*[^/]\s*group\('[^,']*");
+final _multiHtmlTestRegExp = RegExp(r"useHtmlIndividualConfiguration\(\)");
+
+// TODO(rnystrom): Remove support for "///" once tests have been migrated.
+// https://dart-review.googlesource.com/c/sdk/+/106201
+// https://github.com/dart-lang/co19/issues/391
+/// Require at least one non-space character before '//[/#]'.
+final _multitestRegExp = RegExp(r"\S *//[#/] \w+:(.*)");
+
+final _vmOptionsRegExp = RegExp(r"// VMOptions=(.*)");
+final _environmentRegExp = RegExp(r"// Environment=(.*)");
+final _packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
+final _packagesRegExp = RegExp(r"// Packages=(.*)");
+
+List<String> _splitWords(String s) =>
+    s.split(' ').where((e) => e != '').toList();
+
+List<String> _parseOption(String filePath, String contents, String name,
+    {bool allowMultiple = false}) {
+  var matches = RegExp('// $name=(.*)').allMatches(contents);
+  if (!allowMultiple && matches.length > 1) {
+    throw Exception('More than one "// $name=" line in test $filePath');
+  }
+
+  var options = <String>[];
+  for (var match in matches) {
+    options.addAll(_splitWords(match[1]));
+  }
+
+  return options;
+}
+
+/// A single error expectation comment from a [TestFile].
+///
+/// If a test contains any of these, then it is a "static error test" and
+/// exists to validate that a conforming front end produces the expected
+/// compile-time errors.
+///
+/// In order to make it easier to incrementally add error tests before a
+/// feature is fully implemented or specified, an error expectation can be in
+/// an "unspecified" state. That means all that's known is the line number. All
+/// other fields will be `null`. In that state, a front end is expected to
+/// report *some* error on that line, but it can be any location, error code, or
+/// message.
+///
+/// Aside from location, there are two interesting attributes of an error that
+/// a test can verify: its error code and the error message. Currently, for
+/// analyzer we only care about the error code. The CFE does not report an
+/// error code and only reports a message. So this class takes advantage of
+/// that by allowing you to set expectations for analyzer and CFE independently
+/// by assuming the [code] field is only used for the former and the [message]
+/// for the latter.
+class ErrorExpectation {
+  /// The one-based line number of the beginning of the error's location.
+  final int line;
+
+  /// The one-based column number of the beginning of the error's location.
+  final int column;
+
+  /// The number of characters in the error location.
+  final int length;
+
+  /// The expected analyzer error code for the error or `null` if this error
+  /// isn't expected to be reported by analyzer.
+  final String code;
+
+  /// The expected CFE error message or `null` if this error isn't expected to
+  /// be reported by the CFE.
+  final String message;
+
+  ErrorExpectation(
+      {this.line, this.column, this.length, this.code, this.message});
+
+  String toString() {
+    var result = "Error at line $line, column $column, length $length";
+    if (code != null) result += "\n$code";
+    if (message != null) result += "\n$message";
+    return result;
+  }
+}
+
+abstract class _TestFileBase {
+  /// The test suite directory containing this test.
+  final Path _suiteDirectory;
+
+  /// The full path to the test file.
+  final Path path;
+
+  /// The path to the original multitest file this test was generated from.
+  ///
+  /// If this test was not generated from a multitest, just returns [path].
+  Path get originPath;
+
+  /// The parsed error expectation markers in this test, if it is a static
+  /// error test.
+  final List<ErrorExpectation> expectedErrors;
+
+  /// The name of the multitest section this file corresponds to if it was
+  /// generated from a multitest. Otherwise, returns an empty string.
+  String get multitestKey;
+
+  _TestFileBase(this._suiteDirectory, this.path, this.expectedErrors) {
+    assert(path.isAbsolute);
+  }
+
+  /// The logical name of the test.
+  ///
+  /// This is its path relative to the test suite directory containing it,
+  /// minus any file extension. If this test was split from a multitest,
+  /// it contains the multitest key.
+  String get name {
+    var testNamePath = originPath.relativeTo(_suiteDirectory);
+    var directory = testNamePath.directoryPath;
+    var filenameWithoutExt = testNamePath.filenameWithoutExtension;
+
+    String concat(String base, String part) {
+      if (base == "") return part;
+      if (part == "") return base;
+      return "$base/$part";
+    }
+
+    var result = "$directory";
+    result = concat(result, "$filenameWithoutExt");
+    result = concat(result, multitestKey);
+    return result;
+  }
+}
+
+/// Represents a single ".dart" file used as a test and the parsed metadata it
+/// contains.
+///
+/// Special options for individual tests are currently specified in various
+/// ways: with comments directly in test files, by using certain imports, or
+/// by creating additional files in the test directories.
+///
+/// Here is a list of options that are used by 'test.dart' today:
+///
+/// *   Flags can be passed to the VM process that runs the test by adding a
+///     comment to the test file:
+///
+///         // VMOptions=--flag1 --flag2
+///
+/// *   Flags can be passed to dart2js, vm or dartdevc by adding a comment to
+///     the test file:
+///
+///         // SharedOptions=--flag1 --flag2
+///
+/// *   Flags can be passed to dart2js by adding a comment to the test file:
+///
+///         // dart2jsOptions=--flag1 --flag2
+///
+/// *   Flags can be passed to the dart script that contains the test also
+///     using comments, as follows:
+///
+///         // DartOptions=--flag1 --flag2
+///
+/// *   Extra environment variables can be passed to the process that runs
+///     the test by adding comment(s) to the test file:
+///
+///         // Environment=ENV_VAR1=foo bar
+///         // Environment=ENV_VAR2=bazz
+///
+/// *   Most tests are not web tests, but can (and will be) wrapped within an
+///     HTML file and another script file to test them also on browser
+///     environments (e.g. language and corelib tests are run this way). We
+///     deduce that if a file with the same name as the test, but ending in
+///     ".html" instead of ".dart" exists, the test was intended to be a web
+///     test and no wrapping is necessary.
+///
+/// *   This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be in
+///     the system linker path of the VM.
+///
+///         // SharedObjects=foobar
+///
+/// *   'test.dart' assumes tests fail if the process returns a non-zero exit
+///     code (in the case of web tests, we check for PASS/FAIL indications in
+///     the test output).
+class TestFile extends _TestFileBase {
+  /// Read the test file from the given [filePath].
+  factory TestFile.read(Path suiteDirectory, String filePath) => TestFile.parse(
+      suiteDirectory, filePath, File(filePath).readAsStringSync());
+
+  /// Parse a test file with [contents].
+  factory TestFile.parse(
+      Path suiteDirectory, String filePath, String contents) {
+    if (filePath.endsWith('.dill')) {
+      return TestFile._(suiteDirectory, Path(filePath), [],
+          vmOptions: [[]],
+          sharedOptions: [],
+          dart2jsOptions: [],
+          ddcOptions: [],
+          dartOptions: [],
+          packageRoot: null,
+          packages: null,
+          hasSyntaxError: false,
+          hasCompileError: false,
+          hasRuntimeError: false,
+          hasStaticWarning: false,
+          hasCrash: false,
+          isMultitest: false,
+          isMultiHtmlTest: false,
+          subtestNames: [],
+          sharedObjects: [],
+          otherResources: []);
+    }
+
+    // VM options.
+    var vmOptions = <List<String>>[];
+    var matches = _vmOptionsRegExp.allMatches(contents);
+    for (var match in matches) {
+      vmOptions.add(_splitWords(match[1]));
+    }
+    if (vmOptions.isEmpty) vmOptions.add(<String>[]);
+
+    // Other options.
+    var dartOptions = _parseOption(filePath, contents, 'DartOptions');
+    var sharedOptions = _parseOption(filePath, contents, 'SharedOptions');
+    var dart2jsOptions = _parseOption(filePath, contents, 'dart2jsOptions');
+    var ddcOptions = _parseOption(filePath, contents, 'dartdevcOptions');
+    var otherResources =
+        _parseOption(filePath, contents, 'OtherResources', allowMultiple: true);
+    var sharedObjects =
+        _parseOption(filePath, contents, 'SharedObjects', allowMultiple: true);
+
+    // Environment.
+    Map<String, String> environment;
+    matches = _environmentRegExp.allMatches(contents);
+    for (var match in matches) {
+      var envDef = match[1];
+      var pos = envDef.indexOf('=');
+      var name = (pos < 0) ? envDef : envDef.substring(0, pos);
+      var value = (pos < 0) ? '' : envDef.substring(pos + 1);
+      environment ??= {};
+      environment[name] = value;
+    }
+
+    // Packages.
+    String packageRoot;
+    String packages;
+    matches = _packageRootRegExp.allMatches(contents);
+    for (var match in matches) {
+      if (packageRoot != null || packages != null) {
+        throw Exception('More than one "// Package... line in test $filePath');
+      }
+      packageRoot = match[1];
+      if (packageRoot != 'none') {
+        // PackageRoot=none means that no packages or package-root option
+        // should be given. Any other value overrides package-root and
+        // removes any packages option.  Don't use with // Packages=.
+        packageRoot = Uri.file(filePath)
+            .resolveUri(Uri.directory(packageRoot))
+            .toFilePath();
+      }
+    }
+
+    matches = _packagesRegExp.allMatches(contents);
+    for (var match in matches) {
+      if (packages != null || packageRoot != null) {
+        throw Exception('More than one "// Package..." line in test $filePath');
+      }
+      packages = match[1];
+      if (packages != 'none') {
+        // Packages=none means that no packages or package-root option
+        // should be given. Any other value overrides packages and removes
+        // any package-root option. Don't use with // PackageRoot=.
+        packages =
+            Uri.file(filePath).resolveUri(Uri.file(packages)).toFilePath();
+      }
+    }
+
+    var isMultitest = _multitestRegExp.hasMatch(contents);
+    var isMultiHtmlTest = _multiHtmlTestRegExp.hasMatch(contents);
+
+    var subtestNames = <String>[];
+    if (isMultiHtmlTest) {
+      for (var match in _multiHtmlTestGroupRegExp.allMatches(contents)) {
+        var fullMatch = match.group(0);
+        subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
+      }
+    }
+
+    // TODO(rnystrom): During the migration of the existing tests to Dart 2.0,
+    // we have a number of tests that used to both generate static type warnings
+    // and also validate some runtime behavior in an implementation that
+    // ignores those warnings. Those warnings are now errors. The test code
+    // validates the runtime behavior can and should be removed, but the code
+    // that causes the static warning should still be preserved since that is
+    // part of our coverage of the static type system.
+    //
+    // The test needs to indicate that it should have a static error. We could
+    // put that in the status file, but that makes it confusing because it
+    // would look like implementations that *don't* report the error are more
+    // correct. Eventually, we want to have a notation similar to what front_end
+    // is using for the inference tests where we can put a comment inside the
+    // test that says "This specific static error should be reported right by
+    // this token."
+    //
+    // That system isn't in place yet, so we do a crude approximation here in
+    // test.dart. If a test contains `/*@compile-error=`, which matches the
+    // beginning of the tag syntax that front_end uses, then we assume that
+    // this test must have a static error somewhere in it.
+    //
+    // Redo this code once we have a more precise test framework for detecting
+    // and locating these errors.
+    var hasSyntaxError = contents.contains("@syntax-error");
+    var hasCompileError = hasSyntaxError || contents.contains("@compile-error");
+
+    List<ErrorExpectation> errorExpectations;
+    try {
+      errorExpectations = _ErrorExpectationParser(contents).parse();
+    } on FormatException catch (error) {
+      throw FormatException(
+          "Invalid error expectation syntax in $filePath:\n$error");
+    }
+
+    return TestFile._(suiteDirectory, Path(filePath), errorExpectations,
+        packageRoot: packageRoot,
+        packages: packages,
+        environment: environment,
+        isMultitest: isMultitest,
+        isMultiHtmlTest: isMultiHtmlTest,
+        hasSyntaxError: hasSyntaxError,
+        hasCompileError: hasCompileError,
+        hasRuntimeError: contents.contains("@runtime-error"),
+        hasStaticWarning: contents.contains("@static-warning"),
+        hasCrash: false,
+        subtestNames: subtestNames,
+        sharedOptions: sharedOptions,
+        dartOptions: dartOptions,
+        dart2jsOptions: dart2jsOptions,
+        ddcOptions: ddcOptions,
+        vmOptions: vmOptions,
+        sharedObjects: sharedObjects,
+        otherResources: otherResources);
+  }
+
+  /// A special fake test file for representing a VM unit test written in C++.
+  TestFile.vmUnitTest(
+      {this.hasSyntaxError,
+      this.hasCompileError,
+      this.hasRuntimeError,
+      this.hasStaticWarning,
+      this.hasCrash})
+      : packageRoot = null,
+        packages = null,
+        environment = null,
+        isMultitest = false,
+        isMultiHtmlTest = false,
+        subtestNames = [],
+        sharedOptions = [],
+        dartOptions = [],
+        dart2jsOptions = [],
+        ddcOptions = [],
+        vmOptions = [],
+        sharedObjects = [],
+        otherResources = [],
+        super(null, null, []);
+
+  TestFile._(
+      Path suiteDirectory, Path path, List<ErrorExpectation> expectedErrors,
+      {this.packageRoot,
+      this.packages,
+      this.environment,
+      this.isMultitest,
+      this.isMultiHtmlTest,
+      this.hasSyntaxError,
+      this.hasCompileError,
+      this.hasRuntimeError,
+      this.hasStaticWarning,
+      this.hasCrash,
+      this.subtestNames,
+      this.sharedOptions,
+      this.dartOptions,
+      this.dart2jsOptions,
+      this.ddcOptions,
+      this.vmOptions,
+      this.sharedObjects,
+      this.otherResources})
+      : super(suiteDirectory, path, expectedErrors) {
+    assert(!isMultitest || dartOptions.isEmpty);
+  }
+
+  Path get originPath => path;
+
+  String get multitestKey => "";
+
+  final String packageRoot;
+  final String packages;
+
+  final Map<String, String> environment;
+
+  final bool isMultitest;
+  final bool isMultiHtmlTest;
+  final bool hasSyntaxError;
+  final bool hasCompileError;
+  final bool hasRuntimeError;
+  final bool hasStaticWarning;
+  final bool hasCrash;
+
+  final List<String> subtestNames;
+  final List<String> sharedOptions;
+  final List<String> dartOptions;
+  final List<String> dart2jsOptions;
+  final List<String> ddcOptions;
+  final List<List<String>> vmOptions;
+  final List<String> sharedObjects;
+  final List<String> otherResources;
+
+  /// Derive a multitest test section file from this multitest file with the
+  /// given [multitestKey] and expectations.
+  TestFile split(Path path, String multitestKey, String contents,
+          {bool hasCompileError,
+          bool hasRuntimeError,
+          bool hasStaticWarning,
+          bool hasSyntaxError}) =>
+      _MultitestFile(
+          this, path, multitestKey, _ErrorExpectationParser(contents).parse(),
+          hasCompileError: hasCompileError ?? false,
+          hasRuntimeError: hasRuntimeError ?? false,
+          hasStaticWarning: hasStaticWarning ?? false,
+          hasSyntaxError: hasSyntaxError ?? false);
+
+  String toString() => """TestFile(
+  packageRoot: $packageRoot
+  packages: $packages
+  environment: $environment
+  isMultitest: $isMultitest
+  isMultiHtmlTest: $isMultiHtmlTest
+  hasSyntaxError: $hasSyntaxError
+  hasCompileError: $hasCompileError
+  hasRuntimeError: $hasRuntimeError
+  hasStaticWarning: $hasStaticWarning
+  hasCrash: $hasCrash
+  subtestNames: $subtestNames
+  sharedOptions: $sharedOptions
+  dartOptions: $dartOptions
+  dart2jsOptions: $dart2jsOptions
+  ddcOptions: $ddcOptions
+  vmOptions: $vmOptions
+  sharedObjects: $sharedObjects
+  otherResources: $otherResources
+)""";
+}
+
+/// A [TestFile] for a single section file derived from a multitest.
+///
+/// This inherits most properties from the original test file, but overrides
+/// the error flags based on the multitest section's expectation.
+class _MultitestFile extends _TestFileBase implements TestFile {
+  /// The authored test file that was split to generate this multitest.
+  final TestFile _origin;
+
+  final String multitestKey;
+
+  final bool hasCompileError;
+  final bool hasRuntimeError;
+  final bool hasStaticWarning;
+  final bool hasSyntaxError;
+  bool get hasCrash => _origin.hasCrash;
+
+  _MultitestFile(this._origin, Path path, this.multitestKey,
+      List<ErrorExpectation> expectedErrors,
+      {this.hasCompileError,
+      this.hasRuntimeError,
+      this.hasStaticWarning,
+      this.hasSyntaxError})
+      : super(_origin._suiteDirectory, path, expectedErrors);
+
+  Path get originPath => _origin.path;
+
+  String get packageRoot => _origin.packageRoot;
+  String get packages => _origin.packages;
+
+  List<String> get dart2jsOptions => _origin.dart2jsOptions;
+  List<String> get dartOptions => _origin.dartOptions;
+  List<String> get ddcOptions => _origin.ddcOptions;
+  Map<String, String> get environment => _origin.environment;
+
+  bool get isMultiHtmlTest => _origin.isMultiHtmlTest;
+  bool get isMultitest => _origin.isMultitest;
+
+  List<String> get otherResources => _origin.otherResources;
+  List<String> get sharedObjects => _origin.sharedObjects;
+  List<String> get sharedOptions => _origin.sharedOptions;
+  List<String> get subtestNames => _origin.subtestNames;
+  List<List<String>> get vmOptions => _origin.vmOptions;
+
+  TestFile split(Path path, String multitestKey, String contents,
+          {bool hasCompileError,
+          bool hasRuntimeError,
+          bool hasStaticWarning,
+          bool hasSyntaxError}) =>
+      throw UnsupportedError(
+          "Can't derive a test from one already derived from a multitest.");
+}
+
+class _ErrorExpectationParser {
+  /// Marks the location of an expected error, like so:
+  ///
+  ///     int i = "s";
+  ///     //      ^^^
+  ///
+  /// We look for a line that starts with a line comment followed by spaces and
+  /// carets.
+  static final _caretLocationRegExp = RegExp(r"^\s*//\s*(\^+)\s*$");
+
+  /// Matches an explicit error location, like:
+  ///
+  ///     // [error line 1, column 17, length 3]
+  static final _explicitLocationRegExp =
+      RegExp(r"^\s*//\s*\[\s*error line\s+(\d+)\s*,\s*column\s+(\d+)\s*,\s*"
+          r"length\s+(\d+)\s*\]\s*$");
+
+  /// An analyzer error code is a dotted identifier.
+  static final _unspecifiedErrorRegExp =
+      RegExp(r"^\s*// \[unspecified error\]");
+
+  /// An analyzer error expectation starts with "// [analyzer]".
+  static final _analyzerErrorRegExp = RegExp(r"^\s*// \[analyzer\]\s*(.*)");
+
+  /// An analyzer error code is a dotted identifier.
+  static final _errorCodeRegExp = RegExp(r"^\w+\.\w+$");
+
+  /// The first line of a CFE error expectation starts with "// [cfe]".
+  static final _cfeErrorRegExp = RegExp(r"^\s*// \[cfe\]\s*(.*)");
+
+  /// Any line-comment-only lines after the first line of a CFE error message are
+  /// part of it.
+  static final _errorMessageRestRegExp = RegExp(r"^\s*//\s*(.*)");
+
+  /// Matches the multitest marker and yields the preceding content.
+  final _stripMultitestRegExp = RegExp(r"(.*)//#");
+
+  final List<String> _lines;
+  final List<ErrorExpectation> _errors = [];
+  int _currentLine = 0;
+
+  /// One-based index of the last line that wasn't part of an error expectation.
+  int _lastRealLine = -1;
+
+  _ErrorExpectationParser(String source) : _lines = source.split("\n");
+
+  List<ErrorExpectation> parse() {
+    while (!_isAtEnd) {
+      var sourceLine = _peek(0);
+
+      var match = _caretLocationRegExp.firstMatch(sourceLine);
+      if (match != null) {
+        if (_lastRealLine == -1) {
+          _fail("An error expectation must follow some code.");
+        }
+
+        _parseErrorDetails(
+            line: _lastRealLine,
+            column: sourceLine.indexOf("^") + 1,
+            length: match.group(1).length);
+        _advance();
+        continue;
+      }
+
+      match = _explicitLocationRegExp.firstMatch(sourceLine);
+      if (match != null) {
+        _parseErrorDetails(
+            line: int.parse(match.group(1)),
+            column: int.parse(match.group(2)),
+            length: int.parse(match.group(3)));
+        _advance();
+        continue;
+      }
+
+      match = _unspecifiedErrorRegExp.firstMatch(sourceLine);
+      if (match != null) {
+        _errors.add(ErrorExpectation(line: _lastRealLine));
+        _advance();
+        continue;
+      }
+
+      _lastRealLine = _currentLine + 1;
+      _advance();
+    }
+
+    return _errors;
+  }
+
+  /// Finishes parsing an error expectation after parsing the location.
+  void _parseErrorDetails({int line, int column, int length}) {
+    String code;
+    String message;
+
+    // Look for an error code line.
+    if (!_isAtEnd) {
+      var match = _analyzerErrorRegExp.firstMatch(_peek(1));
+      if (match != null) {
+        code = match.group(1);
+
+        if (!_errorCodeRegExp.hasMatch(code)) {
+          _fail("An analyzer error expectation should be a dotted identifier.");
+        }
+
+        _advance();
+      }
+    }
+
+    // Look for an error message.
+    if (!_isAtEnd) {
+      var match = _cfeErrorRegExp.firstMatch(_peek(1));
+      if (match != null) {
+        message = match.group(1);
+        _advance();
+
+        // Consume as many additional error message lines as we find.
+        while (!_isAtEnd) {
+          var nextLine = _peek(1);
+
+          // A location line shouldn't be treated as a message.
+          if (_caretLocationRegExp.hasMatch(nextLine)) break;
+          if (_explicitLocationRegExp.hasMatch(nextLine)) break;
+
+          // Don't let users arbitrarily order the error code and message.
+          if (_analyzerErrorRegExp.hasMatch(nextLine)) {
+            _fail("An analyzer expectation must come before a CFE "
+                "expectation.");
+          }
+
+          var messageMatch = _errorMessageRestRegExp.firstMatch(nextLine);
+          if (messageMatch == null) break;
+
+          message += "\n" + messageMatch.group(1);
+          _advance();
+        }
+      }
+    }
+
+    if (code == null && message == null) {
+      _fail("An error expectation must specify at least an analyzer or CFE "
+          "error.");
+    }
+
+    _errors.add(ErrorExpectation(
+        line: line,
+        column: column,
+        length: length,
+        code: code,
+        message: message));
+  }
+
+  bool get _isAtEnd => _currentLine >= _lines.length;
+
+  void _advance() {
+    _currentLine++;
+  }
+
+  String _peek(int offset) {
+    var line = _lines[_currentLine + offset];
+
+    // Strip off any multitest marker.
+    var multitestMatch = _stripMultitestRegExp.firstMatch(line);
+    if (multitestMatch != null) {
+      line = multitestMatch.group(1).trimRight();
+    }
+
+    return line;
+  }
+
+  void _fail(String message) {
+    throw FormatException("Test error on line ${_currentLine + 1}: $message");
+  }
+}
diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart
index 1204a81..618a023 100644
--- a/pkg/test_runner/lib/src/test_suite.dart
+++ b/pkg/test_runner/lib/src/test_suite.dart
@@ -26,15 +26,10 @@
 import 'summary_report.dart';
 import 'test_case.dart';
 import 'test_configurations.dart';
+import 'test_file.dart';
 import 'testing_servers.dart';
 import 'utils.dart';
 
-RegExp _multiHtmlTestGroupRegExp = RegExp(r"\s*[^/]\s*group\('[^,']*");
-RegExp _multiHtmlTestRegExp = RegExp(r"useHtmlIndividualConfiguration\(\)");
-
-/// Require at least one non-space character before '//[/#]'.
-RegExp _multiTestRegExp = RegExp(r"\S *//[#/] \w+:(.*)");
-
 typedef TestCaseEvent = void Function(TestCase testCase);
 
 /// A simple function that tests [arg] and returns `true` or `false`.
@@ -151,20 +146,20 @@
   /// cache information about the test suite, so that directories do not need
   /// to be listed each time.
   Future forEachTest(
-      TestCaseEvent onTest, Map<String, List<TestInformation>> testCache,
+      TestCaseEvent onTest, Map<String, List<TestFile>> testCache,
       [VoidFunction onDone]);
 
-  /// This function will be called for every TestCase of this test suite.
-  /// It will:
-  ///  - handle sharding
-  ///  - update SummaryReport
-  ///  - handle SKIP/SKIP_BY_DESIGN markers
-  ///  - test if the selector matches
-  /// and will enqueue the test (if necessary).
-  void enqueueNewTestCase(
-      String testName, List<Command> commands, Set<Expectation> expectations,
-      [TestInformation info]) {
-    var displayName = '$suiteName/$testName';
+  /// This function is called for every TestCase of this test suite. It:
+  ///
+  /// - Handles sharding.
+  /// - Updates [SummaryReport].
+  /// - Handle skip markers.
+  /// - Tests if the selector matches.
+  ///
+  /// and enqueue the test if necessary.
+  void enqueueNewTestCase(TestFile testFile, String fullName,
+      List<Command> commands, Set<Expectation> expectations) {
+    var displayName = '$suiteName/$fullName';
 
     // If the test is not going to be run at all, then a RuntimeError,
     // MissingRuntimeError or Timeout will never occur.
@@ -178,9 +173,9 @@
       if (expectations.isEmpty) expectations.add(Expectation.pass);
     }
 
-    var negative = info != null ? isNegative(info) : false;
+    var negative = testFile != null ? isNegative(testFile) : false;
     var testCase = TestCase(displayName, commands, configuration, expectations,
-        info: info);
+        testFile: testFile);
     if (negative &&
         configuration.runtimeConfiguration.shouldSkipNegativeTests) {
       return;
@@ -213,12 +208,12 @@
       }
     }
 
-    // Update Summary report
+    // Update Summary report.
     if (configuration.printReport) {
       summaryReport.add(testCase);
     }
 
-    // Handle skipped tests
+    // Handle skipped tests.
     if (expectations.contains(Expectation.skip) ||
         expectations.contains(Expectation.skipByDesign) ||
         expectations.contains(Expectation.skipSlow)) {
@@ -236,9 +231,9 @@
     doTest(testCase);
   }
 
-  bool isNegative(TestInformation info) =>
-      info.hasCompileError ||
-      info.hasRuntimeError && configuration.runtime != Runtime.none;
+  bool isNegative(TestFile testFile) =>
+      testFile.hasCompileError ||
+      testFile.hasRuntimeError && configuration.runtime != Runtime.none;
 
   String createGeneratedTestDirectoryHelper(
       String name, String dirname, Path testPath) {
@@ -258,24 +253,6 @@
         .replaceAll('\\', '/');
   }
 
-  String buildTestCaseDisplayName(Path suiteDir, Path originTestPath,
-      {String multitestName = ""}) {
-    Path testNamePath = originTestPath.relativeTo(suiteDir);
-    var directory = testNamePath.directoryPath;
-    var filenameWithoutExt = testNamePath.filenameWithoutExtension;
-
-    String concat(String base, String part) {
-      if (base == "") return part;
-      if (part == "") return base;
-      return "$base/$part";
-    }
-
-    var testName = "$directory";
-    testName = concat(testName, "$filenameWithoutExt");
-    testName = concat(testName, multitestName);
-    return testName;
-  }
-
   /// Create a directories for generated assets (tests, html files,
   /// pubspec checkouts ...).
   String createOutputDirectory(Path testPath) {
@@ -364,11 +341,11 @@
   }
 
   void _addTest(ExpectationSet testExpectations, VMUnitTest test) {
-    final fullName = 'cc/${test.name}';
+    var fullName = 'cc/${test.name}';
     var expectations = testExpectations.expectations(fullName);
 
     // Get the expectation from the cc/ test itself.
-    final Expectation testExpectation = Expectation.find(test.expectation);
+    var testExpectation = Expectation.find(test.expectation);
 
     // Update the legacy status-file based expectations to include
     // [testExpectation].
@@ -378,26 +355,22 @@
     }
 
     // Update the new workflow based expectations to include [testExpectation].
-    final Path filePath = null;
-    final Path originTestPath = null;
-    final hasSyntaxError = false;
-    final hasStaticWarning = false;
-    final hasCompileTimeError = testExpectation == Expectation.compileTimeError;
-    final hasRuntimeError = testExpectation == Expectation.runtimeError;
-    final hasCrash = testExpectation == Expectation.crash;
-    final optionsFromFile = const <String, dynamic>{};
-    final testInfo = TestInformation(filePath, originTestPath, optionsFromFile,
-        hasSyntaxError, hasCompileTimeError, hasRuntimeError, hasStaticWarning,
-        hasCrash: hasCrash);
+    var testFile = TestFile.vmUnitTest(
+        hasSyntaxError: false,
+        hasCompileError: testExpectation == Expectation.compileTimeError,
+        hasRuntimeError: testExpectation == Expectation.runtimeError,
+        hasStaticWarning: false,
+        hasCrash: testExpectation == Expectation.crash);
 
     var args = configuration.standardOptions.toList();
     if (configuration.compilerConfiguration.previewDart2) {
-      final filename = configuration.architecture == Architecture.x64
+      var filename = configuration.architecture == Architecture.x64
           ? '$buildDir/gen/kernel-service.dart.snapshot'
           : '$buildDir/gen/kernel_service.dill';
-      final dfePath = Path(filename).absolute.toNativePath();
+      var dfePath = Path(filename).absolute.toNativePath();
       // '--dfe' has to be the first argument for run_vm_test to pick it up.
       args.insert(0, '--dfe=$dfePath');
+      args.addAll(configuration.vmOptions);
     }
     if (expectations.contains(Expectation.crash)) {
       args.insert(0, '--suppress-core-dump');
@@ -405,9 +378,9 @@
 
     args.add(test.name);
 
-    final command = Command.process(
+    var command = Command.process(
         'run_vm_unittest', targetRunnerPath, args, environmentOverrides);
-    enqueueNewTestCase(fullName, [command], expectations, testInfo);
+    enqueueNewTestCase(testFile, fullName, [command], expectations);
   }
 
   Future<Iterable<VMUnitTest>> _listTests(String runnerPath) async {
@@ -435,37 +408,12 @@
   VMUnitTest(this.name, this.expectation);
 }
 
-class TestInformation {
-  Path filePath;
-  Path originTestPath;
-  Map<String, dynamic> optionsFromFile;
-  bool hasSyntaxError;
-  bool hasCompileError;
-  bool hasRuntimeError;
-  bool hasStaticWarning;
-  bool hasCrash;
-  String multitestKey;
-
-  TestInformation(
-      this.filePath,
-      this.originTestPath,
-      this.optionsFromFile,
-      this.hasSyntaxError,
-      this.hasCompileError,
-      this.hasRuntimeError,
-      this.hasStaticWarning,
-      {this.multitestKey = '',
-      this.hasCrash = false}) {
-    assert(filePath.isAbsolute);
-  }
-}
-
 /// A standard [TestSuite] implementation that searches for tests in a
 /// directory, and creates [TestCase]s that compile and/or run them.
 class StandardTestSuite extends TestSuite {
   final Path suiteDir;
   ExpectationSet testExpectations;
-  List<TestInformation> cachedTests;
+  List<TestFile> cachedTests;
   final Path dartDir;
   final bool listRecursively;
   final List<String> extraVmOptions;
@@ -581,19 +529,18 @@
 
   List<String> additionalOptions(Path filePath) => [];
 
-  Future forEachTest(
-      Function onTest, Map<String, List<TestInformation>> testCache,
+  Future forEachTest(Function onTest, Map<String, List<TestFile>> testCache,
       [VoidFunction onDone]) async {
     doTest = onTest;
     testExpectations = readExpectations();
 
     // Check if we have already found and generated the tests for this suite.
     if (!testCache.containsKey(suiteName)) {
-      cachedTests = testCache[suiteName] = <TestInformation>[];
+      cachedTests = testCache[suiteName] = <TestFile>[];
       await enqueueTests();
     } else {
-      for (var info in testCache[suiteName]) {
-        enqueueTestCaseFromTestInformation(info);
+      for (var testFile in testCache[suiteName]) {
+        enqueueTestCaseFromTestFile(testFile);
       }
     }
     testExpectations = null;
@@ -638,93 +585,73 @@
     group.add(lister);
   }
 
-  void enqueueFile(String filename, FutureGroup group) {
+  void enqueueFile(String filePath, FutureGroup group) {
     // This is an optimization to avoid scanning and generating extra tests.
     // The definitive check against configuration.testList is performed in
     // TestSuite.enqueueNewTestCase().
-    if (_testListPossibleFilenames?.contains(filename) == false) return;
+    if (_testListPossibleFilenames?.contains(filePath) == false) return;
+
     // Note: have to use Path instead of a filename for matching because
     // on Windows we need to convert backward slashes to forward slashes.
     // Our display test names (and filters) are given using forward slashes
     // while filenames on Windows use backwards slashes.
-    final Path filePath = Path(filename);
-    if (!_selectorFilenameRegExp.hasMatch(filePath.toString())) return;
+    if (!_selectorFilenameRegExp.hasMatch(Path(filePath).toString())) return;
 
-    if (!isTestFile(filename)) return;
+    if (!isTestFile(filePath)) return;
 
-    var optionsFromFile = readOptionsFromFile(Uri.file(filename));
-    CreateTest createTestCase = makeTestCaseCreator(optionsFromFile);
+    var testFile = TestFile.read(suiteDir, filePath);
 
-    if (optionsFromFile['isMultitest'] as bool) {
-      group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase,
-          configuration.hotReload || configuration.hotReloadRollback));
+    if (testFile.isMultitest) {
+      group.add(splitMultitest(testFile, buildDir, suiteDir,
+              hotReload:
+                  configuration.hotReload || configuration.hotReloadRollback)
+          .then((splitTests) {
+        for (var test in splitTests) {
+          cachedTests.add(test);
+          enqueueTestCaseFromTestFile(test);
+        }
+      }));
     } else {
-      createTestCase(filePath, filePath,
-          hasSyntaxError: optionsFromFile['hasSyntaxError'] as bool,
-          hasCompileError: optionsFromFile['hasCompileError'] as bool,
-          hasRuntimeError: optionsFromFile['hasRuntimeError'] as bool,
-          hasStaticWarning: optionsFromFile['hasStaticWarning'] as bool);
+      cachedTests.add(testFile);
+      enqueueTestCaseFromTestFile(testFile);
     }
   }
 
-  void enqueueTestCaseFromTestInformation(TestInformation info) {
-    String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath,
-        multitestName: info.optionsFromFile['isMultitest'] as bool
-            ? info.multitestKey
-            : "");
-    var optionsFromFile = info.optionsFromFile;
-
-    // If this test is inside a package, we will check if there is a
-    // pubspec.yaml file and if so, create a custom package root for it.
-    Path packageRoot;
-    Path packages;
-
-    if (optionsFromFile['packageRoot'] == null &&
-        optionsFromFile['packages'] == null) {
-      if (configuration.packageRoot != null) {
-        packageRoot = Path(configuration.packageRoot);
-        optionsFromFile['packageRoot'] = packageRoot.toNativePath();
-      }
-      if (configuration.packages != null) {
-        Path packages = Path(configuration.packages);
-        optionsFromFile['packages'] = packages.toNativePath();
-      }
-    }
+  void enqueueTestCaseFromTestFile(TestFile testFile) {
     if (configuration.compilerConfiguration.hasCompiler &&
-        info.hasCompileError) {
+        testFile.hasCompileError) {
       // If a compile-time error is expected, and we're testing a
       // compiler, we never need to attempt to run the program (in a
       // browser or otherwise).
-      enqueueStandardTest(info, testName);
+      enqueueStandardTest(testFile);
     } else if (configuration.runtime.isBrowser) {
       var expectationsMap = <String, Set<Expectation>>{};
 
-      if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
+      if (testFile.isMultiHtmlTest) {
         // A browser multi-test has multiple expectations for one test file.
         // Find all the different sub-test expectations for one entire test
         // file.
-        var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
+        var subtestNames = testFile.subtestNames;
         expectationsMap = <String, Set<Expectation>>{};
         for (var subtest in subtestNames) {
           expectationsMap[subtest] =
-              testExpectations.expectations('$testName/$subtest');
+              testExpectations.expectations('${testFile.name}/$subtest');
         }
       } else {
-        expectationsMap[testName] = testExpectations.expectations(testName);
+        expectationsMap[testFile.name] =
+            testExpectations.expectations(testFile.name);
       }
 
-      _enqueueBrowserTest(
-          packageRoot, packages, info, testName, expectationsMap);
+      _enqueueBrowserTest(testFile, expectationsMap);
     } else {
-      enqueueStandardTest(info, testName);
+      enqueueStandardTest(testFile);
     }
   }
 
-  void enqueueStandardTest(TestInformation info, String testName) {
-    var commonArguments =
-        commonArgumentsFromFile(info.filePath, info.optionsFromFile);
+  void enqueueStandardTest(TestFile testFile) {
+    var commonArguments = _commonArgumentsFromFile(testFile);
 
-    var vmOptionsList = getVmOptions(info.optionsFromFile);
+    var vmOptionsList = getVmOptions(testFile);
     assert(!vmOptionsList.isEmpty);
 
     for (var vmOptionsVariant = 0;
@@ -736,53 +663,44 @@
         allVmOptions = vmOptions.toList()..addAll(extraVmOptions);
       }
 
-      var expectations = testExpectations.expectations(testName);
+      var expectations = testExpectations.expectations(testFile.name);
       var isCrashExpected = expectations.contains(Expectation.crash);
-      var commands = makeCommands(info, vmOptionsVariant, allVmOptions,
+      var commands = makeCommands(testFile, vmOptionsVariant, allVmOptions,
           commonArguments, isCrashExpected);
-      var variantTestName = testName;
+      var variantTestName = testFile.name;
       if (vmOptionsList.length > 1) {
-        variantTestName = "$testName/$vmOptionsVariant";
+        variantTestName = "${testFile.name}/$vmOptionsVariant";
       }
-      enqueueNewTestCase(variantTestName, commands, expectations, info);
+      enqueueNewTestCase(testFile, variantTestName, commands, expectations);
     }
   }
 
-  List<Command> makeCommands(TestInformation info, int vmOptionsVariant,
+  List<Command> makeCommands(TestFile testFile, int vmOptionsVariant,
       List<String> vmOptions, List<String> args, bool isCrashExpected) {
     var commands = <Command>[];
     var compilerConfiguration = configuration.compilerConfiguration;
-    var sharedOptions = info.optionsFromFile['sharedOptions'] as List<String>;
-    var dartOptions = info.optionsFromFile['dartOptions'] as List<String>;
-    var dart2jsOptions = info.optionsFromFile['dart2jsOptions'] as List<String>;
-    var ddcOptions = info.optionsFromFile['ddcOptions'] as List<String>;
-
-    var isMultitest = info.optionsFromFile["isMultitest"] as bool;
-    assert(!isMultitest || dartOptions.isEmpty);
 
     var compileTimeArguments = <String>[];
     String tempDir;
     if (compilerConfiguration.hasCompiler) {
       compileTimeArguments = compilerConfiguration.computeCompilerArguments(
           vmOptions,
-          sharedOptions,
-          dartOptions,
-          dart2jsOptions,
-          ddcOptions,
+          testFile.sharedOptions,
+          testFile.dartOptions,
+          testFile.dart2jsOptions,
+          testFile.ddcOptions,
           args);
       // Avoid doing this for analyzer.
-      var path = info.filePath;
+      var path = testFile.path;
       if (vmOptionsVariant != 0) {
         // Ensure a unique directory for each test case.
         path = path.join(Path(vmOptionsVariant.toString()));
       }
       tempDir = createCompilationOutputDirectory(path);
 
-      var otherResources =
-          info.optionsFromFile['otherResources'] as List<String>;
-      for (var name in otherResources) {
+      for (var name in testFile.otherResources) {
         var namePath = Path(name);
-        var fromPath = info.filePath.directoryPath.join(namePath);
+        var fromPath = testFile.path.directoryPath.join(namePath);
         File('$tempDir/$name').parent.createSync(recursive: true);
         File(fromPath.toNativePath()).copySync('$tempDir/$name');
       }
@@ -794,7 +712,7 @@
       commands.addAll(compilationArtifact.commands);
     }
 
-    if (info.hasCompileError &&
+    if (testFile.hasCompileError &&
         compilerConfiguration.hasCompiler &&
         !compilerConfiguration.runRuntimeDespiteMissingCompileTimeError) {
       // Do not attempt to run the compiled result. A compilation
@@ -809,44 +727,22 @@
 
     var runtimeArguments = compilerConfiguration.computeRuntimeArguments(
         configuration.runtimeConfiguration,
-        info,
+        testFile,
         vmOptions,
-        sharedOptions,
-        dartOptions,
         args,
         compilationArtifact);
 
-    var environment = environmentOverrides;
-    var extraEnv = info.optionsFromFile['environment'] as Map<String, String>;
-    if (extraEnv != null) {
-      environment = {...environment, ...extraEnv};
-    }
+    var environment = {...environmentOverrides, ...?testFile.environment};
 
     return commands
       ..addAll(configuration.runtimeConfiguration.computeRuntimeCommands(
           compilationArtifact,
           runtimeArguments,
           environment,
-          info.optionsFromFile["sharedObjects"] as List<String>,
+          testFile.sharedObjects,
           isCrashExpected));
   }
 
-  CreateTest makeTestCaseCreator(Map<String, dynamic> optionsFromFile) {
-    return (Path filePath, Path originTestPath,
-        {bool hasSyntaxError,
-        bool hasCompileError,
-        bool hasRuntimeError,
-        bool hasStaticWarning = false,
-        String multitestKey}) {
-      // Cache the test information for each test case.
-      var info = TestInformation(filePath, originTestPath, optionsFromFile,
-          hasSyntaxError, hasCompileError, hasRuntimeError, hasStaticWarning,
-          multitestKey: multitestKey);
-      cachedTests.add(info);
-      enqueueTestCaseFromTestInformation(info);
-    };
-  }
-
   /// Takes a [file], which is either located in the dart or in the build
   /// directory, and returns a String representing the relative path to either
   /// the dart or the build directory.
@@ -907,26 +803,20 @@
   ///
   /// In order to handle browser multitests, [expectations] is a map of subtest
   /// names to expectation sets. If the test is not a multitest, the map has
-  /// a single key, [testName].
+  /// a single key, [testFile.name].
   void _enqueueBrowserTest(
-      Path packageRoot,
-      Path packages,
-      TestInformation info,
-      String testName,
-      Map<String, Set<Expectation>> expectations) {
-    var tempDir = createOutputDirectory(info.filePath);
-    var fileName = info.filePath.toNativePath();
-    var optionsFromFile = info.optionsFromFile;
-    var compilationTempDir = createCompilationOutputDirectory(info.filePath);
-    var nameNoExt = info.filePath.filenameWithoutExtension;
+      TestFile testFile, Map<String, Set<Expectation>> expectations) {
+    var tempDir = createOutputDirectory(testFile.path);
+    var compilationTempDir = createCompilationOutputDirectory(testFile.path);
+    var nameNoExt = testFile.path.filenameWithoutExtension;
     var outputDir = compilationTempDir;
-    var commonArguments =
-        commonArgumentsFromFile(info.filePath, optionsFromFile);
+
+    var commonArguments = _commonArgumentsFromFile(testFile);
 
     // Use existing HTML document if available.
     String content;
     var customHtml = File(
-        info.filePath.directoryPath.append('$nameNoExt.html').toNativePath());
+        testFile.path.directoryPath.append('$nameNoExt.html').toNativePath());
     if (customHtml.existsSync()) {
       outputDir = tempDir;
       content = customHtml.readAsStringSync().replaceAll(
@@ -936,7 +826,7 @@
       if (configuration.compiler == Compiler.dart2js) {
         var scriptPath =
             _createUrlPathFromFile(Path('$compilationTempDir/$nameNoExt.js'));
-        content = dart2jsHtml(fileName, scriptPath);
+        content = dart2jsHtml(testFile.path.toNativePath(), scriptPath);
       } else {
         var jsDir =
             Path(compilationTempDir).relativeTo(Repository.dir).toString();
@@ -956,33 +846,40 @@
       Compiler.dartdevk
     };
     assert(supportedCompilers.contains(configuration.compiler));
-    var sharedOptions = optionsFromFile["sharedOptions"] as List<String>;
-    var dart2jsOptions = optionsFromFile["dart2jsOptions"] as List<String>;
-    var ddcOptions = optionsFromFile["ddcOptions"] as List<String>;
 
     var args = configuration.compilerConfiguration.computeCompilerArguments(
-        null, sharedOptions, null, dart2jsOptions, ddcOptions, commonArguments);
+        null,
+        testFile.sharedOptions,
+        null,
+        testFile.dart2jsOptions,
+        testFile.ddcOptions,
+        commonArguments);
     var compilation = configuration.compilerConfiguration
         .computeCompilationArtifact(outputDir, args, environmentOverrides);
     commands.addAll(compilation.commands);
 
-    if (info.optionsFromFile['isMultiHtmlTest'] as bool) {
+    if (testFile.isMultiHtmlTest) {
       // Variables for browser multi-tests.
-      var subtestNames = info.optionsFromFile['subtestNames'] as List<String>;
+      var subtestNames = testFile.subtestNames;
       for (var subtestName in subtestNames) {
-        _enqueueSingleBrowserTest(commands, info, '$testName/$subtestName',
-            subtestName, expectations[subtestName], htmlPath);
+        _enqueueSingleBrowserTest(
+            commands,
+            testFile,
+            '${testFile.name}/$subtestName',
+            subtestName,
+            expectations[subtestName],
+            htmlPath);
       }
     } else {
-      _enqueueSingleBrowserTest(
-          commands, info, testName, null, expectations[testName], htmlPath);
+      _enqueueSingleBrowserTest(commands, testFile, testFile.name, null,
+          expectations[testFile.name], htmlPath);
     }
   }
 
   /// Enqueues a single browser test, or a single subtest of an HTML multitest.
   void _enqueueSingleBrowserTest(
       List<Command> commands,
-      TestInformation info,
+      TestFile testFile,
       String testName,
       String subtestName,
       Set<Expectation> expectations,
@@ -994,300 +891,66 @@
     var fullHtmlPath = _uriForBrowserTest(htmlPathSubtest, subtestName);
 
     commands.add(Command.browserTest(fullHtmlPath, configuration,
-        retry: !isNegative(info)));
+        retry: !isNegative(testFile)));
 
     var fullName = testName;
     if (subtestName != null) fullName += "/$subtestName";
-    enqueueNewTestCase(fullName, commands, expectations, info);
+    enqueueNewTestCase(testFile, fullName, commands, expectations);
   }
 
-  List<String> commonArgumentsFromFile(
-      Path filePath, Map<String, dynamic> optionsFromFile) {
+  List<String> _commonArgumentsFromFile(TestFile testFile) {
     var args = configuration.standardOptions.toList();
 
-    var packages = packagesArgument(optionsFromFile['packageRoot'] as String,
-        optionsFromFile['packages'] as String);
+    var packages = packagesArgument(testFile.packageRoot, testFile.packages);
     if (packages != null) {
       args.add(packages);
     }
-    args.addAll(additionalOptions(filePath));
+    args.addAll(additionalOptions(testFile.path));
     if (configuration.compiler == Compiler.dart2analyzer) {
       args.add('--format=machine');
       args.add('--no-hints');
 
-      if (filePath.filename.contains("dart2js") ||
-          filePath.directoryPath.segments().last.contains('html_common')) {
+      if (testFile.path.filename.contains("dart2js") ||
+          testFile.path.directoryPath.segments().last.contains('html_common')) {
         args.add("--use-dart2js-libraries");
       }
     }
 
-    args.add(filePath.toNativePath());
+    args.add(testFile.path.toNativePath());
 
     return args;
   }
 
-  String packagesArgument(String packageRootFromFile, String packagesFromFile) {
-    if (packageRootFromFile == 'none' || packagesFromFile == 'none') {
+  String packagesArgument(String packageRoot, String packages) {
+    // If this test is inside a package, we will check if there is a
+    // pubspec.yaml file and if so, create a custom package root for it.
+    if (packageRoot == null && packages == null) {
+      if (configuration.packageRoot != null) {
+        packageRoot = Path(configuration.packageRoot).toNativePath();
+      }
+
+      if (configuration.packages != null) {
+        packages = Path(configuration.packages).toNativePath();
+      }
+    }
+
+    if (packageRoot == 'none' || packages == 'none') {
       return null;
-    } else if (packagesFromFile != null) {
-      return '--packages=$packagesFromFile';
-    } else if (packageRootFromFile != null) {
-      return '--package-root=$packageRootFromFile';
+    } else if (packages != null) {
+      return '--packages=$packages';
+    } else if (packageRoot != null) {
+      return '--package-root=$packageRoot';
     } else {
       return null;
     }
   }
 
-  /// Special options for individual tests are currently specified in various
-  /// ways: with comments directly in test files, by using certain imports, or
-  /// by creating additional files in the test directories.
-  ///
-  /// Here is a list of options that are used by 'test.dart' today:
-  ///   - Flags can be passed to the vm process that runs the test by adding a
-  ///   comment to the test file:
-  ///
-  ///     // VMOptions=--flag1 --flag2
-  ///
-  ///   - Flags can be passed to dart2js, vm or dartdevc by adding a comment to
-  ///   the test file:
-  ///
-  ///     // SharedOptions=--flag1 --flag2
-  ///
-  ///   - Flags can be passed to dart2js by adding a comment to the test file:
-  ///
-  ///     // dart2jsOptions=--flag1 --flag2
-  ///
-  ///   - Flags can be passed to the dart script that contains the test also
-  ///   using comments, as follows:
-  ///
-  ///     // DartOptions=--flag1 --flag2
-  ///
-  ///   - Extra environment variables can be passed to the process that runs
-  ///   the test by adding comment(s) to the test file:
-  ///
-  ///     // Environment=ENV_VAR1=foo bar
-  ///     // Environment=ENV_VAR2=bazz
-  ///
-  ///   - Most tests are not web tests, but can (and will be) wrapped within
-  ///   an HTML file and another script file to test them also on browser
-  ///   environments (e.g. language and corelib tests are run this way).
-  ///   We deduce that if a file with the same name as the test, but ending in
-  ///   .html instead of .dart exists, the test was intended to be a web test
-  ///   and no wrapping is necessary.
-  ///
-  ///     // SharedObjects=foobar
-  ///
-  ///   - This test requires libfoobar.so, libfoobar.dylib or foobar.dll to be
-  ///   in the system linker path of the VM.
-  ///
-  ///   - 'test.dart' assumes tests fail if
-  ///   the process returns a non-zero exit code (in the case of web tests, we
-  ///   check for PASS/FAIL indications in the test output).
-  ///
-  /// This method is static as the map is cached and shared amongst
-  /// configurations, so it may not use [configuration].
-  Map<String, dynamic> readOptionsFromFile(Uri uri) {
-    if (uri.path.endsWith('.dill')) {
-      return optionsFromKernelFile();
-    }
-    var testOptionsRegExp = RegExp(r"// VMOptions=(.*)");
-    var environmentRegExp = RegExp(r"// Environment=(.*)");
-    var otherResourcesRegExp = RegExp(r"// OtherResources=(.*)");
-    var sharedObjectsRegExp = RegExp(r"// SharedObjects=(.*)");
-    var packageRootRegExp = RegExp(r"// PackageRoot=(.*)");
-    var packagesRegExp = RegExp(r"// Packages=(.*)");
-    var isolateStubsRegExp = RegExp(r"// IsolateStubs=(.*)");
-    // TODO(gram) Clean these up once the old directives are not supported.
-    var domImportRegExp = RegExp(
-        r"^[#]?import.*dart:(html|web_audio|indexed_db|svg|web_sql)",
-        multiLine: true);
-
-    var bytes = File.fromUri(uri).readAsBytesSync();
-    var contents = decodeUtf8(bytes);
-    bytes = null;
-
-    // Find the options in the file.
-    var result = <List<String>>[];
-    List<String> dartOptions;
-    List<String> sharedOptions;
-    List<String> dart2jsOptions;
-    List<String> ddcOptions;
-    Map<String, String> environment;
-    String packageRoot;
-    String packages;
-
-    List<String> wordSplit(String s) =>
-        s.split(' ').where((e) => e != '').toList();
-
-    List<String> singleListOfOptions(String name) {
-      var matches = RegExp('// $name=(.*)').allMatches(contents);
-      List<String> options;
-      for (var match in matches) {
-        if (options != null) {
-          throw Exception(
-              'More than one "// $name=" line in test ${uri.toFilePath()}');
-        }
-        options = wordSplit(match[1]);
-      }
-      return options;
-    }
-
-    var matches = testOptionsRegExp.allMatches(contents);
-    for (var match in matches) {
-      result.add(wordSplit(match[1]));
-    }
-    if (result.isEmpty) result.add(<String>[]);
-
-    dartOptions = singleListOfOptions('DartOptions');
-    sharedOptions = singleListOfOptions('SharedOptions');
-    dart2jsOptions = singleListOfOptions('dart2jsOptions');
-    ddcOptions = singleListOfOptions('dartdevcOptions');
-
-    matches = environmentRegExp.allMatches(contents);
-    for (var match in matches) {
-      var envDef = match[1];
-      var pos = envDef.indexOf('=');
-      var name = (pos < 0) ? envDef : envDef.substring(0, pos);
-      var value = (pos < 0) ? '' : envDef.substring(pos + 1);
-      environment ??= <String, String>{};
-      environment[name] = value;
-    }
-
-    matches = packageRootRegExp.allMatches(contents);
-    for (var match in matches) {
-      if (packageRoot != null || packages != null) {
-        throw Exception(
-            'More than one "// Package... line in test ${uri.toFilePath()}');
-      }
-      packageRoot = match[1];
-      if (packageRoot != 'none') {
-        // PackageRoot=none means that no packages or package-root option
-        // should be given. Any other value overrides package-root and
-        // removes any packages option.  Don't use with // Packages=.
-        packageRoot = uri.resolveUri(Uri.directory(packageRoot)).toFilePath();
-      }
-    }
-
-    matches = packagesRegExp.allMatches(contents);
-    for (var match in matches) {
-      if (packages != null || packageRoot != null) {
-        throw Exception(
-            'More than one "// Package..." line in test ${uri.toFilePath()}');
-      }
-      packages = match[1];
-      if (packages != 'none') {
-        // Packages=none means that no packages or package-root option
-        // should be given. Any other value overrides packages and removes
-        // any package-root option. Don't use with // PackageRoot=.
-        packages = uri.resolveUri(Uri.file(packages)).toFilePath();
-      }
-    }
-
-    var otherResources = <String>[];
-    matches = otherResourcesRegExp.allMatches(contents);
-    for (var match in matches) {
-      otherResources.addAll(wordSplit(match[1]));
-    }
-
-    var sharedObjects = <String>[];
-    matches = sharedObjectsRegExp.allMatches(contents);
-    for (var match in matches) {
-      sharedObjects.addAll(wordSplit(match[1]));
-    }
-
-    var isMultitest = _multiTestRegExp.hasMatch(contents);
-    var isMultiHtmlTest = _multiHtmlTestRegExp.hasMatch(contents);
-    var isolateMatch = isolateStubsRegExp.firstMatch(contents);
-    var isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
-    var containsDomImport = domImportRegExp.hasMatch(contents);
-
-    var subtestNames = <String>[];
-    var matchesIter = _multiHtmlTestGroupRegExp.allMatches(contents).iterator;
-    while (matchesIter.moveNext() && isMultiHtmlTest) {
-      var fullMatch = matchesIter.current.group(0);
-      subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
-    }
-
-    // TODO(rnystrom): During the migration of the existing tests to Dart 2.0,
-    // we have a number of tests that used to both generate static type warnings
-    // and also validate some runtime behavior in an implementation that
-    // ignores those warnings. Those warnings are now errors. The test code
-    // validates the runtime behavior can and should be removed, but the code
-    // that causes the static warning should still be preserved since that is
-    // part of our coverage of the static type system.
-    //
-    // The test needs to indicate that it should have a static error. We could
-    // put that in the status file, but that makes it confusing because it
-    // would look like implementations that *don't* report the error are more
-    // correct. Eventually, we want to have a notation similar to what front_end
-    // is using for the inference tests where we can put a comment inside the
-    // test that says "This specific static error should be reported right by
-    // this token."
-    //
-    // That system isn't in place yet, so we do a crude approximation here in
-    // test.dart. If a test contains `/*@compile-error=`, which matches the
-    // beginning of the tag syntax that front_end uses, then we assume that
-    // this test must have a static error somewhere in it.
-    //
-    // Redo this code once we have a more precise test framework for detecting
-    // and locating these errors.
-    final hasSyntaxError = contents.contains("@syntax-error");
-    final hasCompileError =
-        hasSyntaxError || contents.contains("@compile-error");
-    final hasRuntimeError = contents.contains("@runtime-error");
-    final hasStaticWarning = contents.contains("@static-warning");
-
-    return {
-      "vmOptions": result,
-      "sharedOptions": sharedOptions ?? <String>[],
-      "dart2jsOptions": dart2jsOptions ?? <String>[],
-      "ddcOptions": ddcOptions ?? <String>[],
-      "dartOptions": dartOptions ?? <String>[],
-      "environment": environment,
-      "packageRoot": packageRoot,
-      "packages": packages,
-      "hasSyntaxError": hasSyntaxError,
-      "hasCompileError": hasCompileError,
-      "hasRuntimeError": hasRuntimeError,
-      "hasStaticWarning": hasStaticWarning,
-      "otherResources": otherResources,
-      "sharedObjects": sharedObjects,
-      "isMultitest": isMultitest,
-      "isMultiHtmlTest": isMultiHtmlTest,
-      "subtestNames": subtestNames,
-      "isolateStubs": isolateStubs,
-      "containsDomImport": containsDomImport
-    };
-  }
-
-  Map<String, dynamic> optionsFromKernelFile() {
-    return const {
-      "vmOptions": [<String>[]],
-      "sharedOptions": <String>[],
-      "dart2jsOptions": <String>[],
-      "dartOptions": <String>[],
-      "packageRoot": null,
-      "packages": null,
-      "hasSyntaxError": false,
-      "hasCompileError": false,
-      "hasRuntimeError": false,
-      "hasStaticWarning": false,
-      "isMultitest": false,
-      "isMultiHtmlTest": false,
-      "subtestNames": [],
-      "isolateStubs": '',
-      "containsDomImport": false,
-    };
-  }
-
-  List<List<String>> getVmOptions(Map<String, dynamic> optionsFromFile) {
+  List<List<String>> getVmOptions(TestFile testFile) {
     const compilers = [
       Compiler.none,
       Compiler.dartk,
       Compiler.dartkb,
       Compiler.dartkp,
-      Compiler.precompiler,
-      Compiler.appJit,
       Compiler.appJitk,
     ];
 
@@ -1296,7 +959,7 @@
     var needsVmOptions = compilers.contains(configuration.compiler) &&
         runtimes.contains(configuration.runtime);
     if (!needsVmOptions) return [[]];
-    return optionsFromFile['vmOptions'] as List<List<String>>;
+    return testFile.vmOptions;
   }
 }
 
@@ -1308,21 +971,20 @@
             ["$directoryPath/.status"],
             recursive: true);
 
-  void _enqueueBrowserTest(Path packageRoot, packages, TestInformation info,
-      String testName, Map<String, Set<Expectation>> expectations) {
-    var filePath = info.filePath;
-    var dir = filePath.directoryPath;
-    var nameNoExt = filePath.filenameWithoutExtension;
+  void _enqueueBrowserTest(
+      TestFile testFile, Map<String, Set<Expectation>> expectations) {
+    var dir = testFile.path.directoryPath;
+    var nameNoExt = testFile.path.filenameWithoutExtension;
     var customHtmlPath = dir.append('$nameNoExt.html');
     var customHtml = File(customHtmlPath.toNativePath());
     if (!customHtml.existsSync()) {
-      super._enqueueBrowserTest(
-          packageRoot, packages, info, testName, expectations);
+      super._enqueueBrowserTest(testFile, expectations);
     } else {
       var fullPath = _createUrlPathFromFile(customHtmlPath);
       var command = Command.browserTest(fullPath, configuration,
-          retry: !isNegative(info));
-      enqueueNewTestCase(testName, [command], expectations[testName], info);
+          retry: !isNegative(testFile));
+      enqueueNewTestCase(
+          testFile, testFile.name, [command], expectations[testFile.name]);
     }
   }
 }
diff --git a/pkg/test_runner/lib/src/testing_servers.dart b/pkg/test_runner/lib/src/testing_servers.dart
index 92d3949..06a1fc5 100644
--- a/pkg/test_runner/lib/src/testing_servers.dart
+++ b/pkg/test_runner/lib/src/testing_servers.dart
@@ -223,7 +223,7 @@
 
   void _handleEchoRequest(HttpRequest request) {
     request.response.headers.set("Access-Control-Allow-Origin", "*");
-    request.pipe(request.response).catchError((e) {
+    request.cast<List<int>>().pipe(request.response).catchError((e) {
       DebugLogger.warning(
           'HttpServer: error while closing the response stream', e);
     });
@@ -373,7 +373,7 @@
       response.headers.set('Content-Type', 'text/xml');
     }
     response.headers.removeAll("X-Frame-Options");
-    file.openRead().pipe(response).catchError((e) {
+    file.openRead().cast<List<int>>().pipe(response).catchError((e) {
       DebugLogger.warning(
           'HttpServer: error while closing the response stream', e);
     });
diff --git a/pkg/test_runner/lib/src/utils.dart b/pkg/test_runner/lib/src/utils.dart
index 1d1d0a5..121b235 100644
--- a/pkg/test_runner/lib/src/utils.dart
+++ b/pkg/test_runner/lib/src/utils.dart
@@ -424,9 +424,7 @@
   }
 
   static void deleteTempSnapshotDirectory(TestConfiguration configuration) {
-    if (configuration.compiler == Compiler.appJit ||
-        configuration.compiler == Compiler.precompiler ||
-        configuration.compiler == Compiler.dartk ||
+    if (configuration.compiler == Compiler.dartk ||
         configuration.compiler == Compiler.dartkb ||
         configuration.compiler == Compiler.dartkp) {
       var checked = configuration.isChecked ? '-checked' : '';
diff --git a/pkg/test_runner/test/test_file_test.dart b/pkg/test_runner/test/test_file_test.dart
new file mode 100644
index 0000000..9d42f3d
--- /dev/null
+++ b/pkg/test_runner/test/test_file_test.dart
@@ -0,0 +1,509 @@
+// Copyright (c) 2019, 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 'dart:io';
+
+import 'package:expect/expect.dart';
+
+import 'package:test_runner/src/path.dart';
+import 'package:test_runner/src/test_file.dart';
+
+// Note: This test file validates how some of the special markers used by the
+// test runner are parsed. But this test is also run *by* that same test
+// runner, and we don't want it to see the markers inside the string literals
+// here as significant, so we obfuscate them using seemingly-pointless string
+// escapes here like `\/`.
+
+void main() {
+  testParseDill();
+  testParseVMOptions();
+  testParseOtherOptions();
+  testParseEnvironment();
+  testParsePackages();
+  testParseMultitest();
+  testParseMultiHtmltest();
+  testParseErrorFlags();
+  testParseErrorExpectations();
+  testName();
+  testMultitest();
+}
+
+void testParseDill() {
+  // Handles ".dill" files.
+  var file = parse("", path: "test.dill");
+  Expect.isNotNull(file.vmOptions);
+  Expect.equals(1, file.vmOptions.length);
+  Expect.listEquals(<String>[], file.vmOptions.first);
+
+  Expect.listEquals(<String>[], file.dartOptions);
+  Expect.listEquals(<String>[], file.sharedOptions);
+  Expect.listEquals(<String>[], file.dart2jsOptions);
+  Expect.listEquals(<String>[], file.ddcOptions);
+  Expect.listEquals(<String>[], file.otherResources);
+  Expect.listEquals(<String>[], file.sharedObjects);
+
+  Expect.isNull(file.environment);
+  Expect.isNull(file.packages);
+
+  Expect.isFalse(file.isMultitest);
+
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isFalse(file.hasCompileError);
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+}
+
+void testParseVMOptions() {
+  expectVMOptions(String source, List<List<String>> expected) {
+    var file = parse(source);
+    Expect.isNotNull(file.vmOptions);
+    Expect.equals(expected.length, file.vmOptions.length);
+    for (var i = 0; i < expected.length; i++) {
+      Expect.listEquals(expected[i], file.vmOptions[i]);
+    }
+  }
+
+  // No options.
+  expectVMOptions("", [[]]);
+
+  // Splits words.
+  expectVMOptions("/\/ VMOptions=--verbose --async", [
+    ["--verbose", "--async"]
+  ]);
+
+  // Allows multiple.
+  expectVMOptions("""
+  /\/ VMOptions=--first one
+  /\/ VMOptions=--second two
+  """, [
+    ["--first", "one"],
+    ["--second", "two"]
+  ]);
+}
+
+void testParseOtherOptions() {
+  // No options.
+  var file = parse("");
+  Expect.listEquals(<String>[], file.dartOptions);
+  Expect.listEquals(<String>[], file.sharedOptions);
+  Expect.listEquals(<String>[], file.dart2jsOptions);
+  Expect.listEquals(<String>[], file.ddcOptions);
+  Expect.listEquals(<String>[], file.otherResources);
+  Expect.listEquals(<String>[], file.sharedObjects);
+
+  // Single options split into words.
+  file = parse("""
+  /\/ DartOptions=dart options
+  /\/ SharedOptions=shared options
+  /\/ dart2jsOptions=dart2js options
+  /\/ dartdevcOptions=ddc options
+  /\/ OtherResources=other resources
+  /\/ SharedObjects=shared objects
+  """);
+  Expect.listEquals(["dart", "options"], file.dartOptions);
+  Expect.listEquals(["shared", "options"], file.sharedOptions);
+  Expect.listEquals(["dart2js", "options"], file.dart2jsOptions);
+  Expect.listEquals(["ddc", "options"], file.ddcOptions);
+  Expect.listEquals(["other", "resources"], file.otherResources);
+  Expect.listEquals(["shared", "objects"], file.sharedObjects);
+
+  // Disallows multiple lines for some options.
+  expectParseThrows("""
+  /\/ DartOptions=first
+  /\/ DartOptions=second
+  """);
+  expectParseThrows("""
+  /\/ SharedOptions=first
+  /\/ SharedOptions=second
+  """);
+  expectParseThrows("""
+  /\/ dart2jsOptions=first
+  /\/ dart2jsOptions=second
+  """);
+  expectParseThrows("""
+  /\/ dartdevcOptions=first
+  /\/ dartdevcOptions=second
+  """);
+
+  // Merges multiple lines for others.
+  file = parse("""
+  /\/ OtherResources=other resources
+  /\/ OtherResources=even more
+  /\/ SharedObjects=shared objects
+  /\/ SharedObjects=many more
+  """);
+  Expect.listEquals(
+      ["other", "resources", "even", "more"], file.otherResources);
+  Expect.listEquals(["shared", "objects", "many", "more"], file.sharedObjects);
+}
+
+void testParseEnvironment() {
+  // No environment.
+  var file = parse("");
+  Expect.isNull(file.environment);
+
+  // Without values.
+  file = parse("""
+  /\/ Environment=some value
+  /\/ Environment=another one
+  """);
+  Expect.mapEquals({"some value": "", "another one": ""}, file.environment);
+
+  // With values.
+  file = parse("""
+  /\/ Environment=some value=its value
+  /\/ Environment=another one   =   also value
+  """);
+  Expect.mapEquals(
+      {"some value": "its value", "another one   ": "   also value"},
+      file.environment);
+}
+
+void testParsePackages() {
+  // No option.
+  var file = parse("");
+  Expect.isNull(file.packages);
+
+  // Single option is converted to a path.
+  file = parse("""
+  /\/ Packages=packages thing
+  """);
+  Expect.isTrue(
+      file.packages.endsWith("${Platform.pathSeparator}packages thing"));
+
+  // "none" is left alone.
+  file = parse("""
+  /\/ Packages=none
+  """);
+  Expect.equals("none", file.packages);
+
+  // Cannot appear more than once.
+  expectParseThrows("""
+  /\/ Packages=first
+  /\/ Packages=second
+  """);
+}
+
+void testParseMultitest() {
+  // Not present.
+  var file = parse("");
+  Expect.isFalse(file.isMultitest);
+
+  // Present.
+  file = parse("""
+  main() {} /\/# 01: compile-time error
+  """);
+  Expect.isTrue(file.isMultitest);
+}
+
+void testParseMultiHtmltest() {
+  // Not present.
+  var file = parse("");
+  Expect.isFalse(file.isMultiHtmlTest);
+  Expect.listEquals(<String>[], file.subtestNames);
+
+  // Present.
+  // Note: the "${''}" is to prevent the test runner running *this* test file
+  // from parsing it as a multi-HTML test.
+  file = parse("""
+  main() {
+    useHtml\IndividualConfiguration();
+    group('pixel_manipulation', () {
+    });
+    group('arc', () {
+    });
+    group('drawImage_image_element', () {
+    });
+  }
+  """);
+  Expect.isTrue(file.isMultiHtmlTest);
+  Expect.listEquals(["pixel_manipulation", "arc", "drawImage_image_element"],
+      file.subtestNames);
+}
+
+void testParseErrorFlags() {
+  // Not present.
+  var file = parse("");
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isFalse(file.hasCompileError);
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+
+  file = parse("@syntax\-error");
+  Expect.isTrue(file.hasSyntaxError);
+  Expect.isTrue(file.hasCompileError); // Note: true.
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+
+  file = parse("@compile\-error");
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isTrue(file.hasCompileError);
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+
+  file = parse("@runtime\-error");
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isFalse(file.hasCompileError);
+  Expect.isTrue(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+
+  file = parse("@static\-warning");
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isFalse(file.hasCompileError);
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isTrue(file.hasStaticWarning);
+  Expect.isFalse(file.hasCrash);
+}
+
+void testParseErrorExpectations() {
+  // No errors.
+  expectParseErrorExpectations("""
+main() {}
+""", []);
+
+  // Empty file
+  expectParseErrorExpectations("", []);
+
+  // Multiple errors.
+  expectParseErrorExpectations("""
+int i = "s";
+/\/      ^^^
+/\/ [analyzer] CompileTimeErrorCode.WRONG_TYPE
+/\/ [cfe] Error: Can't assign a string to an int.
+
+num j = "str";
+  /\/    ^^^^^
+/\/ [analyzer] CompileTimeErrorCode.ALSO_WRONG_TYPE
+    /\/ [cfe] Error: Can't assign a string to a num.
+""", [
+    ErrorExpectation(
+        line: 1,
+        column: 9,
+        length: 3,
+        code: "CompileTimeErrorCode.WRONG_TYPE",
+        message: "Error: Can't assign a string to an int."),
+    ErrorExpectation(
+        line: 6,
+        column: 9,
+        length: 5,
+        code: "CompileTimeErrorCode.ALSO_WRONG_TYPE",
+        message: "Error: Can't assign a string to a num.")
+  ]);
+
+  // Explicit error location.
+  expectParseErrorExpectations("""
+/\/ [error line 123, column 45, length 678]
+/\/ [analyzer] CompileTimeErrorCode.FIRST
+/\/ [cfe] First error.
+  /\/   [ error line   23  ,  column   5  ,  length   78  ]
+/\/ [analyzer] CompileTimeErrorCode.SECOND
+/\/ [cfe] Second error.
+/\/[error line 9,column 8,length 7]
+/\/ [cfe] Third.
+""", [
+    ErrorExpectation(
+        line: 123,
+        column: 45,
+        length: 678,
+        code: "CompileTimeErrorCode.FIRST",
+        message: "First error."),
+    ErrorExpectation(
+        line: 23,
+        column: 5,
+        length: 78,
+        code: "CompileTimeErrorCode.SECOND",
+        message: "Second error."),
+    ErrorExpectation(line: 9, column: 8, length: 7, message: "Third.")
+  ]);
+
+  // Multi-line error message.
+  expectParseErrorExpectations("""
+int i = "s";
+/\/      ^^^
+/\/ [analyzer] CompileTimeErrorCode.WRONG_TYPE
+/\/ [cfe] First line.
+/\/Second line.
+    /\/     Third line.
+
+/\/ The preceding blank line ends the message.
+""", [
+    ErrorExpectation(
+        line: 1,
+        column: 9,
+        length: 3,
+        code: "CompileTimeErrorCode.WRONG_TYPE",
+        message: "First line.\nSecond line.\nThird line.")
+  ]);
+
+  // Multiple errors attached to same line.
+  expectParseErrorExpectations("""
+main() {}
+int i = "s";
+/\/      ^^^
+/\/ [cfe] First error.
+/\/    ^
+/\/ [analyzer] ErrorCode.second
+/\/  ^^^^^^^
+/\/ [cfe] Third error.
+""", [
+    ErrorExpectation(line: 2, column: 9, length: 3, message: "First error."),
+    ErrorExpectation(line: 2, column: 7, length: 1, code: "ErrorCode.second"),
+    ErrorExpectation(line: 2, column: 5, length: 7, message: "Third error."),
+  ]);
+
+  // Unspecified errors.
+  expectParseErrorExpectations("""
+int i = "s";
+/\/ [unspecified error]
+int j = "s";
+  /\/ [unspecified error] some additional info
+""", [
+    ErrorExpectation(
+        line: 1, column: null, length: null, code: null, message: null),
+    ErrorExpectation(
+        line: 3, column: null, length: null, code: null, message: null)
+  ]);
+
+  // Ignore multitest markers.
+  expectParseErrorExpectations("""
+int i = "s";
+/\/      ^^^ /\/# 0: ok
+/\/ [analyzer] ErrorCode.BAD_THING /\/# 123: continued
+/\/ [cfe] Message.  /\/# named: compile-time error
+/\/ More message.  /\/#   another: ok
+/\/ [error line 12, column 34, length 56]  /\/# 3: continued
+/\/ [cfe] Message.
+""", [
+    ErrorExpectation(
+        line: 1,
+        column: 9,
+        length: 3,
+        code: "ErrorCode.BAD_THING",
+        message: "Message.\nMore message."),
+    ErrorExpectation(line: 12, column: 34, length: 56, message: "Message."),
+  ]);
+
+  // Must have either a code or a message.
+  expectFormatError("""
+int i = "s";
+/\/      ^^^
+
+var wrong;
+""");
+
+  // Location must follow some real code.
+  expectFormatError("""
+/\/ [error line 123, column 45, length 678]
+/\/ [analyzer] CompileTimeErrorCode.FIRST
+/\/ ^^^
+/\/ [cfe] This doesn't make sense.
+""");
+
+  // Location at end without code or message.
+  expectFormatError("""
+int i = "s";
+/\/ ^^^
+""");
+
+  // Code cannot follow message.
+  expectFormatError("""
+int i = "s";
+/\/      ^^^
+/\/ [cfe] Error message.
+/\/ [analyzer] ErrorCode.BAD_THING
+""");
+
+  // Analyzer error must look like an error code.
+  expectFormatError("""
+int i = "s";
+/\/      ^^^
+/\/ [analyzer] Not error code.
+""");
+}
+
+void testName() {
+  // Immediately inside suite.
+  var file = TestFile.parse(Path("suite").absolute,
+      Path("suite/a_test.dart").absolute.toNativePath(), "");
+  Expect.equals("a_test", file.name);
+
+  // Inside subdirectory.
+  file = TestFile.parse(Path("suite").absolute,
+      Path("suite/a/b/c_test.dart").absolute.toNativePath(), "");
+  Expect.equals("a/b/c_test", file.name);
+
+  // Multitest.
+  file = file.split(Path("suite/a/b/c_test_00.dart").absolute, "00", "");
+  Expect.equals("a/b/c_test/00", file.name);
+}
+
+void testMultitest() {
+  var file = parse("", path: "origin.dart");
+  Expect.isFalse(file.hasSyntaxError);
+  Expect.isFalse(file.hasCompileError);
+  Expect.isFalse(file.hasRuntimeError);
+  Expect.isFalse(file.hasStaticWarning);
+
+  var a = file.split(Path("a.dart").absolute, "a", "", hasSyntaxError: true);
+  Expect.isTrue(a.originPath.toNativePath().endsWith("origin.dart"));
+  Expect.isTrue(a.path.toNativePath().endsWith("a.dart"));
+  Expect.isTrue(a.hasSyntaxError);
+  Expect.isFalse(a.hasCompileError);
+  Expect.isFalse(a.hasRuntimeError);
+  Expect.isFalse(a.hasStaticWarning);
+
+  var b = file.split(
+    Path("b.dart").absolute,
+    "b",
+    "",
+    hasCompileError: true,
+  );
+  Expect.isTrue(b.originPath.toNativePath().endsWith("origin.dart"));
+  Expect.isTrue(b.path.toNativePath().endsWith("b.dart"));
+  Expect.isFalse(b.hasSyntaxError);
+  Expect.isTrue(b.hasCompileError);
+  Expect.isFalse(b.hasRuntimeError);
+  Expect.isFalse(b.hasStaticWarning);
+
+  var c = file.split(Path("c.dart").absolute, "c", "", hasRuntimeError: true);
+  Expect.isTrue(c.originPath.toNativePath().endsWith("origin.dart"));
+  Expect.isTrue(c.path.toNativePath().endsWith("c.dart"));
+  Expect.isFalse(c.hasSyntaxError);
+  Expect.isFalse(c.hasCompileError);
+  Expect.isTrue(c.hasRuntimeError);
+  Expect.isFalse(c.hasStaticWarning);
+
+  var d = file.split(Path("d.dart").absolute, "d", "", hasStaticWarning: true);
+  Expect.isTrue(d.originPath.toNativePath().endsWith("origin.dart"));
+  Expect.isTrue(d.path.toNativePath().endsWith("d.dart"));
+  Expect.isFalse(d.hasSyntaxError);
+  Expect.isFalse(d.hasCompileError);
+  Expect.isFalse(d.hasRuntimeError);
+  Expect.isTrue(d.hasStaticWarning);
+}
+
+void expectParseErrorExpectations(
+    String source, List<ErrorExpectation> errors) {
+  var file = parse(source);
+  Expect.listEquals(errors.map((error) => error.toString()).toList(),
+      file.expectedErrors.map((error) => error.toString()).toList());
+}
+
+void expectFormatError(String source) {
+  Expect.throwsFormatException(() => parse(source));
+}
+
+void expectParseThrows(String source) {
+  Expect.throws(() => parse(source));
+}
+
+TestFile parse(String source, {String path = "some_test.dart"}) {
+  path = Path(path).absolute.toNativePath();
+  var suiteDirectory = Path(path).directoryPath;
+  return TestFile.parse(suiteDirectory, path, source);
+}
diff --git a/pkg/testing/lib/src/run_tests.dart b/pkg/testing/lib/src/run_tests.dart
index ce0849d..5d6e27d 100644
--- a/pkg/testing/lib/src/run_tests.dart
+++ b/pkg/testing/lib/src/run_tests.dart
@@ -82,6 +82,12 @@
     String configurationPath;
     if (configurationPaths.length == 1) {
       configurationPath = configurationPaths.single;
+      File file = new File(configurationPath);
+      if (await file.exists()) {
+        // If [configurationPath] exists as a file, use the absolute URI. This
+        // handles absolute paths on Windows.
+        configurationPath = file.absolute.uri.toString();
+      }
     } else {
       configurationPath = "testing.json";
       if (!await new File(configurationPath).exists()) {
diff --git a/pkg/testing/lib/src/test_dart/status_file_parser.dart b/pkg/testing/lib/src/test_dart/status_file_parser.dart
index c756341..60c39f8 100644
--- a/pkg/testing/lib/src/test_dart/status_file_parser.dart
+++ b/pkg/testing/lib/src/test_dart/status_file_parser.dart
@@ -82,8 +82,11 @@
     throw new Exception('Cannot find test status file $path');
   }
   int lineNumber = 0;
-  Stream<String> lines =
-      file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+  Stream<String> lines = file
+      .openRead()
+      .cast<List<int>>()
+      .transform(utf8.decoder)
+      .transform(new LineSplitter());
 
   Section currentSection = new Section.always(statusFile, -1);
   sections.add(currentSection);
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index fc07655..9d6e345 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -34,6 +34,7 @@
 import 'package:kernel/kernel.dart' show Component, Procedure;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:vm/bytecode/options.dart' show BytecodeOptions;
 import 'package:vm/incremental_compiler.dart';
 import 'package:vm/kernel_front_end.dart' show runWithFrontEndCompilerContext;
 import 'package:vm/http_filesystem.dart';
@@ -147,11 +148,16 @@
         await runWithFrontEndCompilerContext(script, options, component, () {
           // TODO(alexmarkov): disable source positions, local variables info
           //  and source files in VM PRODUCT mode.
+          // TODO(alexmarkov): disable asserts if they are not enabled in VM.
+          // TODO(rmacnak): disable annotations if mirrors are not enabled.
           generateBytecode(component,
-              environmentDefines: options.environmentDefines,
-              emitSourcePositions: true,
-              emitLocalVarInfo: true,
-              emitSourceFiles: true);
+              options: new BytecodeOptions(
+                  enableAsserts: true,
+                  environmentDefines: options.environmentDefines,
+                  emitSourcePositions: true,
+                  emitLocalVarInfo: true,
+                  emitSourceFiles: true,
+                  emitAnnotations: true));
         });
       }
 
@@ -528,7 +534,12 @@
     assert(incremental,
         "Incremental compiler required for use of 'kUpdateSourcesTag'");
     compiler = lookupIncrementalCompiler(isolateId);
-    assert(compiler != null);
+    if (compiler == null) {
+      port.send(new CompilationResult.errors(
+              ["No incremental compiler available for this isolate."], null)
+          .toResponse());
+      return;
+    }
     updateSources(compiler, sourceFiles);
     port.send(new CompilationResult.ok(null).toResponse());
     return;
diff --git a/pkg/vm/bin/run_binary_size_analysis.dart b/pkg/vm/bin/run_binary_size_analysis.dart
index 4a63676..4c4c9cf 100644
--- a/pkg/vm/bin/run_binary_size_analysis.dart
+++ b/pkg/vm/bin/run_binary_size_analysis.dart
@@ -39,6 +39,7 @@
   // a tree.
   final symbols = await input
       .openRead()
+      .cast<List<int>>()
       .transform(utf8.decoder)
       .transform(json.decoder)
       .first;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index 387db94..a43e1c1 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -79,6 +79,12 @@
     }
   }
 
+  void emitYieldPointSourcePosition() {
+    if (!isUnreachable) {
+      sourcePositions.addYieldPoint(offset, currentSourcePosition);
+    }
+  }
+
   void _emitByte(int abyte) {
     assert(_isUint8(abyte));
     bytecode.add(abyte);
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 244e800..aa73fc3 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,135 +10,94 @@
 /// Before bumping current bytecode version format, make sure that
 /// all users have switched to a VM which is able to consume new
 /// version of bytecode.
-const int currentBytecodeFormatVersion = 10;
-
-/// Version of experimental / bleeding edge bytecode format.
-/// Produced by bytecode generator when --use-future-bytecode-format
-/// option is enabled.
-const int futureBytecodeFormatVersion = currentBytecodeFormatVersion + 1;
+const int currentBytecodeFormatVersion = 12;
 
 enum Opcode {
-  // Old instructions, used before bytecode v7.
-  // TODO(alexmarkov): remove
-
-  kTrap_Old,
-
-  // Prologue and stack management.
-  kEntry_Old,
-  kEntryFixed_Old,
-  kEntryOptional_Old,
-  kLoadConstant_Old,
-  kFrame_Old,
-  kCheckFunctionTypeArgs_Old,
-  kCheckStack_Old,
-
-  // Object allocation.
-  kAllocate_Old,
-  kAllocateT_Old,
-  kCreateArrayTOS_Old,
-
-  // Context allocation and access.
-  kAllocateContext_Old,
-  kCloneContext_Old,
-  kLoadContextParent_Old,
-  kStoreContextParent_Old,
-  kLoadContextVar_Old,
-  kStoreContextVar_Old,
-
-  // Constants.
-  kPushConstant_Old,
-  kPushNull_Old,
-  kPushTrue_Old,
-  kPushFalse_Old,
-  kPushInt_Old,
-
-  // Locals and expression stack.
-  kDrop1_Old,
-  kPush_Old,
-  kPopLocal_Old,
-  kStoreLocal_Old,
-
-  // Instance fields and arrays.
-  kLoadFieldTOS_Old,
-  kStoreFieldTOS_Old,
-  kStoreIndexedTOS_Old,
-
-  // Static fields.
-  kPushStatic_Old,
-  kStoreStaticTOS_Old,
-
-  // Jumps.
-  kJump_Old,
-  kJumpIfNoAsserts_Old,
-  kJumpIfNotZeroTypeArgs_Old,
-  kJumpIfEqStrict_Old,
-  kJumpIfNeStrict_Old,
-  kJumpIfTrue_Old,
-  kJumpIfFalse_Old,
-  kJumpIfNull_Old,
-  kJumpIfNotNull_Old,
-
-  // Calls.
-  kUnused00_Old,
-  kInterfaceCall_Old,
-  kDynamicCall_Old,
-  kNativeCall_Old,
-  kReturnTOS_Old,
-
-  // Types and type checks.
-  kAssertAssignable_Old,
-  kAssertBoolean_Old,
-  kAssertSubtype_Old,
-  kLoadTypeArgumentsField_Old,
-  kInstantiateType_Old,
-  kInstantiateTypeArgumentsTOS_Old,
-
-  // Exception handling.
-  kThrow_Old,
-  kMoveSpecial_Old,
-  kSetFrame_Old,
-
-  // Bool operations.
-  kBooleanNegateTOS_Old,
-
-  // Null operations.
-  kEqualsNull_Old,
-
-  // Int operations.
-  kNegateInt_Old,
-  kAddInt_Old,
-  kSubInt_Old,
-  kMulInt_Old,
-  kTruncDivInt_Old,
-  kModInt_Old,
-  kBitAndInt_Old,
-  kBitOrInt_Old,
-  kBitXorInt_Old,
-  kShlInt_Old,
-  kShrInt_Old,
-  kCompareIntEq_Old,
-  kCompareIntGt_Old,
-  kCompareIntLt_Old,
-  kCompareIntGe_Old,
-  kCompareIntLe_Old,
-
-  kDirectCall_Old,
-
-  kAllocateClosure_Old,
-
-  kUncheckedInterfaceCall_Old,
-
-  // Double operations.
-  kNegateDouble_Old,
-  kAddDouble_Old,
-  kSubDouble_Old,
-  kMulDouble_Old,
-  kDivDouble_Old,
-  kCompareDoubleEq_Old,
-  kCompareDoubleGt_Old,
-  kCompareDoubleLt_Old,
-  kCompareDoubleGe_Old,
-  kCompareDoubleLe_Old,
+  kUnusedOpcode000,
+  kUnusedOpcode001,
+  kUnusedOpcode002,
+  kUnusedOpcode003,
+  kUnusedOpcode004,
+  kUnusedOpcode005,
+  kUnusedOpcode006,
+  kUnusedOpcode007,
+  kUnusedOpcode008,
+  kUnusedOpcode009,
+  kUnusedOpcode010,
+  kUnusedOpcode011,
+  kUnusedOpcode012,
+  kUnusedOpcode013,
+  kUnusedOpcode014,
+  kUnusedOpcode015,
+  kUnusedOpcode016,
+  kUnusedOpcode017,
+  kUnusedOpcode018,
+  kUnusedOpcode019,
+  kUnusedOpcode020,
+  kUnusedOpcode021,
+  kUnusedOpcode022,
+  kUnusedOpcode023,
+  kUnusedOpcode024,
+  kUnusedOpcode025,
+  kUnusedOpcode026,
+  kUnusedOpcode027,
+  kUnusedOpcode028,
+  kUnusedOpcode029,
+  kUnusedOpcode030,
+  kUnusedOpcode031,
+  kUnusedOpcode032,
+  kUnusedOpcode033,
+  kUnusedOpcode034,
+  kUnusedOpcode035,
+  kUnusedOpcode036,
+  kUnusedOpcode037,
+  kUnusedOpcode038,
+  kUnusedOpcode039,
+  kUnusedOpcode040,
+  kUnusedOpcode041,
+  kUnusedOpcode042,
+  kUnusedOpcode043,
+  kUnusedOpcode044,
+  kUnusedOpcode045,
+  kUnusedOpcode046,
+  kUnusedOpcode047,
+  kUnusedOpcode048,
+  kUnusedOpcode049,
+  kUnusedOpcode050,
+  kUnusedOpcode051,
+  kUnusedOpcode052,
+  kUnusedOpcode053,
+  kUnusedOpcode054,
+  kUnusedOpcode055,
+  kUnusedOpcode056,
+  kUnusedOpcode057,
+  kUnusedOpcode058,
+  kUnusedOpcode059,
+  kUnusedOpcode060,
+  kUnusedOpcode061,
+  kUnusedOpcode062,
+  kUnusedOpcode063,
+  kUnusedOpcode064,
+  kUnusedOpcode065,
+  kUnusedOpcode066,
+  kUnusedOpcode067,
+  kUnusedOpcode068,
+  kUnusedOpcode069,
+  kUnusedOpcode070,
+  kUnusedOpcode071,
+  kUnusedOpcode072,
+  kUnusedOpcode073,
+  kUnusedOpcode074,
+  kUnusedOpcode075,
+  kUnusedOpcode076,
+  kUnusedOpcode077,
+  kUnusedOpcode078,
+  kUnusedOpcode079,
+  kUnusedOpcode080,
+  kUnusedOpcode081,
+  kUnusedOpcode082,
+  kUnusedOpcode083,
+  kUnusedOpcode084,
 
   // Bytecode instructions since bytecode format v7:
 
@@ -686,6 +645,9 @@
 // Context IDs are referenced using 8-bit unsigned operands.
 const int contextIdLimit = 1 << 8;
 
+// Number of arguments is encoded as 8-bit unsigned operand.
+const int argumentsLimit = 1 << 8;
+
 // Base class for exceptions thrown when certain limit of bytecode
 // format is exceeded.
 abstract class BytecodeLimitExceededException {}
diff --git a/pkg/vm/lib/bytecode/declarations.dart b/pkg/vm/lib/bytecode/declarations.dart
index 58827b6..bd14856 100644
--- a/pkg/vm/lib/bytecode/declarations.dart
+++ b/pkg/vm/lib/bytecode/declarations.dart
@@ -8,8 +8,7 @@
 import 'bytecode_serialization.dart'
     show BufferedWriter, BufferedReader, BytecodeSizeStatistics, StringTable;
 import 'constant_pool.dart' show ConstantPool;
-import 'dbc.dart'
-    show currentBytecodeFormatVersion, futureBytecodeFormatVersion;
+import 'dbc.dart' show currentBytecodeFormatVersion;
 import 'disassembler.dart' show BytecodeDisassembler;
 import 'exceptions.dart' show ExceptionsTable;
 import 'local_variable_table.dart' show LocalVariableTable;
@@ -19,21 +18,26 @@
 class LibraryDeclaration {
   static const usesDartMirrorsFlag = 1 << 0;
   static const usesDartFfiFlag = 1 << 1;
+  static const hasExtensionsFlag = 1 << 2;
 
   ObjectHandle importUri;
   final int flags;
   final ObjectHandle name;
   final ObjectHandle script;
+  final List<ObjectHandle> extensionUris;
   final List<ClassDeclaration> classes;
 
-  LibraryDeclaration(
-      this.importUri, this.flags, this.name, this.script, this.classes);
+  LibraryDeclaration(this.importUri, this.flags, this.name, this.script,
+      this.extensionUris, this.classes);
 
   void write(BufferedWriter writer) {
     final start = writer.offset;
     writer.writePackedUInt30(flags);
     writer.writePackedObject(name);
     writer.writePackedObject(script);
+    if ((flags & hasExtensionsFlag) != 0) {
+      writer.writePackedList(extensionUris);
+    }
     writer.writePackedUInt30(classes.length);
     for (var cls in classes) {
       writer.writePackedObject(cls.name);
@@ -51,7 +55,11 @@
       final className = reader.readPackedObject();
       return reader.readLinkOffset<ClassDeclaration>()..name = className;
     });
-    return new LibraryDeclaration(null, flags, name, script, classes);
+    final extensionUris = ((flags & hasExtensionsFlag) != 0)
+        ? reader.readPackedList<ObjectHandle>()
+        : const <ObjectHandle>[];
+    return new LibraryDeclaration(
+        null, flags, name, script, extensionUris, classes);
   }
 
   @override
@@ -66,6 +74,9 @@
     if ((flags & usesDartFfiFlag) != 0) {
       sb.writeln('    uses dart:ffi');
     }
+    if ((flags & hasExtensionsFlag) != 0) {
+      sb.writeln('    extensions: $extensionUris');
+    }
     sb.writeln();
     for (var cls in classes) {
       sb.write(cls);
@@ -749,7 +760,7 @@
 
   bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
   bool get hasSourcePositions =>
-      sourcePositions != null && sourcePositions.mapping.isNotEmpty;
+      sourcePositions != null && sourcePositions.isNotEmpty;
   bool get hasLocalVariables =>
       localVariables != null && localVariables.isNotEmpty;
   bool get hasNullableFields => nullableFields.isNotEmpty;
@@ -890,7 +901,11 @@
   static const int hasOptionalNamedParamsFlag = 1 << 1;
   static const int hasTypeParamsFlag = 1 << 2;
   static const int hasSourcePositionsFlag = 1 << 3;
+  static const int isAsyncFlag = 1 << 4;
+  static const int isAsyncStarFlag = 1 << 5;
+  static const int isSyncStarFlag = 1 << 6;
 
+  final int flags;
   final ObjectHandle parent;
   final ObjectHandle name;
   final int position;
@@ -903,6 +918,7 @@
   ClosureCode code;
 
   ClosureDeclaration(
+      this.flags,
       this.parent,
       this.name,
       this.position,
@@ -914,20 +930,6 @@
       this.returnType);
 
   void write(BufferedWriter writer) {
-    int flags = 0;
-    if (numRequiredParams != parameters.length) {
-      if (numNamedParams > 0) {
-        flags |= hasOptionalNamedParamsFlag;
-      } else {
-        flags |= hasOptionalPositionalParamsFlag;
-      }
-    }
-    if (typeParams.isNotEmpty) {
-      flags |= hasTypeParamsFlag;
-    }
-    if (position != TreeNode.noOffset) {
-      flags |= hasSourcePositionsFlag;
-    }
     writer.writePackedUInt30(flags);
     writer.writePackedObject(parent);
     writer.writePackedObject(name);
@@ -996,7 +998,7 @@
         (_) => new NameAndType(
             reader.readPackedObject(), reader.readPackedObject()));
     final returnType = reader.readPackedObject();
-    return new ClosureDeclaration(parent, name, position, endPosition,
+    return new ClosureDeclaration(flags, parent, name, position, endPosition,
         typeParams, numRequiredParams, numNamedParams, parameters, returnType);
   }
 
@@ -1004,6 +1006,15 @@
   String toString() {
     final StringBuffer sb = new StringBuffer();
     sb.write('Closure $parent::$name');
+    if ((flags & isAsyncFlag) != 0) {
+      sb.write(' async');
+    }
+    if ((flags & isAsyncStarFlag) != 0) {
+      sb.write(' async*');
+    }
+    if ((flags & isSyncStarFlag) != 0) {
+      sb.write(' sync*');
+    }
     if (position != TreeNode.noOffset) {
       sb.write(' pos = $position, end-pos = $endPosition');
     }
@@ -1045,7 +1056,7 @@
 
   bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
   bool get hasSourcePositions =>
-      sourcePositions != null && sourcePositions.mapping.isNotEmpty;
+      sourcePositions != null && sourcePositions.isNotEmpty;
   bool get hasLocalVariables =>
       localVariables != null && localVariables.isNotEmpty;
 
@@ -1440,8 +1451,6 @@
     sb.write("Bytecode (version: ");
     if (version == currentBytecodeFormatVersion) {
       sb.write("stable");
-    } else if (version == futureBytecodeFormatVersion) {
-      sb.write("future");
     } else {
       sb.write("v$version");
     }
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 01426c5..3684410 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -9,13 +9,19 @@
 import 'package:front_end/src/api_prototype/constant_evaluator.dart'
     show ConstantEvaluator, EvaluationEnvironment, ErrorReporter;
 import 'package:front_end/src/api_unstable/vm.dart'
-    show CompilerContext, Severity, templateIllegalRecursiveType;
+    show
+        CompilerContext,
+        Severity,
+        messageBytecodeLimitExceededTooManyArguments,
+        noLength,
+        templateIllegalRecursiveType;
 
 import 'package:kernel/ast.dart' hide MapEntry, Component, FunctionDeclaration;
 import 'package:kernel/ast.dart' as ast show Component, FunctionDeclaration;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/external_name.dart' show getExternalName;
+import 'package:kernel/external_name.dart'
+    show getExternalName, getNativeExtensionUris;
 import 'package:kernel/library_index.dart' show LibraryIndex;
 import 'package:kernel/target/targets.dart' show ConstantsBackend;
 import 'package:kernel/type_algebra.dart'
@@ -42,6 +48,7 @@
 import 'nullability_detector.dart' show NullabilityDetector;
 import 'object_table.dart'
     show ObjectHandle, ObjectTable, NameAndType, topLevelClassName;
+import 'options.dart' show BytecodeOptions;
 import 'recognized_methods.dart' show RecognizedMethods;
 import 'recursive_types_validator.dart' show IllegalRecursiveTypeException;
 import 'source_positions.dart' show LineStarts, SourcePositions;
@@ -58,18 +65,12 @@
 
 void generateBytecode(
   ast.Component component, {
-  bool enableAsserts: true,
-  bool emitSourcePositions: false,
-  bool emitSourceFiles: false,
-  bool emitLocalVarInfo: false,
-  bool emitAnnotations: false,
-  bool omitAssertSourcePositions: false,
-  bool useFutureBytecodeFormat: false,
-  Map<String, String> environmentDefines: const <String, String>{},
+  BytecodeOptions options,
   ErrorReporter errorReporter,
   List<Library> libraries,
   ClassHierarchy hierarchy,
 }) {
+  options ??= new BytecodeOptions();
   verifyBytecodeInstructionDeclarations();
   final coreTypes = new CoreTypes(component);
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
@@ -80,21 +81,8 @@
   final errorReporter = new ForwardConstantEvaluationErrors();
   libraries ??= component.libraries;
   try {
-    final bytecodeGenerator = new BytecodeGenerator(
-        component,
-        coreTypes,
-        hierarchy,
-        typeEnvironment,
-        constantsBackend,
-        environmentDefines,
-        enableAsserts,
-        emitSourcePositions,
-        emitSourceFiles,
-        emitLocalVarInfo,
-        emitAnnotations,
-        omitAssertSourcePositions,
-        useFutureBytecodeFormat,
-        errorReporter);
+    final bytecodeGenerator = new BytecodeGenerator(component, coreTypes,
+        hierarchy, typeEnvironment, constantsBackend, options, errorReporter);
     for (var library in libraries) {
       bytecodeGenerator.visitLibrary(library);
     }
@@ -110,14 +98,7 @@
   final ClassHierarchy hierarchy;
   final TypeEnvironment typeEnvironment;
   final ConstantsBackend constantsBackend;
-  final Map<String, String> environmentDefines;
-  final bool enableAsserts;
-  final bool emitSourcePositions;
-  final bool emitSourceFiles;
-  final bool emitLocalVarInfo;
-  final bool emitAnnotations;
-  final bool omitAssertSourcePositions;
-  final bool useFutureBytecodeFormat;
+  final BytecodeOptions options;
   final ErrorReporter errorReporter;
   final BytecodeMetadataRepository metadata = new BytecodeMetadataRepository();
   final RecognizedMethods recognizedMethods;
@@ -165,19 +146,10 @@
       this.hierarchy,
       this.typeEnvironment,
       this.constantsBackend,
-      this.environmentDefines,
-      this.enableAsserts,
-      this.emitSourcePositions,
-      this.emitSourceFiles,
-      this.emitLocalVarInfo,
-      this.emitAnnotations,
-      this.omitAssertSourcePositions,
-      this.useFutureBytecodeFormat,
+      this.options,
       this.errorReporter)
       : recognizedMethods = new RecognizedMethods(typeEnvironment),
-        formatVersion = useFutureBytecodeFormat
-            ? futureBytecodeFormatVersion
-            : currentBytecodeFormatVersion,
+        formatVersion = currentBytecodeFormatVersion,
         astUriToSource = component.uriToSource {
     nullabilityDetector = new NullabilityDetector(recognizedMethods);
     component.addMetadataRepository(metadata);
@@ -243,7 +215,8 @@
 
   ObjectHandle getScript(Uri uri, bool includeSource) {
     SourceFile source;
-    if (includeSource && (emitSourceFiles || emitSourcePositions)) {
+    if (includeSource &&
+        (options.emitSourceFiles || options.emitSourcePositions)) {
       source = bytecodeComponent.uriToSource[uri];
       if (source == null) {
         final astSource = astUriToSource[uri];
@@ -251,12 +224,12 @@
           final importUri =
               objectTable.getNameHandle(null, astSource.importUri.toString());
           LineStarts lineStarts;
-          if (emitSourcePositions) {
+          if (options.emitSourcePositions) {
             lineStarts = new LineStarts(astSource.lineStarts);
             bytecodeComponent.lineStarts.add(lineStarts);
           }
           String text = '';
-          if (emitSourceFiles) {
+          if (options.emitSourceFiles) {
             text = astSource.cachedText ??
                 utf8.decode(astSource.source, allowMalformed: true);
           }
@@ -285,7 +258,14 @@
     }
     final name = objectTable.getNameHandle(null, library.name ?? '');
     final script = getScript(library.fileUri, true);
-    return new LibraryDeclaration(importUri, flags, name, script, classes);
+    final extensionUris = getNativeExtensionUris(library)
+        .map((String uri) => objectTable.getNameHandle(null, uri))
+        .toList();
+    if (extensionUris.isNotEmpty) {
+      flags |= LibraryDeclaration.hasExtensionsFlag;
+    }
+    return new LibraryDeclaration(
+        importUri, flags, name, script, extensionUris, classes);
   }
 
   ClassDeclaration getClassDeclaration(Class cls, Members members) {
@@ -317,9 +297,9 @@
     }
     int position = TreeNode.noOffset;
     int endPosition = TreeNode.noOffset;
-    if (emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
+    if (options.emitSourcePositions && cls.fileOffset != TreeNode.noOffset) {
       flags |= ClassDeclaration.hasSourcePositionsFlag;
-      position = cls.fileOffset;
+      position = cls.startFileOffset;
       endPosition = cls.fileEndOffset;
     }
     Annotations annotations = getAnnotations(cls.annotations);
@@ -357,7 +337,8 @@
       Library library, Members members) {
     int flags = 0;
     int position = TreeNode.noOffset;
-    if (emitSourcePositions && library.fileOffset != TreeNode.noOffset) {
+    if (options.emitSourcePositions &&
+        library.fileOffset != TreeNode.noOffset) {
       flags |= ClassDeclaration.hasSourcePositionsFlag;
       position = library.fileOffset;
     }
@@ -398,14 +379,18 @@
     }
     final savedConstantEvaluator = constantEvaluator;
     if (constantEvaluator == null) {
-      constantEvaluator = new ConstantEvaluator(constantsBackend,
-          environmentDefines, typeEnvironment, enableAsserts, errorReporter)
+      constantEvaluator = new ConstantEvaluator(
+          constantsBackend,
+          options.environmentDefines,
+          typeEnvironment,
+          options.enableAsserts,
+          errorReporter)
         ..env = new EvaluationEnvironment();
     }
     List<Constant> constants = nodes.map(_evaluateConstantExpression).toList();
     constantEvaluator = savedConstantEvaluator;
     bool hasPragma = constants.any(_isPragma);
-    if (!emitAnnotations) {
+    if (!options.emitAnnotations) {
       if (hasPragma) {
         constants = constants.where(_isPragma).toList();
       } else {
@@ -463,7 +448,7 @@
     }
     int position = TreeNode.noOffset;
     int endPosition = TreeNode.noOffset;
-    if (emitSourcePositions && field.fileOffset != TreeNode.noOffset) {
+    if (options.emitSourcePositions && field.fileOffset != TreeNode.noOffset) {
       flags |= FieldDeclaration.hasSourcePositionsFlag;
       position = field.fileOffset;
       endPosition = field.fileEndOffset;
@@ -475,16 +460,20 @@
         flags |= FieldDeclaration.hasPragmaFlag;
       }
     }
-    if (field.fileUri != (field.parent as dynamic).fileUri) {
-      // TODO(alexmarkov): support custom scripts
-      // flags |= FieldDeclaration.hasCustomScriptFlag;
+    ObjectHandle script;
+    if (field.fileUri != null &&
+        field.fileUri != (field.parent as FileUriNode).fileUri) {
+      final isInAnonymousMixin =
+          enclosingClass != null && enclosingClass.isAnonymousMixin;
+      script = getScript(field.fileUri, !isInAnonymousMixin);
+      flags |= FieldDeclaration.hasCustomScriptFlag;
     }
     return new FieldDeclaration(
         flags,
         name,
         objectTable.getHandle(field.type),
         objectTable.getHandle(value),
-        null, // TODO(alexmarkov): script
+        script,
         position,
         endPosition,
         getterName,
@@ -567,9 +556,9 @@
     }
     int position = TreeNode.noOffset;
     int endPosition = TreeNode.noOffset;
-    if (emitSourcePositions && member.fileOffset != TreeNode.noOffset) {
+    if (options.emitSourcePositions && member.fileOffset != TreeNode.noOffset) {
       flags |= FunctionDeclaration.hasSourcePositionsFlag;
-      position = member.fileOffset;
+      position = (member as dynamic).startFileOffset;
       endPosition = member.fileEndOffset;
     }
     Annotations annotations = getAnnotations(member.annotations);
@@ -579,9 +568,15 @@
         flags |= FunctionDeclaration.hasPragmaFlag;
       }
     }
-    if (member.fileUri != (member.parent as dynamic).fileUri) {
-      // TODO(alexmarkov): support custom scripts
-      // flags |= FunctionDeclaration.hasCustomScriptFlag;
+    ObjectHandle script;
+    if (member.fileUri != null &&
+        member.fileUri != (member.parent as FileUriNode).fileUri) {
+      final isInAnonymousMixin =
+          enclosingClass != null && enclosingClass.isAnonymousMixin;
+      final isSynthetic = member is Procedure &&
+          (member.isNoSuchMethodForwarder || member.isSyntheticForwarder);
+      script = getScript(member.fileUri, !isInAnonymousMixin && !isSynthetic);
+      flags |= FunctionDeclaration.hasCustomScriptFlag;
     }
 
     final name = objectTable.getNameHandle(member.name.library,
@@ -595,7 +590,7 @@
     return new FunctionDeclaration(
         flags,
         name,
-        null, // TODO(alexmarkov): script
+        script,
         position,
         endPosition,
         typeParameters,
@@ -713,15 +708,20 @@
             // BytecodeAssembler eliminates this bytecode if it is unreachable.
             asm.emitPushNull();
           }
+          if (node.function != null) {
+            _recordSourcePosition(node.function.fileEndOffset);
+          }
           _genReturnTOS();
         }
       } else {
         throw 'Unexpected member ${node.runtimeType} $node';
       }
       end(node, hasCode);
-    } on BytecodeLimitExceededException {
-      // Do not generate bytecode and fall back to using kernel AST.
-      // TODO(alexmarkov): issue compile-time error
+    } on TooManyArgumentsException catch (e) {
+      CompilerContext.current.options.report(
+          messageBytecodeLimitExceededTooManyArguments.withLocation(
+              node.fileUri, e.fileOffset, noLength),
+          Severity.error);
       hasErrors = true;
       end(node, false);
     }
@@ -852,12 +852,21 @@
       _asyncAwaitCompleterGetFuture ??= libraryIndex.getMember(
           'dart:async', '_AsyncAwaitCompleter', 'get:future');
 
+  Procedure _setAsyncThreadStackTrace;
+  Procedure get setAsyncThreadStackTrace => _setAsyncThreadStackTrace ??=
+      libraryIndex.getTopLevelMember('dart:async', '_setAsyncThreadStackTrace');
+
+  Procedure _clearAsyncThreadStackTrace;
+  Procedure get clearAsyncThreadStackTrace =>
+      _clearAsyncThreadStackTrace ??= libraryIndex.getTopLevelMember(
+          'dart:async', '_clearAsyncThreadStackTrace');
+
   Library _dartFfiLibrary;
   Library get dartFfiLibrary =>
       _dartFfiLibrary ??= libraryIndex.tryGetLibrary('dart:ffi');
 
   void _recordSourcePosition(int fileOffset) {
-    if (emitSourcePositions) {
+    if (options.emitSourcePositions) {
       asm.currentSourcePosition = fileOffset;
     }
     maxSourcePosition = math.max(maxSourcePosition, fileOffset);
@@ -976,22 +985,34 @@
   }
 
   void _genReturnTOS() {
+    if (options.causalAsyncStacks &&
+        parentFunction != null &&
+        (parentFunction.dartAsyncMarker == AsyncMarker.Async ||
+            parentFunction.dartAsyncMarker == AsyncMarker.AsyncStar)) {
+      _genDirectCall(
+          clearAsyncThreadStackTrace, objectTable.getArgDescHandle(0), 0);
+      asm.emitDrop1();
+    }
+
     asm.emitReturnTOS();
   }
 
   void _genDirectCall(Member target, ObjectHandle argDesc, int totalArgCount,
-      {bool isGet: false, bool isSet: false}) {
+      {bool isGet: false, bool isSet: false, TreeNode context}) {
     assert(!isGet || !isSet);
     final kind = isGet
         ? InvocationKind.getter
         : (isSet ? InvocationKind.setter : InvocationKind.method);
     final cpIndex = cp.addDirectCall(kind, target, argDesc);
 
+    if (totalArgCount >= argumentsLimit) {
+      throw new TooManyArgumentsException(context.fileOffset);
+    }
     asm.emitDirectCall(cpIndex, totalArgCount);
   }
 
   void _genDirectCallWithArgs(Member target, Arguments args,
-      {bool hasReceiver: false, bool isFactory: false}) {
+      {bool hasReceiver: false, bool isFactory: false, TreeNode context}) {
     final argDesc = objectTable.getArgDescHandleByArguments(args,
         hasReceiver: hasReceiver, isFactory: isFactory);
 
@@ -1005,7 +1026,7 @@
       totalArgCount++;
     }
 
-    _genDirectCall(target, argDesc, totalArgCount);
+    _genDirectCall(target, argDesc, totalArgCount, context: context);
   }
 
   void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
@@ -1321,8 +1342,12 @@
       functionTypeParametersSet = functionTypeParameters.toSet();
     }
     // TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
-    constantEvaluator = new ConstantEvaluator(constantsBackend,
-        environmentDefines, typeEnvironment, enableAsserts, errorReporter)
+    constantEvaluator = new ConstantEvaluator(
+        constantsBackend,
+        options.environmentDefines,
+        typeEnvironment,
+        options.enableAsserts,
+        errorReporter)
       ..env = new EvaluationEnvironment();
 
     if (node.isAbstract || node is Field && !hasInitializerCode(node)) {
@@ -1345,11 +1370,19 @@
     savedMaxSourcePositions = <int>[];
     maxSourcePosition = node.fileOffset;
 
-    locals = new LocalVariables(node, enableAsserts);
+    locals = new LocalVariables(node, options);
     locals.enterScope(node);
     assert(!locals.isSyncYieldingFrame);
 
-    _recordSourcePosition(node.fileOffset);
+    int position;
+    if (node is Procedure) {
+      position = node.startFileOffset;
+    } else if (node is Constructor) {
+      position = node.startFileOffset;
+    } else {
+      position = node.fileOffset;
+    }
+    _recordSourcePosition(position);
     _genPrologue(node, node.function);
     _setupInitialContext(node.function);
     if (node is Procedure && node.isInstanceMember) {
@@ -1381,7 +1414,7 @@
     if (!hasErrors) {
       Code code;
       if (hasCode) {
-        if (emitLocalVarInfo && node.function != null) {
+        if (options.emitLocalVarInfo && node.function != null) {
           // Leave the scope which was entered in _setupInitialContext.
           asm.localVariableTable
               .leaveScope(asm.offset, node.function.fileEndOffset);
@@ -1452,7 +1485,7 @@
   }
 
   SourcePositions finalizeSourcePositions() {
-    if (asm.sourcePositions.mapping.isEmpty) {
+    if (asm.sourcePositions.isEmpty) {
       return null;
     }
     bytecodeComponent.sourcePositions.add(asm.sourcePositions);
@@ -1593,7 +1626,7 @@
   void _setupInitialContext(FunctionNode function) {
     _allocateContextIfNeeded();
 
-    if (emitLocalVarInfo && function != null) {
+    if (options.emitLocalVarInfo && function != null) {
       // Open scope after allocating context.
       asm.localVariableTable.enterScope(
           asm.offset, locals.currentContextLevel, function.fileOffset);
@@ -1852,7 +1885,8 @@
     }
   }
 
-  int _genClosureBytecode(TreeNode node, String name, FunctionNode function) {
+  int _genClosureBytecode(
+      LocalFunction node, String name, FunctionNode function) {
     _pushAssemblerState();
 
     locals.enterScope(node);
@@ -1865,15 +1899,6 @@
     final savedLoopDepth = currentLoopDepth;
     currentLoopDepth = 0;
 
-    int position = TreeNode.noOffset;
-    int endPosition = TreeNode.noOffset;
-    if (emitSourcePositions) {
-      position = (node is ast.FunctionDeclaration)
-          ? node.fileOffset
-          : function.fileOffset;
-      endPosition = function.fileEndOffset;
-    }
-
     if (function.typeParameters.isNotEmpty) {
       functionTypeParameters ??= new List<TypeParameter>();
       functionTypeParameters.addAll(function.typeParameters);
@@ -1890,27 +1915,8 @@
     locals.sortedNamedParameters.forEach(_evaluateDefaultParameterValue);
 
     final int closureIndex = closures.length;
-    objectTable.declareClosure(function, enclosingMember, closureIndex);
-    final List<NameAndType> parameters = function.positionalParameters
-        .followedBy(function.namedParameters)
-        .map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
-            objectTable.getHandle(v.type)))
-        .toList();
-    final ClosureDeclaration closure = new ClosureDeclaration(
-        objectTable
-            .getHandle(savedIsClosure ? parentFunction : enclosingMember),
-        objectTable.getNameHandle(null, name),
-        position,
-        endPosition,
-        function.typeParameters
-            .map((tp) => new NameAndType(
-                objectTable.getNameHandle(null, tp.name),
-                objectTable.getHandle(tp.bound)))
-            .toList(),
-        function.requiredParameterCount,
-        function.namedParameters.length,
-        parameters,
-        objectTable.getHandle(function.returnType));
+    final closure = getClosureDeclaration(node, function, name, closureIndex,
+        savedIsClosure ? parentFunction : enclosingMember);
     closures.add(closure);
 
     final int closureFunctionIndex = cp.addClosureFunction(closureIndex);
@@ -1918,6 +1924,17 @@
     _recordSourcePosition(function.fileOffset);
     _genPrologue(node, function);
 
+    if (options.causalAsyncStacks &&
+        parentFunction != null &&
+        (parentFunction.dartAsyncMarker == AsyncMarker.Async ||
+            parentFunction.dartAsyncMarker == AsyncMarker.AsyncStar)) {
+      _genLoadVar(locals.asyncStackTraceVar,
+          currentContextLevel: locals.contextLevelAtEntry);
+      _genDirectCall(
+          setAsyncThreadStackTrace, objectTable.getArgDescHandle(1), 1);
+      asm.emitDrop1();
+    }
+
     Label continuationSwitchLabel;
     int continuationSwitchVar;
     if (locals.isSyncYieldingFrame) {
@@ -1930,21 +1947,19 @@
     _setupInitialContext(function);
     _checkArguments(function);
 
-    // TODO(alexmarkov): support --causal_async_stacks.
-
     _generateNode(function.body);
 
     // BytecodeAssembler eliminates this bytecode if it is unreachable.
+    _recordSourcePosition(function.fileEndOffset);
     asm.emitPushNull();
     _genReturnTOS();
-    _recordSourcePosition(function.fileEndOffset);
 
     if (locals.isSyncYieldingFrame) {
       _genSyncYieldingEpilogue(
           function, continuationSwitchLabel, continuationSwitchVar);
     }
 
-    if (emitLocalVarInfo) {
+    if (options.emitLocalVarInfo) {
       // Leave the scope which was entered in _setupInitialContext.
       asm.localVariableTable.leaveScope(asm.offset, function.fileEndOffset);
     }
@@ -1972,6 +1987,71 @@
     return closureFunctionIndex;
   }
 
+  ClosureDeclaration getClosureDeclaration(LocalFunction node,
+      FunctionNode function, String name, int closureIndex, TreeNode parent) {
+    objectTable.declareClosure(function, enclosingMember, closureIndex);
+
+    int flags = 0;
+    int position = TreeNode.noOffset;
+    int endPosition = TreeNode.noOffset;
+    if (options.emitSourcePositions) {
+      position = (node is ast.FunctionDeclaration)
+          ? node.fileOffset
+          : function.fileOffset;
+      endPosition = function.fileEndOffset;
+      if (position != TreeNode.noOffset) {
+        flags |= ClosureDeclaration.hasSourcePositionsFlag;
+      }
+    }
+
+    switch (function.dartAsyncMarker) {
+      case AsyncMarker.Async:
+        flags |= ClosureDeclaration.isAsyncFlag;
+        break;
+      case AsyncMarker.AsyncStar:
+        flags |= ClosureDeclaration.isAsyncStarFlag;
+        break;
+      case AsyncMarker.SyncStar:
+        flags |= ClosureDeclaration.isSyncStarFlag;
+        break;
+      default:
+        break;
+    }
+
+    final List<NameAndType> parameters = function.positionalParameters
+        .followedBy(function.namedParameters)
+        .map((v) => new NameAndType(objectTable.getNameHandle(null, v.name),
+            objectTable.getHandle(v.type)))
+        .toList();
+    if (function.requiredParameterCount != parameters.length) {
+      if (function.namedParameters.isNotEmpty) {
+        flags |= ClosureDeclaration.hasOptionalNamedParamsFlag;
+      } else {
+        flags |= ClosureDeclaration.hasOptionalPositionalParamsFlag;
+      }
+    }
+
+    final typeParams = function.typeParameters
+        .map((tp) => new NameAndType(objectTable.getNameHandle(null, tp.name),
+            objectTable.getHandle(tp.bound)))
+        .toList();
+    if (typeParams.isNotEmpty) {
+      flags |= ClosureDeclaration.hasTypeParamsFlag;
+    }
+
+    return new ClosureDeclaration(
+        flags,
+        objectTable.getHandle(parent),
+        objectTable.getNameHandle(null, name),
+        position,
+        endPosition,
+        typeParams,
+        function.requiredParameterCount,
+        function.namedParameters.length,
+        parameters,
+        objectTable.getHandle(function.returnType));
+  }
+
   void _genSyncYieldingPrologue(FunctionNode function, Label continuationLabel,
       int switchVarIndexInFrame) {
     // switch_var = :await_jump_var
@@ -2045,7 +2125,7 @@
     asm.emitStoreFieldTOS(cp.addInstanceField(closureContext));
   }
 
-  void _genClosure(TreeNode node, String name, FunctionNode function) {
+  void _genClosure(LocalFunction node, String name, FunctionNode function) {
     final int closureFunctionIndex = _genClosureBytecode(node, name, function);
     _genAllocateClosureInstance(node, closureFunctionIndex, function);
   }
@@ -2068,7 +2148,7 @@
   void _enterScope(TreeNode node) {
     locals.enterScope(node);
     _allocateContextIfNeeded();
-    if (emitLocalVarInfo) {
+    if (options.emitLocalVarInfo) {
       asm.localVariableTable
           .enterScope(asm.offset, locals.currentContextLevel, node.fileOffset);
       _startRecordingMaxPosition(node.fileOffset);
@@ -2076,7 +2156,7 @@
   }
 
   void _leaveScope() {
-    if (emitLocalVarInfo) {
+    if (options.emitLocalVarInfo) {
       asm.localVariableTable.leaveScope(asm.offset, _endRecordingMaxPosition());
     }
     if (locals.currentContextSize > 0) {
@@ -2318,7 +2398,7 @@
         new Arguments(node.arguments.positional, named: node.arguments.named)
           ..parent = node;
     _genArguments(null, args);
-    _genDirectCallWithArgs(node.target, args, hasReceiver: true);
+    _genDirectCallWithArgs(node.target, args, hasReceiver: true, context: node);
     asm.emitDrop1();
   }
 
@@ -2328,7 +2408,7 @@
     _genArguments(node.receiver, args);
     final target = node.target;
     if (target is Procedure && !target.isGetter && !target.isSetter) {
-      _genDirectCallWithArgs(target, args, hasReceiver: true);
+      _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
     } else {
       throw new UnsupportedOperationError(
           'Unsupported DirectMethodInvocation with target ${target.runtimeType} $target');
@@ -2583,7 +2663,11 @@
   }
 
   void _genInstanceCall(
-      int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked) {
+      int totalArgCount, int callCpIndex, bool isDynamic, bool isUnchecked,
+      [TreeNode context]) {
+    if (totalArgCount >= argumentsLimit) {
+      throw new TooManyArgumentsException(context.fileOffset);
+    }
     if (isDynamic) {
       assert(!isUnchecked);
       asm.emitDynamicCall(callCpIndex, totalArgCount);
@@ -2621,7 +2705,7 @@
         args.named.length +
         1 /* receiver */ +
         (args.types.isNotEmpty ? 1 : 0) /* type arguments */;
-    _genInstanceCall(totalArgCount, callCpIndex, isDynamic, isUnchecked);
+    _genInstanceCall(totalArgCount, callCpIndex, isDynamic, isUnchecked, node);
   }
 
   @override
@@ -2678,7 +2762,7 @@
       return;
     }
     _genArguments(new ThisExpression(), args);
-    _genDirectCallWithArgs(target, args, hasReceiver: true);
+    _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
   }
 
   @override
@@ -2831,7 +2915,8 @@
             ..parent = node;
     }
     _genArguments(null, args);
-    _genDirectCallWithArgs(target, args, isFactory: target.isFactory);
+    _genDirectCallWithArgs(target, args,
+        isFactory: target.isFactory, context: node);
   }
 
   @override
@@ -2971,7 +3056,7 @@
 
   @override
   visitAssertStatement(AssertStatement node) {
-    if (!enableAsserts) {
+    if (!options.enableAsserts) {
       return;
     }
 
@@ -2980,8 +3065,10 @@
 
     _genConditionAndJumpIf(node.condition, true, done);
 
-    _genPushInt(omitAssertSourcePositions ? 0 : node.conditionStartOffset);
-    _genPushInt(omitAssertSourcePositions ? 0 : node.conditionEndOffset);
+    _genPushInt(
+        options.omitAssertSourcePositions ? 0 : node.conditionStartOffset);
+    _genPushInt(
+        options.omitAssertSourcePositions ? 0 : node.conditionEndOffset);
 
     if (node.message != null) {
       _generateNode(node.message);
@@ -3004,7 +3091,7 @@
 
   @override
   visitAssertBlock(AssertBlock node) {
-    if (!enableAsserts) {
+    if (!options.enableAsserts) {
       return;
     }
 
@@ -3241,12 +3328,12 @@
         _getEnclosingTryFinallyBlocks(node, null);
     if (tryFinallyBlocks.isEmpty) {
       _generateNode(expr);
-      asm.emitReturnTOS();
+      _genReturnTOS();
     } else {
       if (expr is BasicLiteral) {
         _addFinallyBlocks(tryFinallyBlocks, () {
           _generateNode(expr);
-          asm.emitReturnTOS();
+          _genReturnTOS();
         });
       } else {
         // Keep return value in a variable as try-catch statements
@@ -3256,7 +3343,7 @@
 
         _addFinallyBlocks(tryFinallyBlocks, () {
           asm.emitPush(locals.returnVarIndexInFrame);
-          asm.emitReturnTOS();
+          _genReturnTOS();
         });
       }
     }
@@ -3564,7 +3651,7 @@
       } else {
         asm.emitPushNull();
       }
-      if (emitLocalVarInfo && !asm.isUnreachable && node.name != null) {
+      if (options.emitLocalVarInfo && !asm.isUnreachable && node.name != null) {
         _declareLocalVariable(node, maxInitializerPosition + 1);
       }
       _genStoreVar(node);
@@ -3605,6 +3692,10 @@
       return;
     }
 
+    if (options.emitSourcePositions) {
+      asm.emitYieldPointSourcePosition();
+    }
+
     // 0 is reserved for normal entry, yield points are counted from 1.
     final int yieldIndex = yieldPoints.length + 1;
     final Label continuationLabel = new Label(allowsBackwardJumps: true);
@@ -3625,7 +3716,7 @@
     // return <expression>
     // Note: finally blocks are *not* executed on the way out.
     _generateNode(node.expression);
-    asm.emitReturnTOS();
+    _genReturnTOS();
 
     asm.bind(continuationLabel);
 
@@ -3657,7 +3748,7 @@
     final args = node.arguments;
     assert(args.types.isEmpty);
     _genArguments(new ThisExpression(), args);
-    _genDirectCallWithArgs(node.target, args, hasReceiver: true);
+    _genDirectCallWithArgs(node.target, args, hasReceiver: true, context: node);
     asm.emitDrop1();
   }
 
@@ -3675,7 +3766,7 @@
       }
     }
     assert(target != null);
-    _genDirectCallWithArgs(target, args, hasReceiver: true);
+    _genDirectCallWithArgs(target, args, hasReceiver: true, context: node);
     asm.emitDrop1();
   }
 
@@ -3703,6 +3794,11 @@
   String toString() => message;
 }
 
+class TooManyArgumentsException extends BytecodeLimitExceededException {
+  final int fileOffset;
+  TooManyArgumentsException(this.fileOffset);
+}
+
 typedef void GenerateContinuation();
 
 class FinallyBlock {
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index c321b4e..401a528 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -9,7 +9,9 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/transformations/continuation.dart'
     show ContinuationVariables;
+
 import 'dbc.dart';
+import 'options.dart' show BytecodeOptions;
 
 class LocalVariables {
   final Map<TreeNode, Scope> _scopes = <TreeNode, Scope>{};
@@ -24,7 +26,7 @@
       <TreeNode, VariableDeclaration>{};
   final Map<ForInStatement, VariableDeclaration> _capturedIteratorVars =
       <ForInStatement, VariableDeclaration>{};
-  final bool enableAsserts;
+  final BytecodeOptions options;
 
   Scope _currentScope;
   Frame _currentFrame;
@@ -137,6 +139,13 @@
         .getSyntheticVar(ContinuationVariables.awaitContextVar);
   }
 
+  VariableDeclaration get asyncStackTraceVar {
+    assert(options.causalAsyncStacks);
+    assert(_currentFrame.isSyncYielding);
+    return _currentFrame.parent
+        .getSyntheticVar(ContinuationVariables.asyncStackTraceVar);
+  }
+
   VariableDeclaration capturedSavedContextVar(TreeNode node) =>
       _capturedSavedContextVars[node];
   VariableDeclaration capturedExceptionVar(TreeNode node) =>
@@ -176,7 +185,7 @@
   List<VariableDeclaration> get sortedNamedParameters =>
       _currentFrame.sortedNamedParameters;
 
-  LocalVariables(Member node, this.enableAsserts) {
+  LocalVariables(Member node, this.options) {
     final scopeBuilder = new _ScopeBuilder(this);
     node.accept(scopeBuilder);
 
@@ -230,7 +239,7 @@
   bool hasOptionalParameters = false;
   bool hasCapturedParameters = false;
   bool hasClosures = false;
-  bool isDartSync = true;
+  AsyncMarker dartAsyncMarker = AsyncMarker.Sync;
   bool isSyncYielding = false;
   VariableDeclaration receiverVar;
   VariableDeclaration capturedReceiverVar;
@@ -311,7 +320,7 @@
       FunctionNode function = (node as dynamic).function;
       assert(function != null);
 
-      _currentFrame.isDartSync = function.dartAsyncMarker == AsyncMarker.Sync;
+      _currentFrame.dartAsyncMarker = function.dartAsyncMarker;
 
       _currentFrame.isSyncYielding =
           function.asyncMarker == AsyncMarker.SyncYielding;
@@ -363,6 +372,14 @@
             .getSyntheticVar(ContinuationVariables.awaitJumpVar));
         _useVariable(_currentFrame.parent
             .getSyntheticVar(ContinuationVariables.awaitContextVar));
+
+        if (locals.options.causalAsyncStacks &&
+            (_currentFrame.parent.dartAsyncMarker == AsyncMarker.Async ||
+                _currentFrame.parent.dartAsyncMarker ==
+                    AsyncMarker.AsyncStar)) {
+          _useVariable(_currentFrame.parent
+              .getSyntheticVar(ContinuationVariables.asyncStackTraceVar));
+        }
       }
 
       if (node is Constructor) {
@@ -535,7 +552,8 @@
   visitVariableDeclaration(VariableDeclaration node) {
     _declareVariable(node);
 
-    if (!_currentFrame.isDartSync && node.name[0] == ':') {
+    if (_currentFrame.dartAsyncMarker != AsyncMarker.Sync &&
+        node.name[0] == ':') {
       _currentFrame.syntheticVars ??= <String, VariableDeclaration>{};
       assert(_currentFrame.syntheticVars[node.name] == null);
       _currentFrame.syntheticVars[node.name] = node;
@@ -610,7 +628,7 @@
 
   @override
   visitAssertStatement(AssertStatement node) {
-    if (!locals.enableAsserts) {
+    if (!locals.options.enableAsserts) {
       return;
     }
     super.visitAssertStatement(node);
@@ -618,7 +636,7 @@
 
   @override
   visitAssertBlock(AssertBlock node) {
-    if (!locals.enableAsserts) {
+    if (!locals.options.enableAsserts) {
       return;
     }
     _visitWithScope(node);
@@ -1072,7 +1090,7 @@
 
   @override
   visitAssertStatement(AssertStatement node) {
-    if (!locals.enableAsserts) {
+    if (!locals.options.enableAsserts) {
       return;
     }
     super.visitAssertStatement(node);
@@ -1080,7 +1098,7 @@
 
   @override
   visitAssertBlock(AssertBlock node) {
-    if (!locals.enableAsserts) {
+    if (!locals.options.enableAsserts) {
       return;
     }
     _visit(node, scope: true);
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index be1a7ed..6b418e0 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -1543,6 +1543,11 @@
 
   set source(SourceFile sourceFile) {
     _source = sourceFile;
+    if (_source != null) {
+      _flags |= flagHasSourceFile;
+    } else {
+      _flags &= ~flagHasSourceFile;
+    }
   }
 
   @override
@@ -1571,7 +1576,8 @@
   bool operator ==(other) => other is _ScriptHandle && this.uri == other.uri;
 
   @override
-  String toString() => "$uri";
+  String toString() =>
+      "$uri${source != null ? '(source ${source.importUri})' : ''}";
 }
 
 class ObjectTable implements ObjectWriter, ObjectReader {
diff --git a/pkg/vm/lib/bytecode/options.dart b/pkg/vm/lib/bytecode/options.dart
new file mode 100644
index 0000000..516cf57
--- /dev/null
+++ b/pkg/vm/lib/bytecode/options.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2019, 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.
+
+library vm.bytecode.options;
+
+/// Collection of options for bytecode generator.
+class BytecodeOptions {
+  static Map<String, String> commandLineFlags = {
+    'annotations': 'Emit Dart annotations',
+    'local-var-info': 'Emit debug information about local variables',
+    'show-bytecode-size-stat': 'Show bytecode size breakdown',
+    'source-positions': 'Emit source positions',
+  };
+
+  bool enableAsserts;
+  bool causalAsyncStacks;
+  bool emitSourcePositions;
+  bool emitSourceFiles;
+  bool emitLocalVarInfo;
+  bool emitAnnotations;
+  bool omitAssertSourcePositions;
+  bool showBytecodeSizeStatistics;
+  Map<String, String> environmentDefines;
+
+  BytecodeOptions(
+      {this.enableAsserts = false,
+      this.causalAsyncStacks,
+      this.emitSourcePositions = false,
+      this.emitSourceFiles = false,
+      this.emitLocalVarInfo = false,
+      this.emitAnnotations = false,
+      this.omitAssertSourcePositions = false,
+      this.showBytecodeSizeStatistics = false,
+      this.environmentDefines = const <String, String>{}}) {
+    causalAsyncStacks ??=
+        environmentDefines['dart.developer.causal_async_stacks'] == 'true';
+  }
+
+  void parseCommandLineFlags(List<String> flags) {
+    if (flags == null) {
+      return;
+    }
+    for (String flag in flags) {
+      switch (flag) {
+        case 'source-positions':
+          emitSourcePositions = true;
+          break;
+        case 'local-var-info':
+          emitLocalVarInfo = true;
+          break;
+        case 'annotations':
+          emitAnnotations = true;
+          break;
+        case 'show-bytecode-size-stat':
+          showBytecodeSizeStatistics = true;
+          break;
+        default:
+          throw 'Unexpected bytecode flag $flag';
+      }
+    }
+  }
+}
diff --git a/pkg/vm/lib/bytecode/source_positions.dart b/pkg/vm/lib/bytecode/source_positions.dart
index af58534..ec56aa15 100644
--- a/pkg/vm/lib/bytecode/source_positions.dart
+++ b/pkg/vm/lib/bytecode/source_positions.dart
@@ -15,7 +15,10 @@
 
 /// Maintains mapping between bytecode instructions and source positions.
 class SourcePositions {
-  final Map<int, int> mapping = <int, int>{}; // PC -> fileOffset
+  // Special value of fileOffset which marks yield point.
+  static const yieldPointMarker = -2;
+
+  final List<int> _positions = <int>[]; // Pairs (PC, fileOffset).
   int _lastPc = 0;
   int _lastOffset = 0;
 
@@ -25,20 +28,37 @@
     assert(pc > _lastPc);
     assert(fileOffset >= 0);
     if (fileOffset != _lastOffset) {
-      mapping[pc] = fileOffset;
+      _positions.add(pc);
+      _positions.add(fileOffset);
       _lastPc = pc;
       _lastOffset = fileOffset;
     }
   }
 
+  void addYieldPoint(int pc, int fileOffset) {
+    assert(pc > _lastPc);
+    assert(fileOffset >= 0);
+    _positions.add(pc);
+    _positions.add(yieldPointMarker);
+    _positions.add(pc);
+    _positions.add(fileOffset);
+    _lastPc = pc;
+    _lastOffset = fileOffset;
+  }
+
+  bool get isEmpty => _positions.isEmpty;
+  bool get isNotEmpty => !isEmpty;
+
   void write(BufferedWriter writer) {
-    writer.writePackedUInt30(mapping.length);
+    writer.writePackedUInt30(_positions.length ~/ 2);
     final encodePC = new PackedUInt30DeltaEncoder();
     final encodeOffset = new SLEB128DeltaEncoder();
-    mapping.forEach((int pc, int fileOffset) {
+    for (int i = 0; i < _positions.length; i += 2) {
+      final int pc = _positions[i];
+      final int fileOffset = _positions[i + 1];
       encodePC.write(writer, pc);
       encodeOffset.write(writer, fileOffset);
-    });
+    }
   }
 
   SourcePositions.read(BufferedReader reader) {
@@ -48,16 +68,29 @@
     for (int i = 0; i < length; ++i) {
       int pc = decodePC.read(reader);
       int fileOffset = decodeOffset.read(reader);
-      add(pc, fileOffset);
+      _positions.add(pc);
+      _positions.add(fileOffset);
     }
   }
 
   @override
-  String toString() => mapping.toString();
+  String toString() => _positions.toString();
 
   Map<int, String> getBytecodeAnnotations() {
-    return mapping.map((int pc, int fileOffset) =>
-        new MapEntry(pc, 'source position $fileOffset'));
+    final map = <int, String>{};
+    for (int i = 0; i < _positions.length; i += 2) {
+      final int pc = _positions[i];
+      final int fileOffset = _positions[i + 1];
+      final entry = (fileOffset == yieldPointMarker)
+          ? 'yield point'
+          : 'source position $fileOffset';
+      if (map[pc] == null) {
+        map[pc] = entry;
+      } else {
+        map[pc] = "${map[pc]}; $entry";
+      }
+    }
+    return map;
   }
 }
 
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 8402ef8..78a233a 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -48,6 +48,7 @@
 import 'bytecode/bytecode_serialization.dart' show BytecodeSizeStatistics;
 import 'bytecode/gen_bytecode.dart'
     show generateBytecode, createFreshComponentWithBytecode;
+import 'bytecode/options.dart' show BytecodeOptions;
 
 import 'constants_error_reporter.dart' show ForwardConstantEvaluationErrors;
 import 'target/install.dart' show installAdditionalTargets;
@@ -111,19 +112,13 @@
           'Split resulting kernel file into multiple files (one per package).',
       defaultsTo: false);
   args.addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false);
-  args.addFlag('emit-bytecode-source-positions',
-      help: 'Emit source positions in bytecode', defaultsTo: false);
-  args.addFlag('emit-bytecode-local-var-info',
-      help: 'Emit information about local variables in bytecode',
-      defaultsTo: false);
-  args.addFlag('emit-bytecode-annotations',
-      help: 'Emit Dart annotations in bytecode', defaultsTo: false);
+  args.addMultiOption('bytecode-options',
+      help: 'Specify options for bytecode generation:',
+      valueHelp: 'opt1,opt2,...',
+      allowed: BytecodeOptions.commandLineFlags.keys,
+      allowedHelp: BytecodeOptions.commandLineFlags);
   args.addFlag('drop-ast',
-      help: 'Drop AST for members with bytecode', defaultsTo: false);
-  args.addFlag('show-bytecode-size-stat',
-      help: 'Show bytecode size breakdown.', defaultsTo: false);
-  args.addFlag('use-future-bytecode-format',
-      help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);
+      help: 'Include only bytecode into the output file', defaultsTo: false);
   args.addMultiOption('enable-experiment',
       help: 'Comma separated list of experimental features to enable.');
   args.addFlag('help',
@@ -166,18 +161,13 @@
   final bool aot = options['aot'];
   final bool tfa = options['tfa'];
   final bool linkPlatform = options['link-platform'];
+  final bool embedSources = options['embed-sources'];
   final bool genBytecode = options['gen-bytecode'];
-  final bool emitBytecodeSourcePositions =
-      options['emit-bytecode-source-positions'];
-  final bool emitBytecodeLocalVarInfo = options['emit-bytecode-local-var-info'];
-  final bool emitBytecodeAnnotations = options['emit-bytecode-annotations'];
   final bool dropAST = options['drop-ast'];
-  final bool useFutureBytecodeFormat = options['use-future-bytecode-format'];
   final bool enableAsserts = options['enable-asserts'];
   final bool enableConstantEvaluation = options['enable-constant-evaluation'];
   final bool useProtobufTreeShaker = options['protobuf-tree-shaker'];
   final bool splitOutputByPackages = options['split-output-by-packages'];
-  final bool showBytecodeSizeStat = options['show-bytecode-size-stat'];
   final List<String> experimentalFlags = options['enable-experiment'];
   final Map<String, String> environmentDefines = {};
 
@@ -185,6 +175,12 @@
     return badUsageExitCode;
   }
 
+  final BytecodeOptions bytecodeOptions = new BytecodeOptions(
+      enableAsserts: enableAsserts,
+      emitSourceFiles: embedSources,
+      environmentDefines: environmentDefines)
+    ..parseCommandLineFlags(options['bytecode-options']);
+
   final target = createFrontEndTarget(targetName);
   if (target == null) {
     print('Failed to create front-end target $targetName.');
@@ -222,18 +218,15 @@
     ..onDiagnostic = (DiagnosticMessage m) {
       errorDetector(m);
     }
-    ..embedSourceText = options['embed-sources'];
+    ..embedSourceText = embedSources;
 
   final component = await compileToKernel(mainUri, compilerOptions,
       aot: aot,
       useGlobalTypeFlowAnalysis: tfa,
       environmentDefines: environmentDefines,
       genBytecode: genBytecode,
-      emitBytecodeSourcePositions: emitBytecodeSourcePositions,
-      emitBytecodeLocalVarInfo: emitBytecodeLocalVarInfo,
-      emitBytecodeAnnotations: emitBytecodeAnnotations,
+      bytecodeOptions: bytecodeOptions,
       dropAST: dropAST && !splitOutputByPackages,
-      useFutureBytecodeFormat: useFutureBytecodeFormat,
       enableAsserts: enableAsserts,
       enableConstantEvaluation: enableConstantEvaluation,
       useProtobufTreeShaker: useProtobufTreeShaker);
@@ -244,7 +237,7 @@
     return compileTimeErrorExitCode;
   }
 
-  if (showBytecodeSizeStat && !splitOutputByPackages) {
+  if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
     BytecodeSizeStatistics.reset();
   }
 
@@ -253,7 +246,7 @@
   printer.writeComponentFile(component);
   await sink.close();
 
-  if (showBytecodeSizeStat && !splitOutputByPackages) {
+  if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
     BytecodeSizeStatistics.dump();
   }
 
@@ -267,15 +260,9 @@
       compilerOptions,
       component,
       outputFileName,
-      environmentDefines: environmentDefines,
       genBytecode: genBytecode,
-      enableAsserts: enableAsserts,
-      emitBytecodeSourcePositions: emitBytecodeSourcePositions,
-      emitBytecodeLocalVarInfo: emitBytecodeLocalVarInfo,
-      emitBytecodeAnnotations: emitBytecodeAnnotations,
+      bytecodeOptions: bytecodeOptions,
       dropAST: dropAST,
-      showBytecodeSizeStat: showBytecodeSizeStat,
-      useFutureBytecodeFormat: useFutureBytecodeFormat,
     );
   }
 
@@ -292,11 +279,8 @@
     bool useGlobalTypeFlowAnalysis: false,
     Map<String, String> environmentDefines,
     bool genBytecode: false,
-    bool emitBytecodeSourcePositions: false,
-    bool emitBytecodeLocalVarInfo: false,
-    bool emitBytecodeAnnotations: false,
+    BytecodeOptions bytecodeOptions,
     bool dropAST: false,
-    bool useFutureBytecodeFormat: false,
     bool enableAsserts: false,
     bool enableConstantEvaluation: true,
     bool useProtobufTreeShaker: false}) async {
@@ -324,14 +308,7 @@
 
   if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
     await runWithFrontEndCompilerContext(source, options, component, () {
-      generateBytecode(component,
-          enableAsserts: enableAsserts,
-          emitSourcePositions: emitBytecodeSourcePositions,
-          emitSourceFiles: options.embedSourceText,
-          emitLocalVarInfo: emitBytecodeLocalVarInfo,
-          emitAnnotations: emitBytecodeAnnotations,
-          useFutureBytecodeFormat: useFutureBytecodeFormat,
-          environmentDefines: environmentDefines);
+      generateBytecode(component, options: bytecodeOptions);
     });
 
     if (dropAST) {
@@ -661,15 +638,9 @@
   CompilerOptions compilerOptions,
   Component component,
   String outputFileName, {
-  Map<String, String> environmentDefines,
   bool genBytecode: false,
-  bool enableAsserts: true,
-  bool emitBytecodeSourcePositions: false,
-  bool emitBytecodeLocalVarInfo: false,
-  bool emitBytecodeAnnotations: false,
+  BytecodeOptions bytecodeOptions,
   bool dropAST: false,
-  bool showBytecodeSizeStat: false,
-  bool useFutureBytecodeFormat: false,
 }) async {
   // Package sharing: make the encoding not depend on the order in which parts
   // of a package are loaded.
@@ -693,7 +664,7 @@
   final List<String> packages = packagesSet.toList();
   packages.add('main'); // Make sure main package is last.
 
-  if (showBytecodeSizeStat) {
+  if (bytecodeOptions.showBytecodeSizeStatistics) {
     BytecodeSizeStatistics.reset();
   }
 
@@ -724,15 +695,9 @@
             .where((lib) => packageFor(lib) == package)
             .toList();
         generateBytecode(component,
+            options: bytecodeOptions,
             libraries: libraries,
-            hierarchy: hierarchy,
-            enableAsserts: enableAsserts,
-            emitSourcePositions: emitBytecodeSourcePositions,
-            emitSourceFiles: compilerOptions.embedSourceText,
-            emitLocalVarInfo: emitBytecodeLocalVarInfo,
-            emitAnnotations: emitBytecodeAnnotations,
-            useFutureBytecodeFormat: useFutureBytecodeFormat,
-            environmentDefines: environmentDefines);
+            hierarchy: hierarchy);
 
         if (dropAST) {
           partComponent = createFreshComponentWithBytecode(component);
@@ -750,7 +715,7 @@
     }
   });
 
-  if (showBytecodeSizeStat) {
+  if (bytecodeOptions.showBytecodeSizeStatistics) {
     BytecodeSizeStatistics.dump();
   }
 
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index bcbf5fa..c90cd64 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -16,6 +16,9 @@
 
 /// Represents the (instantiated) ffi.NativeType.
 enum NativeType {
+  kNativeType,
+  kNativeInteger,
+  kNativeDouble,
   kPointer,
   kNativeFunction,
   kInt8,
@@ -29,7 +32,8 @@
   kIntptr,
   kFloat,
   kDouble,
-  kVoid
+  kVoid,
+  kStruct
 }
 
 const NativeType kNativeTypeIntStart = NativeType.kInt8;
@@ -37,6 +41,9 @@
 
 /// The [NativeType] class names, indexed by [NativeType].
 const List<String> nativeTypeClassNames = [
+  'NativeType',
+  '_NativeInteger',
+  '_NativeDouble',
   'Pointer',
   'NativeFunction',
   'Int8',
@@ -50,7 +57,8 @@
   'IntPtr',
   'Float',
   'Double',
-  'Void'
+  'Void',
+  'Struct'
 ];
 
 const int UNKNOWN = 0;
@@ -58,6 +66,9 @@
 
 /// The [NativeType] sizes in bytes, indexed by [NativeType].
 const List<int> nativeTypeSizes = [
+  UNKNOWN, // NativeType
+  UNKNOWN, // NativeInteger
+  UNKNOWN, // NativeDouble
   WORD_SIZE, // Pointer
   UNKNOWN, // NativeFunction
   1, // Int8
@@ -72,12 +83,14 @@
   4, // Float
   8, // Double
   UNKNOWN, // Void
+  UNKNOWN, // Struct
 ];
 
 /// [FfiTransformer] contains logic which is shared between
 /// _FfiUseSiteTransformer and _FfiDefinitionTransformer.
 class FfiTransformer extends Transformer {
   final TypeEnvironment env;
+  final CoreTypes coreTypes;
   final LibraryIndex index;
   final ClassHierarchy hierarchy;
   final DiagnosticReporter diagnosticReporter;
@@ -95,15 +108,18 @@
   final Procedure storeMethod;
   final Procedure offsetByMethod;
   final Procedure asFunctionMethod;
+  final Procedure asFunctionInternal;
   final Procedure lookupFunctionMethod;
   final Procedure fromFunctionMethod;
-  final Field structField;
+  final Field addressOfField;
+  final Constructor structFromPointer;
+  final Procedure libraryLookupMethod;
 
   /// Classes corresponding to [NativeType], indexed by [NativeType].
   final List<Class> nativeTypesClasses;
 
   FfiTransformer(
-      this.index, CoreTypes coreTypes, this.hierarchy, this.diagnosticReporter)
+      this.index, this.coreTypes, this.hierarchy, this.diagnosticReporter)
       : env = new TypeEnvironment(coreTypes, hierarchy),
         intClass = coreTypes.intClass,
         doubleClass = coreTypes.doubleClass,
@@ -116,15 +132,21 @@
         loadMethod = index.getMember('dart:ffi', 'Pointer', 'load'),
         storeMethod = index.getMember('dart:ffi', 'Pointer', 'store'),
         offsetByMethod = index.getMember('dart:ffi', 'Pointer', 'offsetBy'),
+        addressOfField = index.getMember('dart:ffi', 'Struct', 'addressOf'),
+        structFromPointer =
+            index.getMember('dart:ffi', 'Struct', 'fromPointer'),
         asFunctionMethod = index.getMember('dart:ffi', 'Pointer', 'asFunction'),
+        asFunctionInternal =
+            index.getTopLevelMember('dart:ffi', '_asFunctionInternal'),
         lookupFunctionMethod =
             index.getMember('dart:ffi', 'DynamicLibrary', 'lookupFunction'),
         fromFunctionMethod =
-            index.getTopLevelMember('dart:ffi', 'fromFunction'),
-        structField = index.getTopLevelMember('dart:ffi', 'struct'),
+            index.getMember('dart:ffi', 'Pointer', 'fromFunction'),
+        libraryLookupMethod =
+            index.getMember('dart:ffi', 'DynamicLibrary', 'lookup'),
         nativeTypesClasses = nativeTypeClassNames
             .map((name) => index.getClass('dart:ffi', name))
-            .toList() {}
+            .toList();
 
   /// Computes the Dart type corresponding to a ffi.[NativeType], returns null
   /// if it is not a valid NativeType.
@@ -145,19 +167,23 @@
   /// T extends [Pointer]                  -> T
   /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
   ///    where DartRepresentationOf(Tn) -> Sn
-  DartType convertNativeTypeToDartType(DartType nativeType) {
+  DartType convertNativeTypeToDartType(DartType nativeType, bool allowStructs) {
     if (nativeType is! InterfaceType) {
       return null;
     }
-    Class nativeClass = (nativeType as InterfaceType).classNode;
-    if (env.isSubtypeOf(
-        InterfaceType(nativeClass), InterfaceType(pointerClass))) {
-      return nativeType;
-    }
+    InterfaceType native = nativeType;
+    Class nativeClass = native.classNode;
     NativeType nativeType_ = getType(nativeClass);
+
+    if (hierarchy.isSubclassOf(nativeClass, structClass)) {
+      return allowStructs ? nativeType : null;
+    }
     if (nativeType_ == null) {
       return null;
     }
+    if (nativeType_ == NativeType.kPointer) {
+      return nativeType;
+    }
     if (kNativeTypeIntStart.index <= nativeType_.index &&
         nativeType_.index <= kNativeTypeIntEnd.index) {
       return InterfaceType(intClass);
@@ -168,23 +194,26 @@
     if (nativeType_ == NativeType.kVoid) {
       return VoidType();
     }
-    if (nativeType_ == NativeType.kNativeFunction) {
-      DartType fun = (nativeType as InterfaceType).typeArguments[0];
-      if (fun is FunctionType) {
-        if (fun.namedParameters.isNotEmpty) return null;
-        if (fun.positionalParameters.length != fun.requiredParameterCount)
-          return null;
-        if (fun.typeParameters.length != 0) return null;
-        DartType returnType = convertNativeTypeToDartType(fun.returnType);
-        if (returnType == null) return null;
-        List<DartType> argumentTypes = fun.positionalParameters
-            .map(this.convertNativeTypeToDartType)
-            .toList();
-        if (argumentTypes.contains(null)) return null;
-        return FunctionType(argumentTypes, returnType);
-      }
+    if (nativeType_ != NativeType.kNativeFunction ||
+        native.typeArguments[0] is! FunctionType) {
+      return null;
     }
-    return null;
+
+    FunctionType fun = native.typeArguments[0];
+    if (fun.namedParameters.isNotEmpty) return null;
+    if (fun.positionalParameters.length != fun.requiredParameterCount) {
+      return null;
+    }
+    if (fun.typeParameters.length != 0) return null;
+    // TODO(36730): Structs cannot appear in native function signatures.
+    DartType returnType =
+        convertNativeTypeToDartType(fun.returnType, /*allowStructs=*/ false);
+    if (returnType == null) return null;
+    List<DartType> argumentTypes = fun.positionalParameters
+        .map((t) => convertNativeTypeToDartType(t, /*allowStructs=*/ false))
+        .toList();
+    if (argumentTypes.contains(null)) return null;
+    return FunctionType(argumentTypes, returnType);
   }
 
   NativeType getType(Class c) {
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index ad38a18..34d3fa9 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -9,9 +9,10 @@
 import 'package:front_end/src/api_unstable/vm.dart'
     show
         templateFfiFieldAnnotation,
-        templateFfiStructAnnotation,
         templateFfiTypeMismatch,
-        templateFfiFieldInitializer;
+        templateFfiFieldInitializer,
+        templateFfiStructGeneric,
+        templateFfiWrongStructInheritance;
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -27,40 +28,37 @@
         nativeTypeSizes,
         WORD_SIZE;
 
-/// Checks and expands the dart:ffi @struct and field annotations.
+/// Checks and elaborates the dart:ffi structs and fields.
 ///
-/// Sample input:
-/// @ffi.struct
-/// class Coord extends ffi.Pointer<Void> {
-///   @ffi.Double()
+/// Input:
+/// class Coord extends Struct<Coord> {
+///   @Double()
 ///   double x;
 ///
-///   @ffi.Double()
+///   @Double()
 ///   double y;
 ///
-///   @ffi.Pointer()
+///   @Pointer()
 ///   Coord next;
-///
-///   external static int sizeOf();
 /// }
 ///
-/// Sample output:
-/// class Coordinate extends ffi.Pointer<ffi.Void> {
-///   ffi.Pointer<ffi.Double> get _xPtr => cast();
+/// Output:
+/// class Coord extends Struct<Coord> {
+///   Coord.#fromPointer(Pointer<Coord> coord) : super._(coord);
+///
+///   Pointer<Double> get _xPtr => addressOf.cast();
 ///   set x(double v) => _xPtr.store(v);
 ///   double get x => _xPtr.load();
 ///
-///   ffi.Pointer<ffi.Double> get _yPtr =>
-///       offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
+///   Pointer<Double> get _yPtr => addressOf.offsetBy(...).cast();
 ///   set y(double v) => _yPtr.store(v);
 ///   double get y => _yPtr.load();
 ///
-///   ffi.Pointer<Coordinate> get _nextPtr =>
-///       offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
+///   ffi.Pointer<Coordinate> get _nextPtr => addressof.offsetBy(...).cast();
 ///   set next(Coordinate v) => _nextPtr.store(v);
 ///   Coordinate get next => _nextPtr.load();
 ///
-///   static int sizeOf() => 24;
+///   static final int #sizeOf = 24;
 /// }
 ReplacedMembers transformLibraries(
     Component component,
@@ -71,7 +69,7 @@
   final LibraryIndex index = LibraryIndex(
       component, const ["dart:ffi", "dart:_internal", "dart:core"]);
   if (!index.containsLibrary("dart:ffi")) {
-    // if dart:ffi is not loaded, do not do the transformation
+    // If dart:ffi is not loaded, do not do the transformation.
     return ReplacedMembers({}, {});
   }
   final transformer = new _FfiDefinitionTransformer(
@@ -81,7 +79,7 @@
       transformer.replacedGetters, transformer.replacedSetters);
 }
 
-/// Checks and expands the dart:ffi @struct and field annotations.
+/// Checks and elaborates the dart:ffi structs and fields.
 class _FfiDefinitionTransformer extends FfiTransformer {
   final LibraryIndex index;
   final Field _internalIs64Bit;
@@ -108,20 +106,19 @@
 
   @override
   visitClass(Class node) {
-    if (node == pointerClass || !hierarchy.isSubtypeOf(node, pointerClass)) {
+    if (!hierarchy.isSubclassOf(node, structClass) || node == structClass) {
       return node;
     }
 
-    // Because subtypes of Pointer are only allocated by allocate<Pointer<..>>()
-    // and fromAddress<Pointer<..>>() which are not recognized as constructor
-    // calls, we need to prevent these classes from being tree shaken out.
-    _preventTreeShaking(node);
+    _checkStructClass(node);
 
-    _checkFieldAnnotations(node);
+    // Struct objects are manufactured in the VM by 'allocate' and 'load'.
+    _makeEntryPoint(node);
+
     _checkConstructors(node);
+    final bool fieldsValid = _checkFieldAnnotations(node);
 
-    bool isStruct = _checkStructAnnotation(node);
-    if (isStruct) {
+    if (fieldsValid) {
       int size = _replaceFields(node);
       _replaceSizeOfMethod(node, size);
     }
@@ -129,19 +126,34 @@
     return node;
   }
 
-  bool _checkStructAnnotation(Class node) {
-    bool isStruct = _hasAnnotation(node);
-    if (!isStruct && node.fields.isNotEmpty) {
+  void _checkStructClass(Class node) {
+    if (node.typeParameters.length > 0) {
       diagnosticReporter.report(
-          templateFfiStructAnnotation.withArguments(node.name),
+          templateFfiStructGeneric.withArguments(node.name),
           node.fileOffset,
           1,
-          node.fileUri);
+          node.location.file);
     }
-    return isStruct;
+
+    if (node.supertype?.classNode != structClass) {
+      // Not a struct, but extends a struct. The error will be emitted by
+      // _FfiUseSiteTransformer.
+      return;
+    }
+
+    // A struct classes "C" must extend "Struct<C>".
+    DartType structTypeArg = node.supertype.typeArguments[0];
+    if (structTypeArg != InterfaceType(node)) {
+      diagnosticReporter.report(
+          templateFfiWrongStructInheritance.withArguments(node.name),
+          node.fileOffset,
+          1,
+          node.location.file);
+    }
   }
 
-  void _checkFieldAnnotations(Class node) {
+  bool _checkFieldAnnotations(Class node) {
+    bool success = true;
     for (Field f in node.fields) {
       if (f.initializer is! NullLiteral) {
         diagnosticReporter.report(
@@ -161,21 +173,29 @@
         DartType dartType = f.type;
         DartType nativeType =
             InterfaceType(nativeTypesClasses[annos.first.index]);
-        DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
-        if (!env.isSubtypeOf(dartType, shouldBeDartType)) {
+        // TODO(36730): Support structs inside structs.
+        DartType shouldBeDartType =
+            convertNativeTypeToDartType(nativeType, /*allowStructs=*/ false);
+        if (shouldBeDartType == null ||
+            !env.isSubtypeOf(dartType, shouldBeDartType)) {
           diagnosticReporter.report(
               templateFfiTypeMismatch.withArguments(
                   dartType, shouldBeDartType, nativeType),
               f.fileOffset,
               1,
               f.location.file);
+          success = false;
         }
       }
     }
+    return success;
   }
 
   void _checkConstructors(Class node) {
     List<Initializer> toRemove = [];
+
+    // Constructors cannot have initializers because initializers refer to
+    // fields, and the fields were replaced with getter/setter pairs.
     for (Constructor c in node.constructors) {
       for (Initializer i in c.initializers) {
         if (i is FieldInitializer) {
@@ -192,6 +212,18 @@
     for (Initializer i in toRemove) {
       i.remove();
     }
+
+    // Add a constructor which 'load' can use.
+    // C.#fromPointer(Pointer<Void> address) : super.fromPointer(address);
+    final VariableDeclaration pointer = new VariableDeclaration("#pointer");
+    final Constructor ctor = Constructor(
+        FunctionNode(EmptyStatement(), positionalParameters: [pointer]),
+        name: Name("#fromPointer"),
+        initializers: [
+          SuperInitializer(structFromPointer, Arguments([VariableGet(pointer)]))
+        ]);
+    _makeEntryPoint(ctor);
+    node.addMember(ctor);
   }
 
   /// Computes the field offsets in the struct and replaces the fields with
@@ -230,7 +262,7 @@
   }
 
   /// Sample output:
-  /// ffi.Pointer<ffi.Double> get _xPtr => cast();
+  /// ffi.Pointer<ffi.Double> get _xPtr => addressOf.cast();
   /// double get x => _xPtr.load();
   /// set x(double v) => _xPtr.store(v);
   List<Procedure> _generateMethodsForField(
@@ -241,13 +273,12 @@
     DartType pointerType = InterfaceType(pointerClass, [nativeType]);
     Name pointerName = Name('#_ptr_${field.name.name}');
 
-    // Sample output for primitives:
-    // ffi.Pointer<ffi.Double> get _xPtr => cast<ffi.Pointer<ffi.Double>>();
-    // Sample output for structs:
-    // ffi.Pointer<Coordinate> get _xPtr => offsetBy(16).cast<...>();
-    Expression offsetExpression = ThisExpression();
+    // Sample output:
+    // ffi.Pointer<ffi.Double> get _xPtr => addressOf.offsetBy(...).cast<ffi.Pointer<ffi.Double>>();
+    Expression pointer =
+        PropertyGet(ThisExpression(), addressOfField.name, addressOfField);
     if (offset != 0) {
-      offsetExpression = MethodInvocation(offsetExpression, offsetByMethod.name,
+      pointer = MethodInvocation(pointer, offsetByMethod.name,
           Arguments([IntLiteral(offset)]), offsetByMethod);
     }
     Procedure pointerGetter = Procedure(
@@ -255,9 +286,9 @@
         ProcedureKind.Getter,
         FunctionNode(
             guardOn32Bit(ReturnStatement(MethodInvocation(
-                offsetExpression,
+                pointer,
                 castMethod.name,
-                Arguments([], types: [pointerType]),
+                Arguments([], types: [nativeType]),
                 castMethod))),
             returnType: pointerType));
 
@@ -276,41 +307,40 @@
 
     // Sample output:
     // set x(double v) => _xPtr.store(v);
-    VariableDeclaration argument = VariableDeclaration('#v', type: field.type);
-    Procedure setter = Procedure(
-        field.name,
-        ProcedureKind.Setter,
-        FunctionNode(
-            guardOn32Bit(ReturnStatement(MethodInvocation(
-                PropertyGet(ThisExpression(), pointerName, pointerGetter),
-                storeMethod.name,
-                Arguments([VariableGet(argument)]),
-                storeMethod))),
-            returnType: VoidType(),
-            positionalParameters: [argument]));
+    Procedure setter = null;
+    if (!field.isFinal) {
+      VariableDeclaration argument =
+          VariableDeclaration('#v', type: field.type);
+      setter = Procedure(
+          field.name,
+          ProcedureKind.Setter,
+          FunctionNode(
+              guardOn32Bit(ReturnStatement(MethodInvocation(
+                  PropertyGet(ThisExpression(), pointerName, pointerGetter),
+                  storeMethod.name,
+                  Arguments([VariableGet(argument)]),
+                  storeMethod))),
+              returnType: VoidType(),
+              positionalParameters: [argument]));
+    }
 
     replacedGetters[field] = getter;
     replacedSetters[field] = setter;
 
-    return [pointerGetter, getter, setter];
+    if (setter != null) {
+      return [pointerGetter, getter, setter];
+    } else {
+      return [pointerGetter, getter];
+    }
   }
 
-  /// Sample input:
-  /// external static int sizeOf();
-  ///
   /// Sample output:
-  /// static int sizeOf() => 24;
+  /// static int #sizeOf() => 24;
   void _replaceSizeOfMethod(Class struct, int size) {
-    Procedure sizeOf = _findProcedure(struct, 'sizeOf');
-    if (sizeOf == null || !sizeOf.isExternal || !sizeOf.isStatic) {
-      return;
-    }
-
-    // replace in place to avoid going over use sites
-    sizeOf.function = FunctionNode(
-        guardOn32Bit(ReturnStatement(IntLiteral(size))),
-        returnType: InterfaceType(intClass));
-    sizeOf.isExternal = false;
+    final Field sizeOf = Field(Name("#sizeOf"),
+        isStatic: true, isFinal: true, initializer: IntLiteral(size));
+    _makeEntryPoint(sizeOf);
+    struct.addMember(sizeOf);
   }
 
   // TODO(dacoharkes): move to VM, take into account architecture
@@ -359,25 +389,7 @@
     return _align(highestOffset + highestOffsetSize, largestElement);
   }
 
-  bool _hasAnnotation(Class node) {
-    // Pre constant 2018 update.
-    // TODO(dacoharkes): Remove pre constant 2018 after constants change landed.
-    for (Expression e in node.annotations) {
-      if (e is StaticGet) {
-        if (e.target == structField) {
-          return true;
-        }
-      }
-    }
-    Iterable<Class> postConstant2018 = node.annotations
-        .whereType<ConstantExpression>()
-        .map((expr) => expr.constant)
-        .whereType<InstanceConstant>()
-        .map((constant) => constant.classNode);
-    return postConstant2018.contains(structClass);
-  }
-
-  void _preventTreeShaking(Class node) {
+  void _makeEntryPoint(Annotatable node) {
     node.addAnnotation(ConstructorInvocation(
         pragmaConstructor, Arguments([StringLiteral("vm:entry-point")])));
   }
@@ -409,7 +421,3 @@
     return postConstant2018.followedBy(preConstant2018);
   }
 }
-
-/// Finds procedure with name, otherwise returns null.
-Procedure _findProcedure(Class c, String name) =>
-    c.procedures.firstWhere((p) => p.name.name == name, orElse: () => null);
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index d61ca95..58b0acd 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -8,8 +8,10 @@
     show
         templateFfiTypeInvalid,
         templateFfiTypeMismatch,
+        templateFfiDartTypeMismatch,
         templateFfiTypeUnsized,
-        templateFfiNotStatic;
+        templateFfiNotStatic,
+        templateFfiExtendsOrImplementsSealedClass;
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -35,7 +37,7 @@
     ReplacedMembers replacedFields) {
   final index = new LibraryIndex(component, ["dart:ffi"]);
   if (!index.containsLibrary("dart:ffi")) {
-    // if dart:ffi is not loaded, do not do the transformation
+    // If dart:ffi is not loaded, do not do the transformation.
     return;
   }
   final transformer = new _FfiUseSiteTransformer(
@@ -74,6 +76,7 @@
   visitClass(Class node) {
     env.thisType = InterfaceType(node);
     try {
+      _ensureNotExtendsOrImplementsSealedClass(node);
       return super.visitClass(node);
     } finally {
       env.thisType = null;
@@ -118,20 +121,71 @@
         DartType dartType = func.getStaticType(env);
 
         _ensureIsStatic(func);
+        // TODO(36730): Allow passing/returning structs by value.
         _ensureNativeTypeValid(nativeType, node);
         _ensureNativeTypeToDartType(nativeType, dartType, node);
+
+        // Check `exceptionalReturn`'s type.
+        final FunctionType funcType = dartType;
+        final Expression exceptionalReturn = node.arguments.positional[1];
+        final DartType returnType = exceptionalReturn.getStaticType(env);
+
+        if (!env.isSubtypeOf(returnType, funcType.returnType)) {
+          diagnosticReporter.report(
+              templateFfiDartTypeMismatch.withArguments(
+                  returnType, funcType.returnType),
+              exceptionalReturn.fileOffset,
+              1,
+              exceptionalReturn.location.file);
+        }
       }
     } catch (_FfiStaticTypeError) {}
 
     return node;
   }
 
+  // We need to replace calls to 'DynamicLibrary.lookupFunction' with explicit
+  // Kernel, because we cannot have a generic call to 'asFunction' in its body.
+  //
+  // Below, in 'visitMethodInvocation', we ensure that the type arguments to
+  // 'lookupFunction' are constants, so by inlining the call to 'asFunction' at
+  // the call-site, we ensure that there are no generic calls to 'asFunction'.
+  //
+  // We will not detect dynamic invocations of 'asFunction' -- these are handled
+  // by the stub in 'dynamic_library_patch.dart'. Dynamic invocations of
+  // 'lookupFunction' (and 'asFunction') are not legal and throw a runtime
+  // exception.
+  Expression _replaceLookupFunction(MethodInvocation node) {
+    // The generated code looks like:
+    //
+    // _asFunctionInternal<DS, NS>(lookup<NativeFunction<NS>>(symbolName))
+
+    final DartType nativeSignature = node.arguments.types[0];
+    final DartType dartSignature = node.arguments.types[1];
+
+    final Arguments args = Arguments([
+      node.arguments.positional.single
+    ], types: [
+      InterfaceType(nativeFunctionClass, [nativeSignature])
+    ]);
+
+    final Expression lookupResult = MethodInvocation(
+        node.receiver, Name("lookup"), args, libraryLookupMethod);
+
+    return StaticInvocation(asFunctionInternal,
+        Arguments([lookupResult], types: [dartSignature, nativeSignature]));
+  }
+
   @override
   visitMethodInvocation(MethodInvocation node) {
     super.visitMethodInvocation(node);
 
     Member target = node.interfaceTarget;
     try {
+      // We will not detect dynamic invocations of 'asFunction' and
+      // 'lookupFunction' -- these are handled by the 'asFunctionInternal' stub
+      // in 'dynamic_library_patch.dart'. Dynamic invocations of 'asFunction'
+      // and 'lookupFunction' are not legal and throw a runtime exception.
       if (target == lookupFunctionMethod) {
         DartType nativeType =
             InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
@@ -139,14 +193,8 @@
 
         _ensureNativeTypeValid(nativeType, node);
         _ensureNativeTypeToDartType(nativeType, dartType, node);
+        return _replaceLookupFunction(node);
       } else if (target == asFunctionMethod) {
-        if (isFfiLibrary) {
-          // Library code of dart:ffi uses asFunction to implement
-          // lookupFunction. Since we treat lookupFunction as well, this call
-          // can be generic and still support AOT.
-          return node;
-        }
-
         DartType dartType = node.arguments.types[0];
         DartType pointerType = node.receiver.getStaticType(env);
         DartType nativeType = _pointerTypeGetTypeArg(pointerType);
@@ -154,17 +202,23 @@
         _ensureNativeTypeValid(pointerType, node);
         _ensureNativeTypeValid(nativeType, node);
         _ensureNativeTypeToDartType(nativeType, dartType, node);
+
+        final DartType nativeSignature =
+            (nativeType as InterfaceType).typeArguments[0];
+        return StaticInvocation(asFunctionInternal,
+            Arguments([node.receiver], types: [dartType, nativeSignature]));
       } else if (target == loadMethod) {
-        // TODO(dacoharkes): should load and store permitted to be generic?
+        // TODO(dacoharkes): should load and store be generic?
         // https://github.com/dart-lang/sdk/issues/35902
         DartType dartType = node.arguments.types[0];
         DartType pointerType = node.receiver.getStaticType(env);
         DartType nativeType = _pointerTypeGetTypeArg(pointerType);
 
         _ensureNativeTypeValid(pointerType, node);
-        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeValid(nativeType, node, allowStructs: true);
         _ensureNativeTypeSized(nativeType, node, target.name);
-        _ensureNativeTypeToDartType(nativeType, dartType, node);
+        _ensureNativeTypeToDartType(nativeType, dartType, node,
+            allowStructs: true);
       } else if (target == storeMethod) {
         // TODO(dacoharkes): should load and store permitted to be generic?
         // https://github.com/dart-lang/sdk/issues/35902
@@ -172,6 +226,8 @@
         DartType pointerType = node.receiver.getStaticType(env);
         DartType nativeType = _pointerTypeGetTypeArg(pointerType);
 
+        // TODO(36730): Allow storing an entire struct to memory.
+        // TODO(36780): Emit a better error message for the struct case.
         _ensureNativeTypeValid(pointerType, node);
         _ensureNativeTypeValid(nativeType, node);
         _ensureNativeTypeSized(nativeType, node, target.name);
@@ -183,30 +239,30 @@
   }
 
   DartType _pointerTypeGetTypeArg(DartType pointerType) {
-    if (pointerType is InterfaceType) {
-      InterfaceType superType =
-          hierarchy.getTypeAsInstanceOf(pointerType, pointerClass);
-      return superType?.typeArguments[0];
-    }
-    return null;
+    return pointerType is InterfaceType ? pointerType.typeArguments[0] : null;
   }
 
   void _ensureNativeTypeToDartType(
-      DartType nativeType, DartType dartType, Expression node) {
-    DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
-    if (dartType != shouldBeDartType) {
-      diagnosticReporter.report(
-          templateFfiTypeMismatch.withArguments(
-              dartType, shouldBeDartType, nativeType),
-          node.fileOffset,
-          1,
-          node.location.file);
-      throw _FfiStaticTypeError();
-    }
+      DartType containerTypeArg, DartType elementType, Expression node,
+      {bool allowStructs: false}) {
+    final DartType shouldBeElementType =
+        convertNativeTypeToDartType(containerTypeArg, allowStructs);
+    if (elementType == shouldBeElementType) return;
+    // Both subtypes and implicit downcasts are allowed statically.
+    if (env.isSubtypeOf(shouldBeElementType, elementType)) return;
+    if (env.isSubtypeOf(elementType, shouldBeElementType)) return;
+    diagnosticReporter.report(
+        templateFfiTypeMismatch.withArguments(
+            elementType, shouldBeElementType, containerTypeArg),
+        node.fileOffset,
+        1,
+        node.location.file);
+    throw _FfiStaticTypeError();
   }
 
-  void _ensureNativeTypeValid(DartType nativeType, Expression node) {
-    if (!_nativeTypeValid(nativeType)) {
+  void _ensureNativeTypeValid(DartType nativeType, Expression node,
+      {bool allowStructs: false}) {
+    if (!_nativeTypeValid(nativeType, allowStructs: allowStructs)) {
       diagnosticReporter.report(
           templateFfiTypeInvalid.withArguments(nativeType),
           node.fileOffset,
@@ -218,8 +274,8 @@
 
   /// The Dart type system does not enforce that NativeFunction return and
   /// parameter types are only NativeTypes, so we need to check this.
-  bool _nativeTypeValid(DartType nativeType) {
-    return convertNativeTypeToDartType(nativeType) != null;
+  bool _nativeTypeValid(DartType nativeType, {bool allowStructs: false}) {
+    return convertNativeTypeToDartType(nativeType, allowStructs) != null;
   }
 
   void _ensureNativeTypeSized(
@@ -238,7 +294,7 @@
   /// Consequently, [allocate], [Pointer.load], [Pointer.store], and
   /// [Pointer.elementAt] are not available.
   bool _nativeTypeSized(DartType nativeType) {
-    if (!(nativeType is InterfaceType)) {
+    if (nativeType is! InterfaceType) {
       return false;
     }
     Class nativeClass = (nativeType as InterfaceType).classNode;
@@ -246,6 +302,9 @@
         InterfaceType(nativeClass), InterfaceType(pointerClass))) {
       return true;
     }
+    if (hierarchy.isSubclassOf(nativeClass, structClass)) {
+      return true;
+    }
     NativeType nativeType_ = getType(nativeClass);
     if (nativeType_ == null) {
       return false;
@@ -280,6 +339,37 @@
     }
     return node is ConstantExpression;
   }
+
+  Class _extendsOrImplementsSealedClass(Class klass) {
+    final Class superClass = klass.supertype?.classNode;
+
+    // The Struct class can be extended, but subclasses of Struct cannot be (nor
+    // implemented).
+    if (klass != structClass && hierarchy.isSubtypeOf(klass, structClass)) {
+      return superClass != structClass ? superClass : null;
+    }
+
+    if (!nativeTypesClasses.contains(klass)) {
+      for (final parent in nativeTypesClasses) {
+        if (hierarchy.isSubtypeOf(klass, parent)) {
+          return parent;
+        }
+      }
+    }
+    return null;
+  }
+
+  void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
+    Class extended = _extendsOrImplementsSealedClass(klass);
+    if (extended != null) {
+      diagnosticReporter.report(
+          templateFfiExtendsOrImplementsSealedClass
+              .withArguments(extended.name),
+          klass.fileOffset,
+          1,
+          klass.location.file);
+    }
+  }
 }
 
 /// Used internally for abnormal control flow to prevent cascading error
diff --git a/pkg/vm/test/bytecode/gen_bytecode_test.dart b/pkg/vm/test/bytecode/gen_bytecode_test.dart
index 887a8a0..673a16e 100644
--- a/pkg/vm/test/bytecode/gen_bytecode_test.dart
+++ b/pkg/vm/test/bytecode/gen_bytecode_test.dart
@@ -10,6 +10,7 @@
 import 'package:kernel/kernel.dart';
 import 'package:test/test.dart';
 import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:vm/bytecode/options.dart' show BytecodeOptions;
 import 'package:vm/kernel_front_end.dart' show runWithFrontEndCompilerContext;
 
 import '../common_test_utils.dart';
@@ -34,7 +35,9 @@
     // Need to omit source positions from bytecode as they are different on
     // Linux and Windows (due to differences in newline characters).
     generateBytecode(component,
-        omitAssertSourcePositions: true, libraries: [mainLibrary]);
+        options: new BytecodeOptions(
+            enableAsserts: true, omitAssertSourcePositions: true),
+        libraries: [mainLibrary]);
   });
 
   component.libraries.removeWhere((lib) => lib != mainLibrary);
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 32e7ee9..e142924 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -75,7 +75,7 @@
   [38] = Reserved
   [39] = EndClosureFunctionScope
 }
-Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
+Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' async (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
 ClosureCode {
   EntryFixed           2, 4
   CheckStack           0
@@ -1708,7 +1708,7 @@
   [38] = Reserved
   [39] = EndClosureFunctionScope
 }
-Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int >
+Closure #lib::closure::'nested' async () -> dart:async::Future < dart:core::int >
 ClosureCode {
   EntryFixed           1, 4
   CheckStack           0
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index c6f5421..e1d3aae 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -87,11 +87,18 @@
 
 export DART_CONFIGURATION=${DART_CONFIGURATION:-ReleaseX64}
 BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
+DART_BINARY="$BIN_DIR"/dart
+PLAT_DIR=$(echo ${BIN_DIR} | sed -e 's/SIMARM_X64$/SIMARM/')
+
+PREBUILT_DART_BINARY="tools/sdks/dart-sdk/bin/dart"
+if [ -x "$PREBUILT_DART_BINARY" ]; then
+  DART_BINARY=$PREBUILT_DART_BINARY
+fi
 
 # Step 1: Generate Kernel binary from the input Dart source.
-"$BIN_DIR"/dart                                                                \
+"$DART_BINARY"                                                                 \
      "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart"                                   \
-     --platform "${BIN_DIR}/vm_platform_strong.dill"                           \
+     --platform "${PLAT_DIR}/vm_platform_strong.dill"                          \
      --aot                                                                     \
      "${GEN_KERNEL_OPTIONS[@]}"                                                \
      $PACKAGES                                                                 \
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 20419e7..529da63 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -146,6 +146,10 @@
     include_dirs += [ "../third_party/tcmalloc/gperftools/src" ]
   }
 
+  if (dart_platform_bytecode) {
+    defines += [ "DART_USE_BYTECODE" ]
+  }
+
   if (is_fuchsia) {
     if (using_fuchsia_sdk) {
       # TODO(chinmaygarde): Currenty these targets need to be build in the
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 36efb0d..2a0e13b 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -24,9 +24,9 @@
 extern const uint8_t kPlatformStrongDill[];
 extern intptr_t kPlatformStrongDillSize;
 #else
-const uint8_t* kKernelServiceDill = NULL;
+const uint8_t* kKernelServiceDill = nullptr;
 intptr_t kKernelServiceDillSize = 0;
-const uint8_t* kPlatformStrongDill = NULL;
+const uint8_t* kPlatformStrongDill = nullptr;
 intptr_t kPlatformStrongDillSize = 0;
 #endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
 }
@@ -65,8 +65,8 @@
 DFE::DFE()
     : use_dfe_(false),
       use_incremental_compiler_(false),
-      frontend_filename_(NULL),
-      application_kernel_buffer_(NULL),
+      frontend_filename_(nullptr),
+      application_kernel_buffer_(nullptr),
       application_kernel_buffer_size_(0) {
   // The run_vm_tests binary has the DART_PRECOMPILER set in order to allow unit
   // tests to exercise JIT and AOT pipeline.
@@ -75,26 +75,30 @@
   // need to fall back to the built-in one (if we have it).
 #if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) || defined(DART_NO_SNAPSHOT) ||   \
     (defined(DART_PRECOMPILER) && defined(TARGET_ARCH_X64))
-  kernel_service_dill_ = NULL;
+  kernel_service_dill_ = nullptr;
   kernel_service_dill_size_ = 0;
-  platform_strong_dill_ = NULL;
-  platform_strong_dill_size_ = 0;
+  platform_strong_dill_for_compilation_ = nullptr;
+  platform_strong_dill_for_compilation_size_ = 0;
+  platform_strong_dill_for_execution_ = nullptr;
+  platform_strong_dill_for_execution_size_ = 0;
 #else
   kernel_service_dill_ = kKernelServiceDill;
   kernel_service_dill_size_ = kKernelServiceDillSize;
-  platform_strong_dill_ = kPlatformStrongDill;
-  platform_strong_dill_size_ = kPlatformStrongDillSize;
+  platform_strong_dill_for_compilation_ = kPlatformStrongDill;
+  platform_strong_dill_for_compilation_size_ = kPlatformStrongDillSize;
+  platform_strong_dill_for_execution_ = kPlatformStrongDill;
+  platform_strong_dill_for_execution_size_ = kPlatformStrongDillSize;
 #endif
 }
 
 DFE::~DFE() {
-  if (frontend_filename_ != NULL) {
+  if (frontend_filename_ != nullptr) {
     free(frontend_filename_);
   }
-  frontend_filename_ = NULL;
+  frontend_filename_ = nullptr;
 
   free(application_kernel_buffer_);
-  application_kernel_buffer_ = NULL;
+  application_kernel_buffer_ = nullptr;
   application_kernel_buffer_size_ = 0;
 }
 
@@ -103,7 +107,7 @@
 }
 
 void DFE::Init(int target_abi_version) {
-  if (platform_strong_dill_ == NULL) {
+  if (platform_strong_dill_for_compilation_ == nullptr) {
     return;
   }
 
@@ -111,8 +115,8 @@
     return;
   }
 
-  Dart_SetDartLibrarySourcesKernel(platform_strong_dill_,
-                                   platform_strong_dill_size_);
+  Dart_SetDartLibrarySourcesKernel(platform_strong_dill_for_compilation_,
+                                   platform_strong_dill_for_compilation_size_);
 }
 
 bool DFE::InitKernelServiceAndPlatformDills(int target_abi_version) {
@@ -120,7 +124,7 @@
   const char kKernelServiceDillFile[] = "kernel_service.dill";
   const char kPlatformStrongDillFile[] = "vm_platform_strong.dill";
 
-  if (frontend_filename_ != NULL) {
+  if (frontend_filename_ != nullptr) {
     return true;
   }
 
@@ -129,18 +133,19 @@
       GetDirectoryPrefixFromExeName(), free);
 
   if (target_abi_version != Options::kAbiVersionUnset) {
-    kernel_service_dill_ = NULL;
+    kernel_service_dill_ = nullptr;
     kernel_service_dill_size_ = 0;
-    platform_strong_dill_ = NULL;
-    platform_strong_dill_size_ = 0;
+    platform_strong_dill_for_compilation_ = nullptr;
+    platform_strong_dill_for_compilation_size_ = 0;
 
     // Look in the old abi version directory.
     char* script_uri =
         Utils::SCreate("%s%s/%d/%s", dir_prefix.get(), kAbiVersionsDir,
                        target_abi_version, kPlatformStrongDillFile);
-    if (!TryReadKernelFile(script_uri,
-                           const_cast<uint8_t**>(&platform_strong_dill_),
-                           &platform_strong_dill_size_)) {
+    if (!TryReadKernelFile(
+            script_uri,
+            const_cast<uint8_t**>(&platform_strong_dill_for_compilation_),
+            &platform_strong_dill_for_compilation_size_)) {
       Syslog::PrintErr("Can't find old ABI dill file: %s\n", script_uri);
       free(script_uri);
       return false;
@@ -163,27 +168,27 @@
   // Look for the frontend snapshot next to the executable.
   frontend_filename_ =
       Utils::SCreate("%s%s", dir_prefix.get(), kKernelServiceSnapshot);
-  if (File::Exists(NULL, frontend_filename_)) {
+  if (File::Exists(nullptr, frontend_filename_)) {
     return true;
   }
   free(frontend_filename_);
-  frontend_filename_ = NULL;
+  frontend_filename_ = nullptr;
 
   // If the frontend snapshot is not found next to the executable, then look for
   // it in the "snapshots" directory.
   frontend_filename_ =
       Utils::SCreate("%s%s%s%s", dir_prefix.get(), kSnapshotsDirectory,
                      File::PathSeparator(), kKernelServiceSnapshot);
-  if (File::Exists(NULL, frontend_filename_)) {
+  if (File::Exists(nullptr, frontend_filename_)) {
     return true;
   }
   free(frontend_filename_);
-  frontend_filename_ = NULL;
+  frontend_filename_ = nullptr;
   return true;
 }
 
 bool DFE::KernelServiceDillAvailable() const {
-  return kernel_service_dill_ != NULL;
+  return kernel_service_dill_ != nullptr;
 }
 
 void DFE::LoadKernelService(const uint8_t** kernel_service_buffer,
@@ -194,13 +199,13 @@
 
 void DFE::LoadPlatform(const uint8_t** kernel_buffer,
                        intptr_t* kernel_buffer_size) {
-  *kernel_buffer = platform_strong_dill_;
-  *kernel_buffer_size = platform_strong_dill_size_;
+  *kernel_buffer = platform_strong_dill_for_execution_;
+  *kernel_buffer_size = platform_strong_dill_for_execution_size_;
 }
 
 bool DFE::CanUseDartFrontend() const {
-  return (platform_strong_dill_ != NULL) &&
-         (KernelServiceDillAvailable() || (frontend_filename() != NULL));
+  return (platform_strong_dill_for_compilation_ != nullptr) &&
+         (KernelServiceDillAvailable() || (frontend_filename() != nullptr));
 }
 
 class WindowsPathSanitizer {
@@ -217,7 +222,7 @@
     // (see builtin.dart#_sanitizeWindowsPath)
     intptr_t len = strlen(path);
     sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
-    if (sanitized_uri_ == NULL) {
+    if (sanitized_uri_ == nullptr) {
       OUT_OF_MEMORY();
     }
     char* s = sanitized_uri_;
@@ -251,9 +256,9 @@
   const char* sanitized_uri = script_uri;
 #endif
 
-  return Dart_CompileToKernel(sanitized_uri, platform_strong_dill_,
-                              platform_strong_dill_size_, incremental,
-                              package_config);
+  return Dart_CompileToKernel(
+      sanitized_uri, platform_strong_dill_for_compilation_,
+      platform_strong_dill_for_compilation_size_, incremental, package_config);
 }
 
 void DFE::CompileAndReadScript(const char* script_uri,
@@ -268,7 +273,7 @@
     case Dart_KernelCompilationStatus_Ok:
       *kernel_buffer = result.kernel;
       *kernel_buffer_size = result.kernel_size;
-      *error = NULL;
+      *error = nullptr;
       *exit_code = 0;
       break;
     case Dart_KernelCompilationStatus_Error:
@@ -298,18 +303,18 @@
   }
   if (!Dart_IsKernel(*kernel_buffer, *kernel_buffer_size)) {
     free(*kernel_buffer);
-    *kernel_buffer = NULL;
+    *kernel_buffer = nullptr;
     *kernel_buffer_size = -1;
   }
   int64_t end = Dart_TimelineGetMicros();
   Dart_TimelineEvent("DFE::ReadScript", start, end,
-                     Dart_Timeline_Event_Duration, 0, NULL, NULL);
+                     Dart_Timeline_Event_Duration, 0, nullptr, nullptr);
 }
 
 // Attempts to treat [buffer] as a in-memory kernel byte representation.
 // If successful, returns [true] and places [buffer] into [kernel_ir], byte size
 // into [kernel_ir_size].
-// If unsuccessful, returns [false], puts [NULL] into [kernel_ir], -1 into
+// If unsuccessful, returns [false], puts [nullptr] into [kernel_ir], -1 into
 // [kernel_ir_size].
 static bool TryReadSimpleKernelBuffer(uint8_t* buffer,
                                       uint8_t** p_kernel_ir,
@@ -325,7 +330,7 @@
     return true;
   }
   free(buffer);
-  *p_kernel_ir = NULL;
+  *p_kernel_ir = nullptr;
   *p_kernel_ir_size = -1;
   return false;
 }
@@ -337,12 +342,12 @@
 static bool TryReadFile(const char* script_uri, uint8_t** buffer,
                         intptr_t* size) {
   void* script_file = DartUtils::OpenFileUri(script_uri, false);
-  if (script_file == NULL) {
+  if (script_file == nullptr) {
     return false;
   }
   DartUtils::ReadFile(buffer, size, script_file);
   DartUtils::CloseFile(script_file);
-  if (*size <= 0 || buffer == NULL) {
+  if (*size <= 0 || buffer == nullptr) {
     return false;
   }
   return true;
@@ -359,7 +364,7 @@
 
   static void Add(KernelIRNode** p_head, KernelIRNode** p_tail,
                   KernelIRNode* node) {
-    if (*p_head == NULL) {
+    if (*p_head == nullptr) {
       *p_head = node;
     } else {
       (*p_tail)->next_ = node;
@@ -370,17 +375,17 @@
   static void Merge(KernelIRNode* head, uint8_t** p_bytes,
                              intptr_t* p_size) {
     intptr_t size = 0;
-    for (KernelIRNode* node = head; node != NULL; node = node->next_) {
+    for (KernelIRNode* node = head; node != nullptr; node = node->next_) {
       size = size + node->kernel_size_;
     }
 
     *p_bytes = reinterpret_cast<uint8_t*>(malloc(size));
-    if (*p_bytes == NULL) {
+    if (*p_bytes == nullptr) {
       OUT_OF_MEMORY();
     }
     uint8_t* p = *p_bytes;
     KernelIRNode* node = head;
-    while (node != NULL) {
+    while (node != nullptr) {
       memmove(p, node->kernel_ir_, node->kernel_size_);
       p += node->kernel_size_;
       KernelIRNode* next = node->next_;
@@ -391,7 +396,7 @@
 
   static void Delete(KernelIRNode* head) {
     KernelIRNode* node = head;
-    while (node != NULL) {
+    while (node != nullptr) {
       KernelIRNode* next = node->next_;
       delete (node);
       node = next;
@@ -402,7 +407,7 @@
   uint8_t* kernel_ir_;
   intptr_t kernel_size_;
 
-  KernelIRNode* next_ = NULL;
+  KernelIRNode* next_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(KernelIRNode);
 };
@@ -435,14 +440,14 @@
                                     uint8_t** kernel_ir,
                                     intptr_t* kernel_ir_size) {
   const char* kernel_list_dirname = DartUtils::DirName(script_uri);
-  KernelIRNode* kernel_ir_head = NULL;
-  KernelIRNode* kernel_ir_tail = NULL;
+  KernelIRNode* kernel_ir_head = nullptr;
+  KernelIRNode* kernel_ir_tail = nullptr;
   // Add all kernels to the linked list
   char* filename =
       reinterpret_cast<char*>(buffer + kernel_list_magic_number.length);
   intptr_t filename_size = buffer_size - kernel_list_magic_number.length;
   char* tail = reinterpret_cast<char*>(memchr(filename, '\n', filename_size));
-  while (tail != NULL) {
+  while (tail != nullptr) {
     *tail = '\0';
     intptr_t this_kernel_size;
     uint8_t* this_buffer;
@@ -461,7 +466,7 @@
                                    &this_kernel_size)) {
       // Abandon read if any of the files in the list are invalid.
       KernelIRNode::Delete(kernel_ir_head);
-      *kernel_ir = NULL;
+      *kernel_ir = nullptr;
       *kernel_ir_size = -1;
       return false;
     }
@@ -481,7 +486,7 @@
 bool DFE::TryReadKernelFile(const char* script_uri,
                             uint8_t** kernel_ir,
                             intptr_t* kernel_ir_size) {
-  *kernel_ir = NULL;
+  *kernel_ir = nullptr;
   *kernel_ir_size = -1;
 
   uint8_t* buffer;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 932936f..fc33e64 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -26,7 +26,7 @@
   char* frontend_filename() const { return frontend_filename_; }
 
   void set_frontend_filename(const char* name) {
-    if (frontend_filename_ != NULL) {
+    if (frontend_filename_ != nullptr) {
       free(frontend_filename_);
     }
     frontend_filename_ = strdup(name);
@@ -107,8 +107,10 @@
   char* frontend_filename_;
   const uint8_t* kernel_service_dill_;
   intptr_t kernel_service_dill_size_;
-  const uint8_t* platform_strong_dill_;
-  intptr_t platform_strong_dill_size_;
+  const uint8_t* platform_strong_dill_for_compilation_;
+  intptr_t platform_strong_dill_for_compilation_size_;
+  const uint8_t* platform_strong_dill_for_execution_;
+  intptr_t platform_strong_dill_for_execution_size_;
 
   // Kernel binary specified on the cmd line.
   uint8_t* application_kernel_buffer_;
diff --git a/runtime/bin/entrypoints_verification_test_extension.cc b/runtime/bin/entrypoints_verification_test_extension.cc
index 1f4eab6..c2c9adb 100644
--- a/runtime/bin/entrypoints_verification_test_extension.cc
+++ b/runtime/bin/entrypoints_verification_test_extension.cc
@@ -20,7 +20,8 @@
 
 #define ASSERT(E)                                                              \
   if (!(E)) {                                                                  \
-    fprintf(stderr, "Assertion \"" #E "\" failed!");                           \
+    fprintf(stderr, "Assertion \"" #E "\" failed at %s:%d!\n", __FILE__,       \
+            __LINE__);                                                         \
     abort();                                                                   \
   }
 
diff --git a/runtime/bin/ffi_test/ffi_test_functions.cc b/runtime/bin/ffi_test/ffi_test_functions.cc
index 91c7856..3350088 100644
--- a/runtime/bin/ffi_test/ffi_test_functions.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions.cc
@@ -632,13 +632,13 @@
   return 0;
 }
 
-DART_EXPORT int TestReturnNull(int32_t fn()) {
-  CHECK_EQ(fn(), 0);
+DART_EXPORT int TestReturnNull(int32_t (*fn)()) {
+  CHECK_EQ(fn(), 42);
   return 0;
 }
 
 DART_EXPORT int TestNullPointers(int64_t* (*fn)(int64_t* ptr)) {
-  CHECK_EQ(fn(nullptr), nullptr);
+  CHECK_EQ(fn(nullptr), reinterpret_cast<void*>(sizeof(int64_t)));
   int64_t p[2] = {0};
   CHECK_EQ(fn(p), p + 1);
   return 0;
@@ -662,6 +662,26 @@
   return 0;
 }
 
+DART_EXPORT int TestReturnVoid(int (*return_void)()) {
+  CHECK_EQ(return_void(), 0);
+  return 0;
+}
+
+DART_EXPORT int TestThrowExceptionDouble(double (*fn)()) {
+  CHECK_EQ(fn(), 42.0);
+  return 0;
+}
+
+DART_EXPORT int TestThrowExceptionPointer(void* (*fn)()) {
+  CHECK_EQ(fn(), reinterpret_cast<void*>(42));
+  return 0;
+}
+
+DART_EXPORT int TestThrowException(int (*fn)()) {
+  CHECK_EQ(fn(), 42);
+  return 0;
+}
+
 struct CallbackTestData {
   int success;
   void (*callback)();
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index c9edf66..622b326 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -12,7 +12,6 @@
 #include "include/dart_embedder_api.h"
 #include "include/dart_tools_api.h"
 
-#include "bin/abi_version.h"
 #include "bin/builtin.h"
 #include "bin/console.h"
 #include "bin/crashpad.h"
@@ -597,8 +596,7 @@
   Dart_Isolate isolate = NULL;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  if ((!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) ||
-      (Options::target_abi_version() != Options::kAbiVersionUnset)) {
+  if (!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) {
     const uint8_t* platform_kernel_buffer = NULL;
     intptr_t platform_kernel_buffer_size = 0;
     dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
diff --git a/runtime/bin/observatory_assets_empty.cc b/runtime/bin/observatory_assets_empty.cc
index e7e1738..5c79cdc 100644
--- a/runtime/bin/observatory_assets_empty.cc
+++ b/runtime/bin/observatory_assets_empty.cc
@@ -5,13 +5,7 @@
 // This file is linked into the dart executable when it does not have
 // Observatory baked in.
 
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
 #include <stdint.h>
-#endif
-#include <stddef.h>
 
 namespace dart {
 namespace bin {
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 70022e8..019522b 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -322,7 +322,7 @@
       dart::bin::DartUtils::OpenFile, dart::bin::DartUtils::ReadFile,
       dart::bin::DartUtils::WriteFile, dart::bin::DartUtils::CloseFile,
       nullptr /* entropy_source */, nullptr /* get_service_assets */,
-      start_kernel_isolate);
+      start_kernel_isolate, nullptr /* observer */);
   if (error != nullptr) {
     Syslog::PrintErr("Failed to initialize VM: %s\n", error);
     free(error);
diff --git a/runtime/bin/snapshot_empty.cc b/runtime/bin/snapshot_empty.cc
index 6629e07..b9c89be 100644
--- a/runtime/bin/snapshot_empty.cc
+++ b/runtime/bin/snapshot_empty.cc
@@ -5,17 +5,11 @@
 // This file is linked into the dart executable when it does not have a
 // snapshot linked into it.
 
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
 #include <stdint.h>
-#endif
-#include <stddef.h>
 
 extern "C" {
-const uint8_t* kDartVmSnapshotData = NULL;
-const uint8_t* kDartVmSnapshotInstructions = NULL;
-const uint8_t* kDartCoreIsolateSnapshotData = NULL;
-const uint8_t* kDartCoreIsolateSnapshotInstructions = NULL;
+const uint8_t* kDartVmSnapshotData = nullptr;
+const uint8_t* kDartVmSnapshotInstructions = nullptr;
+const uint8_t* kDartCoreIsolateSnapshotData = nullptr;
+const uint8_t* kDartCoreIsolateSnapshotInstructions = nullptr;
 }
diff --git a/runtime/bin/snapshot_in.cc b/runtime/bin/snapshot_in.cc
index 544d830..bc3047c 100644
--- a/runtime/bin/snapshot_in.cc
+++ b/runtime/bin/snapshot_in.cc
@@ -7,13 +7,7 @@
 // This file is linked into the dart executable when it has a snapshot
 // linked into it.
 
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
 #include <stdint.h>
-#endif
-#include <stddef.h>
 
 extern "C" {
 
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 9bb1b94..f5c3a9c 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -1985,6 +1985,6 @@
 
 @pragma("vm:entry-point", "call")
 Datagram _makeDatagram(
-    List<int> data, String address, Uint8List in_addr, int port) {
+    Uint8List data, String address, Uint8List in_addr, int port) {
   return new Datagram(data, new _InternetAddress(address, null, in_addr), port);
 }
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index ec77ddc..748ee68 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -298,8 +298,8 @@
 
       String result;
       try {
-        result = await _service.devfs.handlePutStream(
-            fsName, fsPath, fsUri, request.transform(GZIP.decoder));
+        result = await _service.devfs.handlePutStream(fsName, fsPath, fsUri,
+            request.cast<List<int>>().transform(GZIP.decoder));
       } catch (e) {
         request.response.statusCode = HttpStatus.internalServerError;
         request.response.write(e);
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 31a7d1b..66a90d8 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -15,6 +15,16 @@
  * This reference is generated from the header include/dart_api.h.
  */
 
+/* __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
+ * enable platform independent printf format specifiers. */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
+
 #ifdef __cplusplus
 #define DART_EXTERN_C extern "C"
 #else
@@ -24,32 +34,12 @@
 #if defined(__CYGWIN__)
 #error Tool chain and platform not supported.
 #elif defined(_WIN32)
-// Define bool if necessary.
-#ifndef __cplusplus
-typedef unsigned __int8 bool;
-#endif
-// Define integer types.
-typedef signed __int8 int8_t;
-typedef signed __int16 int16_t;
-typedef signed __int32 int32_t;
-typedef signed __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
 #if defined(DART_SHARED_LIB)
 #define DART_EXPORT DART_EXTERN_C __declspec(dllexport)
 #else
 #define DART_EXPORT DART_EXTERN_C
 #endif
 #else
-/* __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
- * enable platform independent printf format specifiers. */
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
-#include <inttypes.h>
-#include <stdbool.h>
 #if __GNUC__ >= 4
 #if defined(DART_SHARED_LIB)
 #define DART_EXPORT                                                            \
@@ -70,8 +60,6 @@
 #define DART_WARN_UNUSED_RESULT
 #endif
 
-#include <assert.h>
-
 /*
  * =======
  * Handles
@@ -714,7 +702,31 @@
  * The current version of the Dart_InitializeFlags. Should be incremented every
  * time Dart_InitializeFlags changes in a binary incompatible way.
  */
-#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000003)
+#define DART_INITIALIZE_PARAMS_CURRENT_VERSION (0x00000004)
+
+/** Forward declaration */
+struct Dart_CodeObserver;
+
+/**
+ * Callback provided by the embedder that is used by the VM to notify on code
+ * object creation, *before* it is invoked the first time.
+ * This is useful for embedders wanting to e.g. keep track of PCs beyond
+ * the lifetime of the garbage collected code objects.
+ * Note that an address range may be used by more than one code object over the
+ * lifecycle of a process. Clients of this function should record timestamps for
+ * these compilation events and when collecting PCs to disambiguate reused
+ * address ranges.
+ */
+typedef void (*Dart_OnNewCodeCallback)(struct Dart_CodeObserver* observer,
+                                       const char* name,
+                                       uintptr_t base,
+                                       uintptr_t size);
+
+typedef struct Dart_CodeObserver {
+  void* data;
+
+  Dart_OnNewCodeCallback on_new_code;
+} Dart_CodeObserver;
 
 /**
  * Describes how to initialize the VM. Used with Dart_Initialize.
@@ -736,6 +748,8 @@
  * \param get_service_assets A function to be called by the service isolate when
  *    it requires the vmservice assets archive.
  *    See Dart_GetVMServiceAssetsArchive.
+ * \param code_observer An external code observer callback function.
+ *    The observer can be invoked as early as during the Dart_Initialize() call.
  */
 typedef struct {
   int32_t version;
@@ -752,6 +766,7 @@
   Dart_EntropySource entropy_source;
   Dart_GetVMServiceAssetsArchive get_service_assets;
   bool start_kernel_isolate;
+  Dart_CodeObserver* code_observer;
 } Dart_InitializeParams;
 
 /**
diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc
index fb2f903..0705214 100644
--- a/runtime/lib/double.cc
+++ b/runtime/lib/double.cc
@@ -4,7 +4,7 @@
 
 #include "vm/bootstrap_natives.h"
 
-#include "platform/math.h"
+#include <math.h>
 
 #include "vm/dart_entry.h"
 #include "vm/double_conversion.h"
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
index f2ac373..9fc29cf 100644
--- a/runtime/lib/ffi.cc
+++ b/runtime/lib/ffi.cc
@@ -8,10 +8,12 @@
 #include "platform/globals.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/class_finalizer.h"
+#include "vm/class_id.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/ffi.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/exceptions.h"
+#include "vm/flags.h"
 #include "vm/log.h"
 #include "vm/native_arguments.h"
 #include "vm/native_entry.h"
@@ -26,66 +28,14 @@
 // Some checks are only performed at runtime to allow for generic code, these
 // throw ArgumentExceptions.
 
-static void ThrowTypeArgumentError(const AbstractType& type_arg,
-                                   const char* expected) {
-  const String& error = String::Handle(String::NewFormatted(
-      "Type argument (%s) should be a %s",
-      String::Handle(type_arg.UserVisibleName()).ToCString(), expected));
-  Exceptions::ThrowArgumentError(error);
-}
-
 static bool IsPointerType(const AbstractType& type) {
-  // Do a fast check for predefined types.
-  classid_t type_cid = type.type_class_id();
-  if (RawObject::IsFfiPointerClassId(type_cid)) {
-    return true;
-  }
-
-  // Do a slow check for subtyping.
-  const Class& pointer_class =
-      Class::Handle(Isolate::Current()->object_store()->ffi_pointer_class());
-  AbstractType& pointer_type =
-      AbstractType::Handle(pointer_class.DeclarationType());
-  pointer_type = pointer_type.InstantiateFrom(Object::null_type_arguments(),
-                                              Object::null_type_arguments(),
-                                              kNoneFree, NULL, Heap::kNew);
-  ASSERT(pointer_type.IsInstantiated());
-  ASSERT(type.IsInstantiated());
-  return type.IsSubtypeOf(pointer_type, Heap::kNew);
-}
-
-static bool IsConcreteNativeType(const AbstractType& type) {
-  // Do a fast check for predefined types.
-  classid_t type_cid = type.type_class_id();
-  if (RawObject::IsFfiNativeTypeTypeClassId(type_cid)) {
-    return false;
-  }
-  if (RawObject::IsFfiTypeClassId(type_cid)) {
-    return true;
-  }
-
-  // Do a slow check for subtyping.
-  const Class& native_type_class = Class::Handle(
-      Isolate::Current()->object_store()->ffi_native_type_class());
-  AbstractType& native_type_type =
-      AbstractType::Handle(native_type_class.DeclarationType());
-  return type.IsSubtypeOf(native_type_type, Heap::kNew);
-}
-
-static void CheckIsConcreteNativeType(const AbstractType& type) {
-  if (!IsConcreteNativeType(type)) {
-    ThrowTypeArgumentError(type, "concrete sub type of NativeType");
-  }
-}
-
-static bool IsNativeFunction(const AbstractType& type_arg) {
-  classid_t type_cid = type_arg.type_class_id();
-  return RawObject::IsFfiTypeNativeFunctionClassId(type_cid);
+  return RawObject::IsFfiPointerClassId(type.type_class_id());
 }
 
 static void CheckSized(const AbstractType& type_arg) {
-  classid_t type_cid = type_arg.type_class_id();
-  if (RawObject::IsFfiTypeVoidClassId(type_cid) ||
+  const classid_t type_cid = type_arg.type_class_id();
+  if (RawObject::IsFfiNativeTypeTypeClassId(type_cid) ||
+      RawObject::IsFfiTypeVoidClassId(type_cid) ||
       RawObject::IsFfiTypeNativeFunctionClassId(type_cid)) {
     const String& error = String::Handle(String::NewFormatted(
         "%s does not have a predefined size (@unsized). "
@@ -98,6 +48,8 @@
   }
 }
 
+enum class FfiVariance { kCovariant = 0, kContravariant = 1 };
+
 // Checks that a dart type correspond to a [NativeType].
 // Because this is checked already in a kernel transformation, it does not throw
 // an ArgumentException but a boolean which should be asserted.
@@ -114,11 +66,12 @@
 // [Double]                             -> [double]
 // [Float]                              -> [double]
 // [Pointer]<T>                         -> [Pointer]<T>
-// T extends [Pointer]                  -> T
+// T extends [Struct]                   -> T
 // [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
 //    where DartRepresentationOf(Tn) -> Sn
 static bool DartAndCTypeCorrespond(const AbstractType& native_type,
-                                   const AbstractType& dart_type) {
+                                   const AbstractType& dart_type,
+                                   FfiVariance variance) {
   classid_t native_type_cid = native_type.type_class_id();
   if (RawObject::IsFfiTypeIntClassId(native_type_cid)) {
     return dart_type.IsSubtypeOf(AbstractType::Handle(Type::IntType()),
@@ -129,7 +82,11 @@
                                  Heap::kNew);
   }
   if (RawObject::IsFfiPointerClassId(native_type_cid)) {
-    return native_type.Equals(dart_type) || dart_type.IsNullType();
+    return (variance == FfiVariance::kCovariant &&
+            dart_type.IsSubtypeOf(native_type, Heap::kNew)) ||
+           (variance == FfiVariance::kContravariant &&
+            native_type.IsSubtypeOf(dart_type, Heap::kNew)) ||
+           dart_type.IsNullType();
   }
   if (RawObject::IsFfiTypeNativeFunctionClassId(native_type_cid)) {
     if (!dart_type.IsFunctionType()) {
@@ -142,7 +99,8 @@
     if (!nativefunction_type_arg.IsFunctionType()) {
       return false;
     }
-    Function& dart_function = Function::Handle(((Type&)dart_type).signature());
+    Function& dart_function =
+        Function::Handle((Type::Cast(dart_type)).signature());
     if (dart_function.NumTypeParameters() != 0 ||
         dart_function.HasOptionalPositionalParameters() ||
         dart_function.HasOptionalNamedParameters()) {
@@ -161,13 +119,14 @@
     }
     if (!DartAndCTypeCorrespond(
             AbstractType::Handle(nativefunction_function.result_type()),
-            AbstractType::Handle(dart_function.result_type()))) {
+            AbstractType::Handle(dart_function.result_type()), variance)) {
       return false;
     }
     for (intptr_t i = 0; i < dart_function.NumParameters(); i++) {
       if (!DartAndCTypeCorrespond(
               AbstractType::Handle(nativefunction_function.ParameterTypeAt(i)),
-              AbstractType::Handle(dart_function.ParameterTypeAt(i)))) {
+              AbstractType::Handle(dart_function.ParameterTypeAt(i)),
+              variance)) {
         return false;
       }
     }
@@ -175,20 +134,21 @@
   return true;
 }
 
-// The following functions are runtime checks on arguments.
-
-// Note that expected_from and expected_to are inclusive.
-static void CheckRange(const Integer& argument_value,
-                       intptr_t expected_from,
-                       intptr_t expected_to,
-                       const char* argument_name) {
-  int64_t value = argument_value.AsInt64Value();
-  if (value < expected_from || expected_to < value) {
-    Exceptions::ThrowRangeError(argument_name, argument_value, expected_from,
-                                expected_to);
+static void CheckDartAndCTypeCorrespond(const AbstractType& native_type,
+                                        const AbstractType& dart_type,
+                                        FfiVariance variance) {
+  if (!DartAndCTypeCorrespond(native_type, dart_type, variance)) {
+    const String& error = String::Handle(String::NewFormatted(
+        "Expected type '%s' to be different, it should be "
+        "DartRepresentationOf('%s').",
+        String::Handle(dart_type.UserVisibleName()).ToCString(),
+        String::Handle(native_type.UserVisibleName()).ToCString()));
+    Exceptions::ThrowArgumentError(error);
   }
 }
 
+// The following functions are runtime checks on arguments.
+
 static const Pointer& AsPointer(const Instance& instance) {
   if (!instance.IsPointer()) {
     const String& error = String::Handle(String::NewFormatted(
@@ -216,50 +176,50 @@
   return Double::Cast(instance);
 }
 
+// Calcuate the size of a native type.
+//
+// You must check [IsConcreteNativeType] and [CheckSized] first to verify that
+// this type has a defined size.
+static size_t SizeOf(const AbstractType& type) {
+  if (RawObject::IsFfiTypeClassId(type.type_class_id())) {
+    return compiler::ffi::ElementSizeInBytes(type.type_class_id());
+  } else {
+    Class& struct_class = Class::Handle(type.type_class());
+    Object& result = Object::Handle(
+        struct_class.InvokeGetter(Symbols::SizeOfStructField(),
+                                  /*throw_nsm_if_absent=*/false,
+                                  /*respect_reflectable=*/false));
+    ASSERT(!result.IsNull() && result.IsInteger());
+    return Integer::Cast(result).AsInt64Value();
+  }
+}
+
 // The remainder of this file implements the dart:ffi native methods.
 
 DEFINE_NATIVE_ENTRY(Ffi_allocate, 1, 1) {
-  // TODO(dacoharkes): When we have a way of determining the size of structs in
-  // the VM, change the signature so we can allocate structs, subtype of
-  // Pointer. https://github.com/dart-lang/sdk/issues/35782
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
 
-  CheckIsConcreteNativeType(type_arg);
   CheckSized(type_arg);
+  size_t element_size = SizeOf(type_arg);
 
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, argCount, arguments->NativeArgAt(0));
   int64_t count = argCount.AsInt64Value();
-  classid_t type_cid = type_arg.type_class_id();
-  int64_t max_count = INTPTR_MAX / compiler::ffi::ElementSizeInBytes(type_cid);
-  CheckRange(argCount, 1, max_count, "count");
-
-  size_t size = compiler::ffi::ElementSizeInBytes(type_cid) * count;
-  uint64_t memory = reinterpret_cast<uint64_t>(malloc(size));
+  size_t size = element_size * count;  // Truncates overflow.
+  size_t memory = reinterpret_cast<size_t>(malloc(size));
   if (memory == 0) {
     const String& error = String::Handle(String::NewFormatted(
         "allocating (%" Pd ") bytes of memory failed", size));
     Exceptions::ThrowArgumentError(error);
   }
 
-  RawPointer* result = Pointer::New(
-      type_arg, Integer::Handle(zone, Integer::NewFromUint64(memory)));
+  RawPointer* result = Pointer::New(type_arg, memory);
   return result;
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
-  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
-  AbstractType& native_type = AbstractType::Handle(
-      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
-  CheckIsConcreteNativeType(native_type);
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg_ptr, arguments->NativeArgAt(0));
-
-  // TODO(dacoharkes): should this return NULL if address is 0?
-  // https://github.com/dart-lang/sdk/issues/35756
-
-  RawPointer* result =
-      Pointer::New(native_type, arg_ptr, type_arg.type_class_id());
-  return result;
+  return Pointer::New(type_arg, arg_ptr.AsInt64Value());
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_elementAt, 0, 2) {
@@ -268,14 +228,9 @@
   AbstractType& pointer_type_arg =
       AbstractType::Handle(zone, pointer.type_argument());
   CheckSized(pointer_type_arg);
-
-  classid_t class_id = pointer_type_arg.type_class_id();
-  Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
-  address = Integer::New(address.AsInt64Value() +
-                         index.AsInt64Value() *
-                             compiler::ffi::ElementSizeInBytes(class_id));
-  RawPointer* result = Pointer::New(pointer_type_arg, address);
-  return result;
+  return Pointer::New(pointer_type_arg,
+                      pointer.NativeAddress() +
+                          index.AsInt64Value() * SizeOf(pointer_type_arg));
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_offsetBy, 0, 2) {
@@ -284,64 +239,35 @@
   AbstractType& pointer_type_arg =
       AbstractType::Handle(pointer.type_argument());
 
-  intptr_t address =
-      Integer::Handle(zone, pointer.GetCMemoryAddress()).AsInt64Value() +
-      offset.AsInt64Value();
-  RawPointer* result = Pointer::New(
-      pointer_type_arg, Integer::Handle(zone, Integer::New(address)));
-  return result;
+  return Pointer::New(pointer_type_arg,
+                      pointer.NativeAddress() + offset.AsInt64Value());
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
-  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
-  AbstractType& native_type = AbstractType::Handle(
-      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
-  CheckIsConcreteNativeType(native_type);
-
-  const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
-  RawPointer* result =
-      Pointer::New(native_type, address, type_arg.type_class_id());
-  return result;
+  return Pointer::New(type_arg, pointer.NativeAddress());
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_free, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
 
-  const Integer& address = Integer::Handle(zone, pointer.GetCMemoryAddress());
-  free(reinterpret_cast<void*>(address.AsInt64Value()));
-  pointer.SetCMemoryAddress(Integer::Handle(zone, Integer::New(0)));
+  free(reinterpret_cast<void*>(pointer.NativeAddress()));
+  pointer.SetNativeAddress(0);
+
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_address, 0, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
-  return pointer.GetCMemoryAddress();
+  return Integer::New(pointer.NativeAddress());
 }
 
-static RawInstance* BoxLoadPointer(Zone* zone,
-                                   uint8_t* address,
-                                   const AbstractType& instance_type_arg,
-                                   intptr_t type_cid) {
-  // TODO(dacoharkes): should this return NULL if addres is 0?
-  // https://github.com/dart-lang/sdk/issues/35756
-  if (address == nullptr) {
-    return Instance::null();
-  }
-  AbstractType& type_arg =
-      AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
-                               .TypeAt(Pointer::kNativeTypeArgPos));
-  return Pointer::New(
-      type_arg,
-      Integer::Handle(zone, Integer::New(reinterpret_cast<intptr_t>(address))),
-      type_cid);
-}
-
-static RawInstance* LoadValue(Zone* zone,
-                              uint8_t* address,
-                              const AbstractType& instance_type_arg) {
+static RawObject* LoadValue(Zone* zone,
+                            const Pointer& target,
+                            const AbstractType& instance_type_arg) {
   classid_t type_cid = instance_type_arg.type_class_id();
+  size_t address = target.NativeAddress();
   switch (type_cid) {
     case kFfiInt8Cid:
       return Integer::New(*reinterpret_cast<int8_t*>(address));
@@ -365,11 +291,39 @@
       return Double::New(*reinterpret_cast<float_t*>(address));
     case kFfiDoubleCid:
       return Double::New(*reinterpret_cast<double_t*>(address));
-    case kFfiPointerCid:
-    default:
-      ASSERT(IsPointerType(instance_type_arg));
-      return BoxLoadPointer(zone, *reinterpret_cast<uint8_t**>(address),
-                            instance_type_arg, type_cid);
+    default: {
+      if (IsPointerType(instance_type_arg)) {
+        const AbstractType& type_arg = AbstractType::Handle(
+            TypeArguments::Handle(instance_type_arg.arguments())
+                .TypeAt(Pointer::kNativeTypeArgPos));
+        return Pointer::New(type_arg, reinterpret_cast<size_t>(
+                                          *reinterpret_cast<void**>(address)));
+      } else {
+        // Result is a struct class -- find <class name>.#fromPointer
+        // constructor and call it.
+        Class& cls = Class::Handle(zone, instance_type_arg.type_class());
+        const Function& constructor =
+            Function::Handle(cls.LookupFunctionAllowPrivate(String::Handle(
+                String::Concat(String::Handle(String::Concat(
+                                   String::Handle(cls.Name()), Symbols::Dot())),
+                               Symbols::StructFromPointer()))));
+        ASSERT(!constructor.IsNull());
+        ASSERT(constructor.IsGenerativeConstructor());
+        ASSERT(!Object::Handle(constructor.VerifyCallEntryPoint()).IsError());
+        Instance& new_object = Instance::Handle(Instance::New(cls));
+        new_object.SetTypeArguments(
+            TypeArguments::Handle(instance_type_arg.arguments()));
+        ASSERT(cls.is_allocated() ||
+               Dart::vm_snapshot_kind() != Snapshot::kFullAOT);
+        const Array& args = Array::Handle(zone, Array::New(2));
+        args.SetAt(0, new_object);
+        args.SetAt(1, target);
+        Object& constructorResult =
+            Object::Handle(DartEntry::InvokeFunction(constructor, args));
+        ASSERT(!constructorResult.IsError());
+        return new_object.raw();
+      }
+    }
   }
 }
 
@@ -379,19 +333,17 @@
   AbstractType& pointer_type_arg =
       AbstractType::Handle(pointer.type_argument());
   CheckSized(pointer_type_arg);
-  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
+  CheckDartAndCTypeCorrespond(pointer_type_arg, type_arg,
+                              FfiVariance::kContravariant);
 
-  uint8_t* address = reinterpret_cast<uint8_t*>(
-      Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
-  return LoadValue(zone, address, pointer_type_arg);
+  return LoadValue(zone, pointer, pointer_type_arg);
 }
 
 static void StoreValue(Zone* zone,
                        const Pointer& pointer,
                        classid_t type_cid,
                        const Instance& new_value) {
-  uint8_t* address = reinterpret_cast<uint8_t*>(
-      Integer::Handle(pointer.GetCMemoryAddress()).AsInt64Value());
+  uint8_t* const address = reinterpret_cast<uint8_t*>(pointer.NativeAddress());
   AbstractType& pointer_type_arg =
       AbstractType::Handle(pointer.type_argument());
   switch (type_cid) {
@@ -436,20 +388,16 @@
     case kFfiDoubleCid:
       *reinterpret_cast<double*>(address) = AsDouble(new_value).value();
       break;
-    case kFfiPointerCid:
-    default: {
+    case kFfiPointerCid: {
       ASSERT(IsPointerType(pointer_type_arg));
-      intptr_t new_value_unwrapped = 0;
-      if (!new_value.IsNull()) {
-        ASSERT(new_value.IsPointer());
-        new_value_unwrapped =
-            Integer::Handle(AsPointer(new_value).GetCMemoryAddress())
-                .AsInt64Value();
-        // TODO(dacoharkes): should this return NULL if addres is 0?
-        // https://github.com/dart-lang/sdk/issues/35756
-      }
-      *reinterpret_cast<intptr_t*>(address) = new_value_unwrapped;
-    } break;
+      ASSERT(new_value.IsPointer());
+      const void* const stored =
+          reinterpret_cast<void*>(AsPointer(new_value).NativeAddress());
+      *reinterpret_cast<const void**>(address) = stored;
+      break;
+    }
+    default:
+      UNREACHABLE();
   }
 }
 
@@ -460,7 +408,14 @@
   AbstractType& pointer_type_arg =
       AbstractType::Handle(pointer.type_argument());
   CheckSized(pointer_type_arg);
-  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, arg_type));
+  CheckDartAndCTypeCorrespond(pointer_type_arg, arg_type,
+                              FfiVariance::kCovariant);
+
+  if (new_value.IsNull()) {
+    const String& error = String::Handle(
+        String::NewFormatted("Argument to Pointer.store is null."));
+    Exceptions::ThrowArgumentError(error);
+  }
 
   classid_t type_cid = pointer_type_arg.type_class_id();
   StoreValue(zone, pointer, type_cid, new_value);
@@ -469,96 +424,17 @@
 
 DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) {
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
-  CheckIsConcreteNativeType(type_arg);
   CheckSized(type_arg);
 
-  classid_t type_cid = type_arg.type_class_id();
-  return Smi::New(compiler::ffi::ElementSizeInBytes(type_cid));
+  return Integer::New(SizeOf(type_arg));
 }
 
-// TODO(dacoharkes): Cache the trampolines.
-// We can possibly address simultaniously with 'precaching' in AOT.
-static RawFunction* TrampolineFunction(const Function& dart_signature,
-                                       const Function& c_signature) {
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  String& name =
-      String::ZoneHandle(Symbols::New(Thread::Current(), "FfiTrampoline"));
-  const Library& lib = Library::Handle(Library::FfiLibrary());
-  const Class& owner_class = Class::Handle(lib.toplevel_class());
-  Function& function =
-      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
-                                           /*is_static=*/true,
-                                           /*is_const=*/false,
-                                           /*is_abstract=*/false,
-                                           /*is_external=*/false,
-                                           /*is_native=*/false, owner_class,
-                                           TokenPosition::kMinSource));
-  function.set_is_debuggable(false);
-  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
-  function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
-  function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
-
-  // The signature function won't have any names for the parameters. We need to
-  // assign unique names for scope building and error messages.
-  const intptr_t num_params = dart_signature.num_fixed_parameters();
-  const Array& parameter_names = Array::Handle(Array::New(num_params));
-  for (intptr_t i = 0; i < num_params; ++i) {
-    if (i == 0) {
-      name = Symbols::ClosureParameter().raw();
-    } else {
-      name = Symbols::NewFormatted(thread, ":ffiParam%" Pd, i);
-    }
-    parameter_names.SetAt(i, name);
-  }
-  function.set_parameter_names(parameter_names);
-  function.SetFfiCSignature(c_signature);
-
-  return function.raw();
-}
-
-DEFINE_NATIVE_ENTRY(Ffi_asFunction, 1, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
-  AbstractType& pointer_type_arg =
-      AbstractType::Handle(pointer.type_argument());
-  ASSERT(IsNativeFunction(pointer_type_arg));
-  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
-  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
-
-  Function& dart_signature = Function::Handle(Type::Cast(type_arg).signature());
-  TypeArguments& nativefunction_type_args =
-      TypeArguments::Handle(pointer_type_arg.arguments());
-  AbstractType& nativefunction_type_arg =
-      AbstractType::Handle(nativefunction_type_args.TypeAt(0));
-  Function& c_signature =
-      Function::Handle(Type::Cast(nativefunction_type_arg).signature());
-  Function& function =
-      Function::Handle(TrampolineFunction(dart_signature, c_signature));
-
-  // Set the c function pointer in the context of the closure rather than in
-  // the function so that we can reuse the function for each c function with
-  // the same signature.
-  Context& context = Context::Handle(Context::New(1));
-  context.SetAt(0, Integer::Handle(zone, pointer.GetCMemoryAddress()));
-
-  RawClosure* raw_closure =
-      Closure::New(Object::null_type_arguments(), Object::null_type_arguments(),
-                   function, context, Heap::kOld);
-
-  return raw_closure;
-}
-
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER) &&        \
+    !defined(TARGET_ARCH_DBC)
 // Generates assembly to trampoline from native code into Dart.
 static uword CompileNativeCallback(const Function& c_signature,
-                                   const Function& dart_target) {
-#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
-  UNREACHABLE();
-#elif defined(TARGET_ARCH_DBC)
-  // https://github.com/dart-lang/sdk/issues/35774
-  // FFI is supported, but callbacks are not.
-  Exceptions::ThrowUnsupportedError(
-      "FFI callbacks are not yet supported on DBC.");
-#else
+                                   const Function& dart_target,
+                                   const Instance& exceptional_return) {
   Thread* const thread = Thread::Current();
   const int32_t callback_id = thread->AllocateFfiCallbackId();
 
@@ -566,10 +442,9 @@
   // library. Note that these functions will never be invoked by Dart, so it
   // doesn't matter that they all have the same name.
   Zone* const Z = thread->zone();
-  const String& name =
-      String::ZoneHandle(Symbols::New(Thread::Current(), "FfiCallback"));
-  const Library& lib = Library::Handle(Library::FfiLibrary());
-  const Class& owner_class = Class::Handle(lib.toplevel_class());
+  const String& name = String::Handle(Symbols::New(thread, "FfiCallback"));
+  const Library& lib = Library::Handle(Z, Library::FfiLibrary());
+  const Class& owner_class = Class::Handle(Z, lib.toplevel_class());
   const Function& function =
       Function::Handle(Z, Function::New(name, RawFunction::kFfiTrampoline,
                                         /*is_static=*/true,
@@ -586,6 +461,33 @@
   function.SetFfiCallbackId(callback_id);
   function.SetFfiCallbackTarget(dart_target);
 
+  // We require that the exceptional return value for functions returning 'Void'
+  // must be 'null', since native code should not look at the result.
+  if (compiler::ffi::NativeTypeIsVoid(
+          AbstractType::Handle(c_signature.result_type())) &&
+      !exceptional_return.IsNull()) {
+    Exceptions::ThrowUnsupportedError(
+        "Only 'null' may be used as the exceptional return value for a "
+        "callback returning void.");
+  }
+
+  // We need to load the exceptional return value as a constant in the generated
+  // function. This means we need to ensure that it's in old space and has no
+  // (transitively) mutable fields. This is done by checking (asserting) that
+  // it's a built-in FFI class, whose fields are all immutable, or a
+  // user-defined Pointer class, which has no fields.
+  //
+  // TODO(36730): We'll need to extend this when we support passing/returning
+  // structs by value.
+  ASSERT(exceptional_return.IsNull() || exceptional_return.IsNumber() ||
+         exceptional_return.IsPointer());
+  if (!exceptional_return.IsSmi() && exceptional_return.IsNew()) {
+    function.SetFfiCallbackExceptionalReturn(
+        Instance::Handle(exceptional_return.CopyShallowToOldSpace(thread)));
+  } else {
+    function.SetFfiCallbackExceptionalReturn(exceptional_return);
+  }
+
   // We compile the callback immediately because we need to return a pointer to
   // the entry-point. Native calls do not use patching like Dart calls, so we
   // cannot compile it lazily.
@@ -600,23 +502,72 @@
   thread->SetFfiCallbackCode(callback_id, code);
 
   return code.EntryPoint();
+}
+#endif
+
+// Static invocations to this method are translated directly in streaming FGB
+// and bytecode FGB. However, we can still reach this entrypoint in the bytecode
+// interpreter.
+DEFINE_NATIVE_ENTRY(Ffi_asFunctionInternal, 2, 1) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+  UNREACHABLE();
+#else
+  ASSERT(FLAG_enable_interpreter);
+
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NATIVE_TYPE_ARGUMENT(dart_type, arguments->NativeTypeArgAt(0));
+  GET_NATIVE_TYPE_ARGUMENT(native_type, arguments->NativeTypeArgAt(1));
+
+  const Function& dart_signature =
+      Function::Handle(zone, Type::Cast(dart_type).signature());
+  const Function& native_signature =
+      Function::Handle(zone, Type::Cast(native_type).signature());
+  const Function& function = Function::Handle(
+      compiler::ffi::TrampolineFunction(dart_signature, native_signature));
+
+  // Set the c function pointer in the context of the closure rather than in
+  // the function so that we can reuse the function for each c function with
+  // the same signature.
+  const Context& context = Context::Handle(Context::New(1));
+  context.SetAt(0,
+                Integer::Handle(zone, Integer::New(pointer.NativeAddress())));
+
+  return Closure::New(Object::null_type_arguments(),
+                      Object::null_type_arguments(), function, context,
+                      Heap::kOld);
 #endif
 }
 
-DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
+DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 2) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER) ||          \
+    defined(TARGET_ARCH_DBC)
+  // https://github.com/dart-lang/sdk/issues/37295
+  // FFI is supported, but callbacks are not.
+  Exceptions::ThrowUnsupportedError(
+      "FFI callbacks are not yet supported in AOT or on DBC.");
+#else
   GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Instance, exceptional_return,
+                               arguments->NativeArgAt(1));
+
+  if (!type_arg.IsInstantiated() || !type_arg.IsFunctionType()) {
+    // TODO(35902): Remove this when dynamic invocations of fromFunction are
+    // prohibited.
+    Exceptions::ThrowUnsupportedError(
+        "Type argument to fromFunction must an instantiated function type.");
+  }
 
   const Function& native_signature =
-      Function::Handle(((Type&)type_arg).signature());
+      Function::Handle(Type::Cast(type_arg).signature());
   Function& func = Function::Handle(closure.function());
   TypeArguments& type_args = TypeArguments::Handle(zone);
   type_args = TypeArguments::New(1);
   type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
   type_args = type_args.Canonicalize();
 
-  Class& native_function_class = Class::Handle(
-      Isolate::Current()->class_table()->At(kFfiNativeFunctionCid));
+  Class& native_function_class =
+      Class::Handle(isolate->class_table()->At(kFfiNativeFunctionCid));
   native_function_class.EnsureIsFinalized(Thread::Current());
 
   Type& native_function_type = Type::Handle(
@@ -635,12 +586,26 @@
   func = func.parent_function();
   ASSERT(func.is_static());
 
-  const uword address = CompileNativeCallback(native_signature, func);
+  const AbstractType& return_type =
+      AbstractType::Handle(native_signature.result_type());
+  if (compiler::ffi::NativeTypeIsVoid(return_type)) {
+    if (!exceptional_return.IsNull()) {
+      const String& error = String::Handle(
+          String::NewFormatted("Exceptional return argument to 'fromFunction' "
+                               "must be null for functions returning void."));
+      Exceptions::ThrowArgumentError(error);
+    }
+  } else if (!compiler::ffi::NativeTypeIsPointer(return_type) &&
+             exceptional_return.IsNull()) {
+    const String& error = String::Handle(String::NewFormatted(
+        "Exceptional return argument to 'fromFunction' must not be null."));
+    Exceptions::ThrowArgumentError(error);
+  }
 
-  const Pointer& result = Pointer::Handle(Pointer::New(
-      native_function_type, Integer::Handle(zone, Integer::New(address))));
-
-  return result.raw();
+  return Pointer::New(
+      native_function_type,
+      CompileNativeCallback(native_signature, func, exceptional_return));
+#endif
 }
 
 #if defined(TARGET_ARCH_DBC)
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
index 102e1b3..7260b2b 100644
--- a/runtime/lib/ffi_dynamic_library.cc
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -109,14 +109,9 @@
 
   void* handle = dlib.GetHandle();
 
-  const intptr_t pointer = reinterpret_cast<intptr_t>(
-      ResolveSymbol(handle, argSymbolName.ToCString()));
-
-  // TODO(dacoharkes): should this return Object::null() if address is 0?
-  // https://github.com/dart-lang/sdk/issues/35756
-  RawPointer* result =
-      Pointer::New(type_arg, Integer::Handle(zone, Integer::New(pointer)));
-  return result;
+  const uword pointer =
+      reinterpret_cast<uword>(ResolveSymbol(handle, argSymbolName.ToCString()));
+  return Pointer::New(type_arg, pointer);
 }
 
 DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
diff --git a/runtime/lib/ffi_dynamic_library_patch.dart b/runtime/lib/ffi_dynamic_library_patch.dart
index 29e8c88..92bffec 100644
--- a/runtime/lib/ffi_dynamic_library_patch.dart
+++ b/runtime/lib/ffi_dynamic_library_patch.dart
@@ -18,6 +18,15 @@
   Pointer<T> lookup<T extends NativeType>(String symbolName)
       native "Ffi_dl_lookup";
 
+  // The real implementation of this function lives in FfiUseSitesTransformer
+  // for interface calls. Only dynamic calls (which are illegal) reach this
+  // implementation.
+  @patch
+  F lookupFunction<T extends Function, F extends Function>(String symbolName) {
+    throw UnsupportedError(
+        "Dynamic invocation of lookupFunction is not supported.");
+  }
+
   // TODO(dacoharkes): Expose this to users, or extend Pointer?
   // https://github.com/dart-lang/sdk/issues/35881
   int getHandle() native "Ffi_dl_getHandle";
@@ -32,4 +41,7 @@
   int get hashCode {
     return getHandle().hashCode;
   }
+
+  @patch
+  Pointer<Void> get handle => Pointer.fromAddress(getHandle());
 }
diff --git a/runtime/lib/ffi_patch.dart b/runtime/lib/ffi_patch.dart
index 6915d51..4f586cd 100644
--- a/runtime/lib/ffi_patch.dart
+++ b/runtime/lib/ffi_patch.dart
@@ -5,22 +5,35 @@
 import "dart:_internal" show patch;
 
 @patch
-Pointer<T> allocate<T extends NativeType>({int count: 1}) native "Ffi_allocate";
-
-@patch
-T fromAddress<T extends Pointer>(int ptr) native "Ffi_fromAddress";
-
-@patch
 int sizeOf<T extends NativeType>() native "Ffi_sizeOf";
 
-@patch
-Pointer<NativeFunction<T>> fromFunction<T extends Function>(
-    @DartRepresentationOf("T") Function f) native "Ffi_fromFunction";
+Pointer<T> _allocate<T extends NativeType>(int count) native "Ffi_allocate";
+
+Pointer<T> _fromAddress<T extends NativeType>(int ptr) native "Ffi_fromAddress";
+
+// The real implementation of this function (for interface calls) lives in
+// BuildFfiAsFunctionCall in the Kernel frontend. No calls can actually reach
+// this function.
+DS _asFunctionInternal<DS extends Function, NS extends Function>(
+    Pointer<NativeFunction<NS>> ptr) native "Ffi_asFunctionInternal";
 
 @patch
 @pragma("vm:entry-point")
 class Pointer<T extends NativeType> {
   @patch
+  factory Pointer.allocate({int count: 1}) => _allocate<T>(count);
+
+  @patch
+  factory Pointer.fromAddress(int ptr) => _fromAddress(ptr);
+
+  @patch
+  static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+      @DartRepresentationOf("T") Function f,
+      Object exceptionalReturn) native "Ffi_fromFunction";
+
+  // TODO(sjindel): When NNBD is available, we should change `value` to be
+  // non-null.
+  @patch
   void store(Object value) native "Ffi_store";
 
   @patch
@@ -45,29 +58,13 @@
   // fromAddress(address). This would be 2 native calls rather than one.
   // What would be better?
   @patch
-  U cast<U extends Pointer>() native "Ffi_cast";
+  Pointer<U> cast<U extends NativeType>() native "Ffi_cast";
 
   @patch
-  R asFunction<R extends Function>() native "Ffi_asFunction";
+  R asFunction<R extends Function>() {
+    throw UnsupportedError("Pointer.asFunction cannot be called dynamically.");
+  }
 
   @patch
   void free() native "Ffi_free";
 }
-
-// This method gets called when an exception bubbles up to the native -> Dart
-// boundary from an FFI native callback. Since native code does not have any
-// concept of exceptions, the exception cannot be propagated any further.
-// Instead, print a warning with the exception and return 0/0.0 from the
-// callback.
-//
-// TODO(36856): Iron out the story behind exceptions.
-@pragma("vm:entry-point")
-void _handleExposedException(dynamic exception, dynamic stackTrace) {
-  print(
-      "==================== UNHANDLED EXCEPTION FROM FFI CALLBACK ====================");
-  print(
-      """ ** Native callbacks should not throw exceptions because they cannot be
-    propagated into native code. **""");
-  print("EXCEPTION: $exception");
-  print(stackTrace);
-}
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 7c28e91..f43d181 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -197,6 +197,10 @@
 
 @pragma("vm:entry-point")
 class _SendPortImpl implements SendPort {
+  factory _SendPortImpl._uninstantiable() {
+    throw "Unreachable";
+  }
+
   /*--- public interface ---*/
   @pragma("vm:entry-point", "call")
   void send(var message) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index beb978b..82bd670 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -132,7 +132,7 @@
     // hence do not have a token position, and therefore cannot be reparsed.
     has_extra_parameter_info = false;
   }
-  if (func.HasBytecode() && (func.kernel_offset() == 0)) {
+  if (func.is_declared_in_bytecode()) {
     // Anonymous closures in bytecode cannot be reparsed.
     has_extra_parameter_info = false;
   }
@@ -1048,18 +1048,19 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
-  const Library& library = Library::Handle(ref.GetLibraryReferent());
+  const Library& library = Library::Handle(zone, ref.GetLibraryReferent());
 
   library.EnsureTopLevelClassIsFinalized();
 
-  Instance& member_mirror = Instance::Handle();
+  Instance& member_mirror = Instance::Handle(zone);
   const GrowableObjectArray& member_mirrors =
-      GrowableObjectArray::Handle(GrowableObjectArray::New());
+      GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
 
-  Object& entry = Object::Handle();
+  Object& entry = Object::Handle(zone);
   DictionaryIterator entries(library);
 
-  AbstractType& type = AbstractType::Handle();
+  Error& error = Error::Handle(zone);
+  AbstractType& type = AbstractType::Handle(zone);
 
   while (entries.HasNext()) {
     entry = entries.GetNext();
@@ -1068,6 +1069,10 @@
       // We filter out dynamic.
       // TODO(12478): Should not need to filter out dynamic.
       if (!klass.IsDynamicClass()) {
+        error = klass.EnsureIsFinalized(thread);
+        if (!error.IsNull()) {
+          Exceptions::PropagateError(error);
+        }
         type = klass.DeclarationType();
         member_mirror = CreateClassMirror(klass, type,
                                           Bool::True(),  // is_declaration
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index f79cf3e..7649a04 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -111,14 +111,11 @@
       int startFromInBytes, int toCid, int fromCid) native "TypedData_setRange";
 }
 
-abstract class _IntListMixin<SpawnedType extends List<int>>
-    implements List<int> {
+mixin _IntListMixin implements List<int> {
   int get elementSizeInBytes;
   int get offsetInBytes;
   _ByteBuffer get buffer;
 
-  SpawnedType _createList(int length);
-
   Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
 
   Iterable<int> followedBy(Iterable<int> other) =>
@@ -179,71 +176,6 @@
     }
   }
 
-  void setRange(int start, int end, Iterable<int> from, [int skipCount = 0]) {
-    // Check ranges.
-    if (0 > start || start > end || end > length) {
-      RangeError.checkValidRange(start, end, length); // Always throws.
-      assert(false);
-    }
-    if (skipCount < 0) {
-      throw new ArgumentError(skipCount);
-    }
-
-    final count = end - start;
-    if ((from.length - skipCount) < count) {
-      throw IterableElementError.tooFew();
-    }
-
-    if (count == 0) return;
-
-    if (from is _TypedListBase) {
-      // Note: _TypedListBase is not related to Iterable<int> so there is
-      // no promotion here.
-      final fromAsTypedList = from as _TypedListBase;
-      if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
-        if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
-          Lists.copy(from as List<int>, skipCount, this, start, count);
-          return;
-        } else if (this.buffer._data._setRange(
-            start * elementSizeInBytes + this.offsetInBytes,
-            count * elementSizeInBytes,
-            fromAsTypedList.buffer._data,
-            skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
-            ClassID.getID(this),
-            ClassID.getID(from))) {
-          return;
-        }
-      } else if (fromAsTypedList.buffer == this.buffer) {
-        // Different element sizes, but same buffer means that we need
-        // an intermediate structure.
-        // TODO(srdjan): Optimize to skip copying if the range does not overlap.
-        final fromAsList = from as List<int>;
-        final tempBuffer = _createList(count);
-        for (var i = 0; i < count; i++) {
-          tempBuffer[i] = fromAsList[skipCount + i];
-        }
-        for (var i = start; i < end; i++) {
-          this[i] = tempBuffer[i - start];
-        }
-        return;
-      }
-    }
-
-    List otherList;
-    int otherStart;
-    if (from is List<int>) {
-      otherList = from;
-      otherStart = skipCount;
-    } else {
-      otherList = from.skip(skipCount).toList(growable: false);
-      otherStart = 0;
-    }
-    if (otherStart + count > otherList.length) {
-      throw IterableElementError.tooFew();
-    }
-    Lists.copy(otherList, otherStart, this, start, count);
-  }
-
   Iterable<int> where(bool f(int element)) => new WhereIterable<int>(this, f);
 
   Iterable<int> take(int n) => new SubListIterable<int>(this, 0, n);
@@ -442,14 +374,6 @@
     throw IterableElementError.tooMany();
   }
 
-  SpawnedType sublist(int start, [int end]) {
-    end = RangeError.checkValidRange(start, end, this.length);
-    var length = end - start;
-    SpawnedType result = _createList(length);
-    result.setRange(0, length, this, start);
-    return result;
-  }
-
   void setAll(int index, Iterable<int> iterable) {
     final end = iterable.length + index;
     setRange(index, end, iterable);
@@ -463,14 +387,89 @@
   }
 }
 
-abstract class _DoubleListMixin<SpawnedType extends List<double>>
-    implements List<double> {
+mixin _TypedIntListMixin<SpawnedType extends List<int>> on _IntListMixin
+    implements List<int> {
+  SpawnedType _createList(int length);
+
+  void setRange(int start, int end, Iterable<int> from, [int skipCount = 0]) {
+    // Check ranges.
+    if (0 > start || start > end || end > length) {
+      RangeError.checkValidRange(start, end, length); // Always throws.
+      assert(false);
+    }
+    if (skipCount < 0) {
+      throw RangeError.range(skipCount, 0, null, "skipCount");
+    }
+
+    final count = end - start;
+    if ((from.length - skipCount) < count) {
+      throw IterableElementError.tooFew();
+    }
+
+    if (count == 0) return;
+
+    if (from is _TypedListBase) {
+      // Note: _TypedListBase is not related to Iterable<int> so there is
+      // no promotion here.
+      final fromAsTypedList = from as _TypedListBase;
+      if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+        if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+          Lists.copy(from as List<int>, skipCount, this, start, count);
+          return;
+        } else if (this.buffer._data._setRange(
+            start * elementSizeInBytes + this.offsetInBytes,
+            count * elementSizeInBytes,
+            fromAsTypedList.buffer._data,
+            skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+            ClassID.getID(this),
+            ClassID.getID(from))) {
+          return;
+        }
+      } else if (fromAsTypedList.buffer == this.buffer) {
+        // Different element sizes, but same buffer means that we need
+        // an intermediate structure.
+        // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+        final fromAsList = from as List<int>;
+        final tempBuffer = _createList(count);
+        for (var i = 0; i < count; i++) {
+          tempBuffer[i] = fromAsList[skipCount + i];
+        }
+        for (var i = start; i < end; i++) {
+          this[i] = tempBuffer[i - start];
+        }
+        return;
+      }
+    }
+
+    List otherList;
+    int otherStart;
+    if (from is List<int>) {
+      otherList = from;
+      otherStart = skipCount;
+    } else {
+      otherList = from.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + count > otherList.length) {
+      throw IterableElementError.tooFew();
+    }
+    Lists.copy(otherList, otherStart, this, start, count);
+  }
+
+  SpawnedType sublist(int start, [int end]) {
+    end = RangeError.checkValidRange(start, end, this.length);
+    var length = end - start;
+    SpawnedType result = _createList(length);
+    result.setRange(0, length, this, start);
+    return result;
+  }
+}
+
+mixin _DoubleListMixin implements List<double> {
   int get elementSizeInBytes;
   int get offsetInBytes;
   _ByteBuffer get buffer;
 
-  SpawnedType _createList(int length);
-
   Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
 
   Iterable<double> followedBy(Iterable<double> other) =>
@@ -531,72 +530,6 @@
     }
   }
 
-  void setRange(int start, int end, Iterable<double> from,
-      [int skipCount = 0]) {
-    // Check ranges.
-    if (0 > start || start > end || end > length) {
-      RangeError.checkValidRange(start, end, length); // Always throws.
-      assert(false);
-    }
-    if (skipCount < 0) {
-      throw new ArgumentError(skipCount);
-    }
-
-    final count = end - start;
-    if ((from.length - skipCount) < count) {
-      throw IterableElementError.tooFew();
-    }
-
-    if (count == 0) return;
-
-    if (from is _TypedListBase) {
-      // Note: _TypedListBase is not related to Iterable<double> so there is
-      // no promotion here.
-      final fromAsTypedList = from as _TypedListBase;
-      if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
-        if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
-          Lists.copy(from as List<double>, skipCount, this, start, count);
-          return;
-        } else if (this.buffer._data._setRange(
-            start * elementSizeInBytes + this.offsetInBytes,
-            count * elementSizeInBytes,
-            fromAsTypedList.buffer._data,
-            skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
-            ClassID.getID(this),
-            ClassID.getID(from))) {
-          return;
-        }
-      } else if (fromAsTypedList.buffer == this.buffer) {
-        // Different element sizes, but same buffer means that we need
-        // an intermediate structure.
-        // TODO(srdjan): Optimize to skip copying if the range does not overlap.
-        final fromAsList = from as List<double>;
-        final tempBuffer = _createList(count);
-        for (var i = 0; i < count; i++) {
-          tempBuffer[i] = fromAsList[skipCount + i];
-        }
-        for (var i = start; i < end; i++) {
-          this[i] = tempBuffer[i - start];
-        }
-        return;
-      }
-    }
-
-    List otherList;
-    int otherStart;
-    if (from is List<double>) {
-      otherList = from;
-      otherStart = skipCount;
-    } else {
-      otherList = from.skip(skipCount).toList(growable: false);
-      otherStart = 0;
-    }
-    if (otherStart + count > otherList.length) {
-      throw IterableElementError.tooFew();
-    }
-    Lists.copy(otherList, otherStart, this, start, count);
-  }
-
   Iterable<double> where(bool f(double element)) =>
       new WhereIterable<double>(this, f);
 
@@ -797,14 +730,6 @@
     throw IterableElementError.tooMany();
   }
 
-  SpawnedType sublist(int start, [int end]) {
-    end = RangeError.checkValidRange(start, end, this.length);
-    var length = end - start;
-    SpawnedType result = _createList(length);
-    result.setRange(0, length, this, start);
-    return result;
-  }
-
   void setAll(int index, Iterable<double> iterable) {
     final end = iterable.length + index;
     setRange(index, end, iterable);
@@ -818,6 +743,85 @@
   }
 }
 
+mixin _TypedDoubleListMixin<SpawnedType extends List<double>>
+    on _DoubleListMixin implements List<double> {
+  SpawnedType _createList(int length);
+
+  void setRange(int start, int end, Iterable<double> from,
+      [int skipCount = 0]) {
+    // Check ranges.
+    if (0 > start || start > end || end > length) {
+      RangeError.checkValidRange(start, end, length); // Always throws.
+      assert(false);
+    }
+    if (skipCount < 0) {
+      throw RangeError.range(skipCount, 0, null, "skipCount");
+    }
+
+    final count = end - start;
+    if ((from.length - skipCount) < count) {
+      throw IterableElementError.tooFew();
+    }
+
+    if (count == 0) return;
+
+    if (from is _TypedListBase) {
+      // Note: _TypedListBase is not related to Iterable<double> so there is
+      // no promotion here.
+      final fromAsTypedList = from as _TypedListBase;
+      if (this.elementSizeInBytes == fromAsTypedList.elementSizeInBytes) {
+        if ((count < 10) && (fromAsTypedList.buffer != this.buffer)) {
+          Lists.copy(from as List<double>, skipCount, this, start, count);
+          return;
+        } else if (this.buffer._data._setRange(
+            start * elementSizeInBytes + this.offsetInBytes,
+            count * elementSizeInBytes,
+            fromAsTypedList.buffer._data,
+            skipCount * elementSizeInBytes + fromAsTypedList.offsetInBytes,
+            ClassID.getID(this),
+            ClassID.getID(from))) {
+          return;
+        }
+      } else if (fromAsTypedList.buffer == this.buffer) {
+        // Different element sizes, but same buffer means that we need
+        // an intermediate structure.
+        // TODO(srdjan): Optimize to skip copying if the range does not overlap.
+        final fromAsList = from as List<double>;
+        final tempBuffer = _createList(count);
+        for (var i = 0; i < count; i++) {
+          tempBuffer[i] = fromAsList[skipCount + i];
+        }
+        for (var i = start; i < end; i++) {
+          this[i] = tempBuffer[i - start];
+        }
+        return;
+      }
+    }
+
+    List otherList;
+    int otherStart;
+    if (from is List<double>) {
+      otherList = from;
+      otherStart = skipCount;
+    } else {
+      otherList = from.skip(skipCount).toList(growable: false);
+      otherStart = 0;
+    }
+    if (otherStart + count > otherList.length) {
+      throw IterableElementError.tooFew();
+    }
+    Lists.copy(otherList, otherStart, this, start, count);
+  }
+
+  SpawnedType sublist(int start, [int end]) {
+    end = RangeError.checkValidRange(start, end, this.length);
+    var length = end - start;
+    SpawnedType result = _createList(length);
+    result.setRange(0, length, this, start);
+    return result;
+  }
+}
+
 abstract class _Float32x4ListMixin implements List<Float32x4> {
   int get elementSizeInBytes;
   int get offsetInBytes;
@@ -893,7 +897,7 @@
       assert(false);
     }
     if (skipCount < 0) {
-      throw new ArgumentError(skipCount);
+      throw RangeError.range(skipCount, 0, null, "skipCount");
     }
 
     final count = end - start;
@@ -1251,7 +1255,7 @@
       assert(false);
     }
     if (skipCount < 0) {
-      throw new ArgumentError(skipCount);
+      throw RangeError.range(skipCount, 0, null, "skipCount");
     }
 
     final count = end - start;
@@ -1608,7 +1612,7 @@
       assert(false);
     }
     if (skipCount < 0) {
-      throw new ArgumentError(skipCount);
+      throw RangeError.range(skipCount, 0, null, "skipCount");
     }
 
     final count = end - start;
@@ -2141,7 +2145,7 @@
 
 @pragma("vm:entry-point")
 class _Int8List extends _TypedList
-    with _IntListMixin<Int8List>
+    with _IntListMixin, _TypedIntListMixin<Int8List>
     implements Int8List {
   factory _Int8List._uninstantiable() {
     throw "Unreachable";
@@ -2189,7 +2193,7 @@
 
 @pragma("vm:entry-point")
 class _Uint8List extends _TypedList
-    with _IntListMixin<Uint8List>
+    with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
   factory _Uint8List._uninstantiable() {
     throw "Unreachable";
@@ -2237,7 +2241,7 @@
 
 @pragma("vm:entry-point")
 class _Uint8ClampedList extends _TypedList
-    with _IntListMixin<Uint8ClampedList>
+    with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
   factory _Uint8ClampedList._uninstantiable() {
     throw "Unreachable";
@@ -2285,7 +2289,7 @@
 
 @pragma("vm:entry-point")
 class _Int16List extends _TypedList
-    with _IntListMixin<Int16List>
+    with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
   factory _Int16List._uninstantiable() {
     throw "Unreachable";
@@ -2352,7 +2356,7 @@
 
 @pragma("vm:entry-point")
 class _Uint16List extends _TypedList
-    with _IntListMixin<Uint16List>
+    with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
   factory _Uint16List._uninstantiable() {
     throw "Unreachable";
@@ -2419,7 +2423,7 @@
 
 @pragma("vm:entry-point")
 class _Int32List extends _TypedList
-    with _IntListMixin<Int32List>
+    with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
   factory _Int32List._uninstantiable() {
     throw "Unreachable";
@@ -2474,7 +2478,7 @@
 
 @pragma("vm:entry-point")
 class _Uint32List extends _TypedList
-    with _IntListMixin<Uint32List>
+    with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
   factory _Uint32List._uninstantiable() {
     throw "Unreachable";
@@ -2529,7 +2533,7 @@
 
 @pragma("vm:entry-point")
 class _Int64List extends _TypedList
-    with _IntListMixin<Int64List>
+    with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
   factory _Int64List._uninstantiable() {
     throw "Unreachable";
@@ -2584,7 +2588,7 @@
 
 @pragma("vm:entry-point")
 class _Uint64List extends _TypedList
-    with _IntListMixin<Uint64List>
+    with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
   factory _Uint64List._uninstantiable() {
     throw "Unreachable";
@@ -2639,7 +2643,7 @@
 
 @pragma("vm:entry-point")
 class _Float32List extends _TypedList
-    with _DoubleListMixin<Float32List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
   factory _Float32List._uninstantiable() {
     throw "Unreachable";
@@ -2695,7 +2699,7 @@
 
 @pragma("vm:entry-point")
 class _Float64List extends _TypedList
-    with _DoubleListMixin<Float64List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
   factory _Float64List._uninstantiable() {
     throw "Unreachable";
@@ -2903,7 +2907,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalInt8Array extends _TypedList
-    with _IntListMixin<Int8List>
+    with _IntListMixin, _TypedIntListMixin<Int8List>
     implements Int8List {
   factory _ExternalInt8Array._uninstantiable() {
     throw "Unreachable";
@@ -2937,7 +2941,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalUint8Array extends _TypedList
-    with _IntListMixin<Uint8List>
+    with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
   factory _ExternalUint8Array._uninstantiable() {
     throw "Unreachable";
@@ -2972,7 +2976,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalUint8ClampedArray extends _TypedList
-    with _IntListMixin<Uint8ClampedList>
+    with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
   factory _ExternalUint8ClampedArray._uninstantiable() {
     throw "Unreachable";
@@ -3007,7 +3011,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalInt16Array extends _TypedList
-    with _IntListMixin<Int16List>
+    with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
   factory _ExternalInt16Array._uninstantiable() {
     throw "Unreachable";
@@ -3049,7 +3053,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalUint16Array extends _TypedList
-    with _IntListMixin<Uint16List>
+    with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
   factory _ExternalUint16Array._uninstantiable() {
     throw "Unreachable";
@@ -3091,7 +3095,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalInt32Array extends _TypedList
-    with _IntListMixin<Int32List>
+    with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
   factory _ExternalInt32Array._uninstantiable() {
     throw "Unreachable";
@@ -3133,7 +3137,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalUint32Array extends _TypedList
-    with _IntListMixin<Uint32List>
+    with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
   factory _ExternalUint32Array._uninstantiable() {
     throw "Unreachable";
@@ -3175,7 +3179,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalInt64Array extends _TypedList
-    with _IntListMixin<Int64List>
+    with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
   factory _ExternalInt64Array._uninstantiable() {
     throw "Unreachable";
@@ -3217,7 +3221,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalUint64Array extends _TypedList
-    with _IntListMixin<Uint64List>
+    with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
   factory _ExternalUint64Array._uninstantiable() {
     throw "Unreachable";
@@ -3259,7 +3263,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalFloat32Array extends _TypedList
-    with _DoubleListMixin<Float32List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
   factory _ExternalFloat32Array._uninstantiable() {
     throw "Unreachable";
@@ -3301,7 +3305,7 @@
 
 @pragma("vm:entry-point")
 class _ExternalFloat64Array extends _TypedList
-    with _DoubleListMixin<Float64List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
   factory _ExternalFloat64Array._uninstantiable() {
     throw "Unreachable";
@@ -3716,7 +3720,7 @@
 
 @pragma("vm:entry-point")
 class _Int8ArrayView extends _TypedListView
-    with _IntListMixin<Int8List>
+    with _IntListMixin, _TypedIntListMixin<Int8List>
     implements Int8List {
   // Constructor.
   @pragma("vm:exact-result-type", _Int8ArrayView)
@@ -3753,7 +3757,7 @@
 
 @pragma("vm:entry-point")
 class _Uint8ArrayView extends _TypedListView
-    with _IntListMixin<Uint8List>
+    with _IntListMixin, _TypedIntListMixin<Uint8List>
     implements Uint8List {
   // Constructor.
   @pragma("vm:exact-result-type", _Uint8ArrayView)
@@ -3790,7 +3794,7 @@
 
 @pragma("vm:entry-point")
 class _Uint8ClampedArrayView extends _TypedListView
-    with _IntListMixin<Uint8ClampedList>
+    with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
     implements Uint8ClampedList {
   // Constructor.
   @pragma("vm:exact-result-type", _Uint8ClampedArrayView)
@@ -3827,7 +3831,7 @@
 
 @pragma("vm:entry-point")
 class _Int16ArrayView extends _TypedListView
-    with _IntListMixin<Int16List>
+    with _IntListMixin, _TypedIntListMixin<Int16List>
     implements Int16List {
   // Constructor.
   @pragma("vm:exact-result-type", _Int16ArrayView)
@@ -3876,7 +3880,7 @@
 
 @pragma("vm:entry-point")
 class _Uint16ArrayView extends _TypedListView
-    with _IntListMixin<Uint16List>
+    with _IntListMixin, _TypedIntListMixin<Uint16List>
     implements Uint16List {
   // Constructor.
   @pragma("vm:exact-result-type", _Uint16ArrayView)
@@ -3926,7 +3930,7 @@
 
 @pragma("vm:entry-point")
 class _Int32ArrayView extends _TypedListView
-    with _IntListMixin<Int32List>
+    with _IntListMixin, _TypedIntListMixin<Int32List>
     implements Int32List {
   // Constructor.
   @pragma("vm:exact-result-type", _Int32ArrayView)
@@ -3963,7 +3967,7 @@
 
 @pragma("vm:entry-point")
 class _Uint32ArrayView extends _TypedListView
-    with _IntListMixin<Uint32List>
+    with _IntListMixin, _TypedIntListMixin<Uint32List>
     implements Uint32List {
   // Constructor.
   @pragma("vm:exact-result-type", _Uint32ArrayView)
@@ -4000,7 +4004,7 @@
 
 @pragma("vm:entry-point")
 class _Int64ArrayView extends _TypedListView
-    with _IntListMixin<Int64List>
+    with _IntListMixin, _TypedIntListMixin<Int64List>
     implements Int64List {
   // Constructor.
   @pragma("vm:exact-result-type", _Int64ArrayView)
@@ -4037,7 +4041,7 @@
 
 @pragma("vm:entry-point")
 class _Uint64ArrayView extends _TypedListView
-    with _IntListMixin<Uint64List>
+    with _IntListMixin, _TypedIntListMixin<Uint64List>
     implements Uint64List {
   // Constructor.
   @pragma("vm:exact-result-type", _Uint64ArrayView)
@@ -4074,7 +4078,7 @@
 
 @pragma("vm:entry-point")
 class _Float32ArrayView extends _TypedListView
-    with _DoubleListMixin<Float32List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
     implements Float32List {
   // Constructor.
   @pragma("vm:exact-result-type", _Float32ArrayView)
@@ -4111,7 +4115,7 @@
 
 @pragma("vm:entry-point")
 class _Float64ArrayView extends _TypedListView
-    with _DoubleListMixin<Float64List>
+    with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
     implements Float64List {
   // Constructor.
   @pragma("vm:exact-result-type", _Float64ArrayView)
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index c6f816e..d19c726 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -8,6 +8,7 @@
 import 'dart:async';
 import 'package:observatory/models.dart'
     show IsolateRef, SourceLocation, Script, ScriptRepository;
+import 'package:observatory/service.dart' as S;
 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/helpers/uris.dart';
@@ -48,6 +49,19 @@
     _repository.get(_isolate, _location.script.id).then((script) {
       _script = script;
       _r.dirty();
+    }, onError: (e) {
+      // The script object has expired, likely due to a hot reload.
+      (_isolate as S.Isolate).getScripts().then((scripts) {
+        for (final script in scripts) {
+          if (script.uri == _location.script.uri) {
+            _script = script;
+            _r.dirty();
+            return;
+          }
+        }
+        // Rethrow the original exception if we can't find a match.
+        throw e;
+      });
     });
     _r.enable();
   }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 124cbc2..7f735d3 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1453,6 +1453,12 @@
     return isolate.invokeRpc('getObject', params);
   }
 
+  Future<List<Script>> getScripts() async {
+    final response = await invokeRpc('getScripts', {}) as ServiceMap;
+    assert(response.type == 'ScriptList');
+    return response['scripts'].cast<Script>();
+  }
+
   Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) async {
     return invokeRpcNoUpgrade('getIsolate', {});
   }
diff --git a/runtime/observatory/tests/service/break_on_async_function_test.dart b/runtime/observatory/tests/service/break_on_async_function_test.dart
new file mode 100644
index 0000000..b5bf200
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_async_function_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, 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:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 13;
+
+Future<String> testFunction() async {
+  await new Future.delayed(new Duration(milliseconds: 1));
+  return "Done";
+}
+
+testMain() async {
+  debugger();
+  var str = await testFunction();
+  print(str);
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+
+// Add breakpoint at the entry of async function
+  (Isolate isolate) async {
+    Library rootLib = await isolate.rootLibrary.load();
+    var function =
+        rootLib.functions.singleWhere((f) => f.name == 'testFunction');
+
+    var bpt = await isolate.addBreakpointAtEntry(function);
+    expect(bpt is Breakpoint, isTrue);
+    print(bpt);
+  },
+
+  resumeIsolate,
+
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_A),
+  resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
index 3233420..faa2fa6 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
@@ -12,7 +12,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(utf8.decoder).listen((String data) {
+  response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
index 891a8f7..8126f45 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
@@ -12,7 +12,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(utf8.decoder).listen((String data) {
+  response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
diff --git a/runtime/observatory/tests/service/dev_fs_uri_test.dart b/runtime/observatory/tests/service/dev_fs_uri_test.dart
index 8446316..2fda4d7 100644
--- a/runtime/observatory/tests/service/dev_fs_uri_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_uri_test.dart
@@ -12,7 +12,7 @@
 Future<String> readResponse(HttpClientResponse response) {
   var completer = new Completer<String>();
   var contents = new StringBuffer();
-  response.transform(utf8.decoder).listen((String data) {
+  response.cast<List<int>>().transform(utf8.decoder).listen((String data) {
     contents.write(data);
   }, onDone: () => completer.complete(contents.toString()));
   return completer.future;
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index a5f9a4f..de073bf 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(20));
+    expect(result['minor'], equals(21));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart
new file mode 100644
index 0000000..e8fa8e6
--- /dev/null
+++ b/runtime/observatory/tests/service/get_vm_timeline_micros_rpc_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, 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:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = <VMTest>[
+  (VM vm) async {
+    var result = await vm.invokeRpcNoUpgrade('getVMTimelineMicros', {});
+    expect(result['type'], equals('Timestamp'));
+    expect(result['timestamp'], isPositive);
+  },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
index 30a0112..06c47dc 100644
--- a/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_isolate_rpc_common.dart
@@ -22,6 +22,7 @@
   final requestUri = serverUri.replace(pathSegments: pathSegments);
   var request = await httpClient.getUrl(requestUri);
   Map response = await (await request.close())
+      .cast<List<int>>()
       .transform(utf8.decoder)
       .transform(json.decoder)
       .first;
@@ -55,6 +56,7 @@
   try {
     var request = await httpClient.getUrl(requestUri);
     Map response = await (await request.close())
+        .cast<List<int>>()
         .transform(utf8.decoder)
         .transform(json.decoder)
         .first;
diff --git a/runtime/observatory/tests/service/http_get_vm_rpc_common.dart b/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
index b193dc9..7298b3d 100644
--- a/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_vm_rpc_common.dart
@@ -31,6 +31,7 @@
   try {
     var request = await httpClient.getUrl(requestUri);
     Map response = await (await request.close())
+        .cast<List<int>>()
         .transform(utf8.decoder)
         .transform(json.decoder)
         .first;
diff --git a/runtime/observatory/tests/service/next_through_simple_async_test.dart b/runtime/observatory/tests/service/next_through_simple_async_test.dart
index 9ed99ed..fd1bcdb 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_test.dart
@@ -30,8 +30,10 @@
   "$file:${LINE_A+1}:16", // on File
   "$file:${LINE_A+2}:31", // on 'lastModified'
   "$file:${LINE_A+2}:23", // on 'await'
+  "$file:${LINE_A+2}:21", // on '='
   "$file:${LINE_A+3}:25", // on 'exists'
   "$file:${LINE_A+3}:17", // on 'await'
+  "$file:${LINE_A+3}:15", // on '='
   "$file:${LINE_A+4}:47", // on ')', i.e. before ';'
   "$file:${LINE_A+4}:3", // on call to 'print'
   "$file:${LINE_A+5}:3", // on call to 'foo'
diff --git a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
index c112a29..ea773c4 100644
--- a/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
+++ b/runtime/observatory/tests/service/next_through_simple_async_with_returns_test.dart
@@ -31,6 +31,7 @@
   "$file:${LINE_A+1}:16", // on 'File'
   "$file:${LINE_A+2}:25", // on 'exists'
   "$file:${LINE_A+2}:17", // on 'await'
+  "$file:${LINE_A+2}:15", // on '='
   "$file:${LINE_A+4}:5" // on 'return'
 ];
 
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 2340759..d733673 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -15,28 +15,6 @@
 [ $arch == arm ]
 process_service_test: Pass, Fail # Issue 24344
 
-[ $compiler == app_jit ]
-bad_reload_test: RuntimeError # Issue 27806
-complex_reload_test: RuntimeError # Issue 27806
-debugger_location_second_test: Skip # Issue 28180
-evaluate_activation_test/instance: RuntimeError # Issue 27806
-evaluate_activation_test/scope: RuntimeError # Issue 27806
-get_object_rpc_test: RuntimeError # Issue 27806
-get_source_report_test: RuntimeError # Issue 27806
-next_through_closure_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_create_list_and_map_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_for_each_loop_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-next_through_implicit_call_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-pause_on_unhandled_async_exceptions2_test: Pass, RuntimeError, Timeout, Crash # Issue 29178
-process_service_test: RuntimeError # Spawned process runs in Dart2 mode
-set_name_rpc_test: RuntimeError # Issue 27806
-simple_reload_test: RuntimeError # Issue 27806
-step_through_constructor_calls_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_function_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_switch_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-step_through_switch_with_continue_test: RuntimeError # Snapshots don't include source and generated source is not 1-to-1. The column offsets are thus off.
-unused_changes_in_last_reload_test: RuntimeError # Issue 27806
-
 # Tests with known analyzer issues
 [ $compiler == dart2analyzer ]
 developer_extension_test: SkipByDesign
@@ -47,9 +25,6 @@
 add_breakpoint_rpc_kernel_test: SkipByDesign # kernel specific version of add_breakpoint_rpc_test
 evaluate_function_type_parameters_test: SkipByDesign # only supported in kernel
 
-[ $compiler == precompiler ]
-*: Skip # Issue 24651
-
 # Service protocol is not supported in product mode.
 [ $mode == product ]
 *: SkipByDesign
@@ -62,6 +37,10 @@
 [ $compiler == none && $runtime == vm && $system == fuchsia ]
 *: Skip # Not yet triaged.
 
+[ $compiler == none && ($runtime == dart_precompiled || $runtime == vm) ]
+evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
+evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
+
 [ $mode == debug && $system == windows && $checked ]
 async_scope_test: Pass, Slow
 
@@ -74,10 +53,6 @@
 [ !$strong && ($compiler == dartk || $compiler == dartkp) ]
 *: Skip
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
-evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
-
 [ $arch != ia32 || $arch != x64 || $system != linux ]
 get_native_allocation_samples_test: Skip # Unsupported.
 
diff --git a/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart b/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
index 8eed4c1..8495d65 100644
--- a/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
+++ b/runtime/observatory/tests/service/step_through_for_each_sync_star_2_test.dart
@@ -34,6 +34,7 @@
   "$file:${LINE + 9}:3", // on yield
 
   "$file:${LINE + 1}:38", // on '{' in 'for' line
+  "$file:${LINE + 1}:12", // on 'datapoint'
   "$file:${LINE + 2}:5", // on 'print'
   "$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
 
@@ -42,6 +43,7 @@
   "$file:${LINE + 10}:3", // on yield
 
   "$file:${LINE + 1}:38", // on '{' in 'for' line
+  "$file:${LINE + 1}:12", // on 'datapoint'
   "$file:${LINE + 2}:5", // on 'print'
   "$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
 
diff --git a/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart b/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
index b390dcf..f36a1e2 100644
--- a/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
+++ b/runtime/observatory/tests/service/step_through_for_each_sync_star_test.dart
@@ -35,6 +35,7 @@
   "$file:${LINE + 9}:3", // on yield
 
   "$file:${LINE + 1}:38", // on '{' in 'for' line
+  "$file:${LINE + 1}:12", // on 'datapoint'
   "$file:${LINE + 2}:5", // on 'print'
   "$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
 
@@ -43,6 +44,7 @@
   "$file:${LINE + 11}:3", // on yield
 
   "$file:${LINE + 1}:38", // on '{' in 'for' line
+  "$file:${LINE + 1}:12", // on 'datapoint'
   "$file:${LINE + 2}:5", // on 'print'
   "$file:${LINE + 1}:25", // on 'generator' (in 'for' line)
 
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
index 16d8592..8ed70cb 100644
--- a/runtime/observatory/web/timeline.js
+++ b/runtime/observatory/web/timeline.js
@@ -648,7 +648,7 @@
                    ':' +
                    parser.port +
                    parser.pathname.replace(/\/ws$/, "") +
-                   '/_getVMTimeline';
+                   '/getVMTimeline';
   fetchUri(requestUri, function(event) {
     // Grab the response.
     var xhr = event.target;
diff --git a/runtime/platform/c99_support_win.h b/runtime/platform/c99_support_win.h
deleted file mode 100644
index 5fd6016..0000000
--- a/runtime/platform/c99_support_win.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) 2011, 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.
-
-#ifndef RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
-#define RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
-
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-
-// Before Visual Studio 2013 Visual C++ was missing a bunch of C99 math macros
-// and functions. Define them here.
-
-#include <float.h>
-#include <string.h>
-
-#include <cmath>
-
-static const unsigned __int64 kQuietNaNMask =
-    static_cast<unsigned __int64>(0xfff) << 51;
-
-#ifndef va_copy
-#define va_copy(dst, src) (memmove(&(dst), &(src), sizeof(dst)))
-#endif /* va_copy */
-
-#define NAN *reinterpret_cast<const double*>(&kQuietNaNMask)
-
-namespace std {
-
-static inline int isinf(double x) {
-  return (_fpclass(x) & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0;
-}
-
-static inline int isnan(double x) {
-  return _isnan(x);
-}
-
-static inline int signbit(double x) {
-  if (x == 0) {
-    return _fpclass(x) & _FPCLASS_NZ;
-  } else {
-    return x < 0;
-  }
-}
-
-}  // namespace std
-
-static inline double trunc(double x) {
-  if (x < 0) {
-    return ceil(x);
-  } else {
-    return floor(x);
-  }
-}
-
-static inline double round(double x) {
-  if (!_finite(x)) {
-    return x;
-  }
-
-  double intpart;
-  double fractpart = modf(x, &intpart);
-
-  if (fractpart >= 0.5) {
-    return intpart + 1;
-  } else if (fractpart > -0.5) {
-    return intpart;
-  } else {
-    return intpart - 1;
-  }
-}
-
-// Windows does not have strtoll defined.
-#if defined(_MSC_VER)
-#define strtoll _strtoi64
-#endif
-
-#endif
-
-#endif  // RUNTIME_PLATFORM_C99_SUPPORT_WIN_H_
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index a3632e8..0803ea3 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -62,28 +62,25 @@
 
 #if !defined(_WIN32)
 #include <arpa/inet.h>
-#include <inttypes.h>
-#include <stdint.h>
 #include <unistd.h>
 #endif  // !defined(_WIN32)
 
 #include <float.h>
+#include <inttypes.h>
 #include <limits.h>
+#include <math.h>
 #include <stdarg.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 
 #if defined(_WIN32)
-#include "platform/c99_support_win.h"
 #include "platform/floating_point_win.h"
-#include "platform/inttypes_support_win.h"
 #endif  // defined(_WIN32)
 
-#include "platform/math.h"
-
 #if !defined(_WIN32)
 #include "platform/floating_point.h"
 #endif  // !defined(_WIN32)
@@ -337,12 +334,16 @@
 #if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64)
 #if !defined(ARCH_IS_64_BIT)
 #error Mismatched Host/Target architectures.
-#endif
+#endif  // !defined(ARCH_IS_64_BIT)
 #elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
-#if !defined(ARCH_IS_32_BIT)
+#if defined(HOST_ARCH_X64) && defined(TARGET_ARCH_ARM)
+// This is simarm_x64, which is the only case where host/target architecture
+// mismatch is allowed.
+#define IS_SIMARM_X64 1
+#elif !defined(ARCH_IS_32_BIT)
 #error Mismatched Host/Target architectures.
-#endif
-#endif
+#endif  // !defined(ARCH_IS_32_BIT)
+#endif  // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
 
 // Determine whether we will be using the simulator.
 #if defined(TARGET_ARCH_IA32)
@@ -351,8 +352,11 @@
 // No simulator used.
 #elif defined(TARGET_ARCH_ARM)
 #if !defined(HOST_ARCH_ARM)
+#define TARGET_HOST_MISMATCH 1
+#if !defined(IS_SIMARM_X64)
 #define USING_SIMULATOR 1
 #endif
+#endif
 
 #elif defined(TARGET_ARCH_ARM64)
 #if !defined(HOST_ARCH_ARM64)
@@ -366,6 +370,12 @@
 #error Unknown architecture.
 #endif
 
+#if defined(ARCH_IS_32_BIT) || defined(IS_SIMARM_X64)
+#define TARGET_ARCH_IS_32_BIT 1
+#elif defined(ARCH_IS_64_BIT)
+#define TARGET_ARCH_IS_64_BIT 1
+#endif
+
 // Determine whether HOST_ARCH equals TARGET_ARCH.
 #if defined(HOST_ARCH_ARM) && defined(TARGET_ARCH_ARM)
 #define HOST_ARCH_EQUALS_TARGET_ARCH 1
diff --git a/runtime/platform/inttypes_support_win.h b/runtime/platform/inttypes_support_win.h
deleted file mode 100644
index 19a64db6..0000000
--- a/runtime/platform/inttypes_support_win.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2011, 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.
-
-#ifndef RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
-#define RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
-
-typedef signed __int8 int8_t;
-typedef signed __int16 int16_t;
-typedef signed __int32 int32_t;
-typedef signed __int64 int64_t;
-typedef unsigned __int8 uint8_t;
-typedef unsigned __int16 uint16_t;
-typedef unsigned __int32 uint32_t;
-typedef unsigned __int64 uint64_t;
-
-// Printf format specifiers for intptr_t and uintptr_t.
-#define PRIdPTR "Id"
-#define PRIuPTR "Iu"
-#define PRIxPTR "Ix"
-#define PRIXPTR "IX"
-
-// Printf format specifiers for int64_t and uint64_t.
-#define PRId64 "I64d"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-#define PRIX64 "I64X"
-
-// Printf format specifiers for int32_t and uint32_t.
-#define PRId32 "I32d"
-#define PRIu32 "I32u"
-#define PRIx32 "I32x"
-#define PRIX32 "I32X"
-
-#endif  // RUNTIME_PLATFORM_INTTYPES_SUPPORT_WIN_H_
diff --git a/runtime/platform/math.h b/runtime/platform/math.h
deleted file mode 100644
index 1926625..0000000
--- a/runtime/platform/math.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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.
-
-#ifndef RUNTIME_PLATFORM_MATH_H_
-#define RUNTIME_PLATFORM_MATH_H_
-
-// We must take these math functions from the C++ header file as long as we
-// are using the STL. Otherwise the Android build will break due to confusion
-// between C++ and C headers when math.h is also included.
-#if !defined(HOST_OS_FUCHSIA)
-#include <cmath>
-
-#define isinf(val) std::isinf(val)
-#define isnan(val) std::isnan(val)
-#define signbit(val) std::signbit(val)
-#define isfinite(val) std::isfinite(val)
-#else
-// TODO(zra): When Fuchsia has STL, do the same thing as above.
-#include <math.h>
-#endif
-
-#endif  // RUNTIME_PLATFORM_MATH_H_
diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni
index 9d53c4b..8a1b83e 100644
--- a/runtime/platform/platform_sources.gni
+++ b/runtime/platform/platform_sources.gni
@@ -15,7 +15,6 @@
   "atomic_linux.h",
   "atomic_macos.h",
   "atomic_win.h",
-  "c99_support_win.h",
   "floating_point.h",
   "floating_point_win.cc",
   "floating_point_win.h",
@@ -23,7 +22,6 @@
   "growable_array.h",
   "hashmap.cc",
   "hashmap.h",
-  "inttypes_support_win.h",
   "memory_sanitizer.h",
   "safe_stack.h",
   "signal_blocker.h",
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index 2193a05..7093b19 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -98,6 +98,7 @@
 uint32_t Utils::WordHash(intptr_t key) {
   // TODO(iposva): Need to check hash spreading.
   // This example is from http://www.concentric.net/~Ttwang/tech/inthash.htm
+  // via. http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm
   uword a = static_cast<uword>(key);
   a = (a + 0x7ed55d16) + (a << 12);
   a = (a ^ 0xc761c23c) ^ (a >> 19);
diff --git a/runtime/tests/vm/dart/issue_31959_31960_test.dart b/runtime/tests/vm/dart/issue_31959_31960_test.dart
index 3990fb6..fddff48 100644
--- a/runtime/tests/vm/dart/issue_31959_31960_test.dart
+++ b/runtime/tests/vm/dart/issue_31959_31960_test.dart
@@ -10,7 +10,7 @@
 import 'package:async_helper/async_helper.dart' show asyncStart, asyncEnd;
 import 'package:expect/expect.dart';
 
-Uint8List generateSampleList(final size) {
+Uint8List generateSampleList(final int size) {
   final list = Uint8List(size);
   for (int i = 0; i < size; i++) {
     list[i] = i % 243;
@@ -18,7 +18,7 @@
   return list;
 }
 
-void validateReceivedList(final expectedSize, final list) {
+void validateReceivedList(final int expectedSize, final list) {
   Expect.equals(expectedSize, list.length);
   // probe few elements
   for (int i = 0; i < list.length; i += max<num>(1, expectedSize ~/ 1000)) {
@@ -56,7 +56,7 @@
 
 main() async {
   asyncStart();
-  int bignum = 100 * 1000 * 1000;
+  int bignum = 10 * 1000 * 1000;
   await testSend(false, bignum, 1); // none
   await testSend(true, bignum, 1); // 31959tr
   await testSend(false, bignum, 1); // 31960
diff --git a/runtime/tests/vm/dart/regress_flutter35121_test.dart b/runtime/tests/vm/dart/regress_flutter35121_test.dart
new file mode 100644
index 0000000..a4d21b6
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_flutter35121_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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.
+
+// This is a regression test for
+// https://github.com/flutter/flutter/issues/35121
+
+class A {
+  static List<int> values = const [1, 2, 3];
+  static int get length => values.length;
+}
+
+main() {
+  print(A.length);
+}
diff --git a/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart b/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart
new file mode 100644
index 0000000..58bac74
--- /dev/null
+++ b/runtime/tests/vm/dart/type_argument_factory_constructor_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// Regression test for Issue https://github.com/dart-lang/sdk/issues/37264.
+typedef SomeCb = T Function<T>(T val);
+
+class A<T> {
+  final SomeCb cb;
+
+  A(this.cb);
+
+  factory A.b(SomeCb cb) {
+    return A(cb);
+  }
+}
+
+main() {
+  // VM should not crash on this case
+  A<int>.b(<String>(v) => v);
+}
diff --git a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
index fa99a62..e3393a3 100644
--- a/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
+++ b/runtime/tests/vm/dart/v8_snapshot_profile_writer_test.dart
@@ -113,6 +113,7 @@
 
   await for (String line in File(rawObjectFieldsPath)
       .openRead()
+      .cast<List<int>>()
       .transform(utf8.decoder)
       .transform(LineSplitter())) {
     Match match = matchComplete(fieldEntry, line);
@@ -133,6 +134,7 @@
   bool hasMissingFields = false;
   await for (String line in File(rawObjectPath)
       .openRead()
+      .cast<List<int>>()
       .transform(utf8.decoder)
       .transform(LineSplitter())) {
     Match match = matchComplete(classStart, line);
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 0c6a32b..44a6971 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -24,6 +24,7 @@
 dart/transferable_throws_oom_test: SkipByDesign # This test tries to allocate too much memory on purpose. Still dartbug.com/37188
 
 [ $builder_tag == optimization_counter_threshold ]
+cc/*: Skip # Many tests want see unoptimized code running
 dart/appjit*: SkipByDesign # Test needs to a particular opt-counter value
 dart/kernel_determinism_test: SkipSlow
 
@@ -35,7 +36,7 @@
 dart/entrypoints/aot/*: SkipByDesign
 
 [ $compiler == dartkb ]
-cc/*: Skip # Bytecode modes are not properly hooked up in run_vm_tests.
+cc/*: Skip # Too many timeouts and crashes for infrastructure to handle.
 
 [ $compiler == dartkp ]
 dart/v8_snapshot_profile_writer_test: Pass, Slow # Can be slow due to re-invoking the precompiler.
@@ -43,9 +44,6 @@
 [ $compiler == fasta ]
 dart/data_uri_import_test/badencodeddate: CompileTimeError
 
-[ $compiler == precompiler ]
-dart/byte_array_test: SkipByDesign # Incompatible flag --disable_alloc_stubs_after_gc
-
 [ $mode == debug ]
 cc/CorelibIsolateStartup: SkipByDesign # This is a benchmark that is not informative in debug mode.
 cc/IRTest_TypedDataAOT_FunctionalGetSet: Skip # run_vm_tests contains JIT/AOT but FLAG_precompiled_mode is not always correct. This causes this test to fail in debug mode, hitting an assertion. See http://dartbug.com/36521
@@ -54,9 +52,11 @@
 dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
 dart/spawn_shutdown_test: Pass, Slow # VM Shutdown test, It can take some time for all the isolates to shutdown in a Debug build.
 
-[ $runtime == dart_precompiled ]
-dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
-dart/issue32950_test: SkipByDesign # uses spawnUri.
+[ $mode == product ]
+cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
+cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
+cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
+dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
 
 [ $system == fuchsia ]
 cc/CorelibIsolateStartup: Skip # OOM crash can bring down the OS.
@@ -106,7 +106,6 @@
 dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
 
 [ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
-dart/issue32950_test: SkipByDesign # uses spawnUri.
 dart/redirection_type_shuffling_test: SkipByDesign # Includes dart:mirrors.
 dart/spawn_shutdown_test: SkipSlow
 
@@ -140,7 +139,6 @@
 dart/redirection_type_shuffling_test/00: MissingCompileTimeError
 
 [ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-cc/Class_ComputeEndTokenPos: Crash
 cc/DartAPI_LoadLibrary: Fail, Crash # Issue 33048.
 cc/DebuggerAPI_BreakpointStubPatching: Fail
 cc/DebuggerAPI_GetClosureInfo: Fail
@@ -174,7 +172,6 @@
 
 [ ($arch == simarm || $arch == simarm64 || $arch == simdbc || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
 dart/appjit*: SkipSlow # DFE too slow
-dart/issue_31959_31960_test: SkipSlow
 
 # Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
@@ -257,15 +254,17 @@
 [ $compiler != dartkp || $hot_reload || $hot_reload_rollback || $arch != arm && $arch != simarm && $arch != x64 ]
 dart/entrypoints/aot/*: SkipByDesign # Only supported in the Dart 2 JIT and AOT, and test optimizations - hence disabled on hotreload bots.
 
-[ $compiler == precompiler || $mode == product ]
-cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
-cc/CreateMirrorSystem: SkipByDesign # Imports dart:mirrors
-cc/StandaloneSnapshotSize: SkipByDesign # Imports dart:mirrors
-dart/redirection_type_shuffling_test: SkipByDesign # Imports dart:mirrors
-
 [ $mode == debug || $runtime != dart_precompiled || $system == android ]
 dart/use_bare_instructions_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
 
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+dart/data_uri_spawn_test: SkipByDesign # Isolate.spawnUri
+dart/issue32950_test: SkipByDesign # uses spawnUri.
+
 [ $runtime != dart_precompiled || $system == android ]
 dart/bare_instructions_trampolines_test: SkipByDesign # This test is for VM AOT only (android fails due to listing interfaces).
 
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index fafbcfe..aa27ca4 100755
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -85,13 +85,7 @@
 ''' % date.today().year)
     out.write('''
 
-#if defined(_WIN32)
-typedef unsigned __int8 uint8_t;
-#else
-#include <inttypes.h>
 #include <stdint.h>
-#endif
-#include <stddef.h>
 
 ''')
     out.write('namespace %s {\n' % outer_namespace)
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 1b38ff7..0cf802f 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -4,6 +4,8 @@
 
 #include "vm/bootstrap.h"
 
+#include <memory>
+
 #include "include/dart_api.h"
 
 #include "vm/class_finalizer.h"
@@ -50,11 +52,18 @@
   Class& cls = Class::Handle(zone, object_store->closure_class());
   ClassFinalizer::LoadClassMembers(cls);
 
+  // Make sure _Closure fields are not marked as unboxing candidates
+  // as they are accessed with plain loads.
+  const Array& fields = Array::Handle(zone, cls.fields());
+  Field& field = Field::Handle(zone);
+  for (intptr_t i = 0; i < fields.Length(); ++i) {
+    field ^= fields.At(i);
+    field.set_is_unboxing_candidate(false);
+  }
+
 #if defined(DEBUG)
   // Verify that closure field offsets are identical in Dart and C++.
-  const Array& fields = Array::Handle(zone, cls.fields());
   ASSERT(fields.Length() == 6);
-  Field& field = Field::Handle(zone);
   field ^= fields.At(0);
   ASSERT(field.Offset() == Closure::instantiator_type_arguments_offset());
   field ^= fields.At(1);
@@ -79,7 +88,7 @@
                                      intptr_t kernel_buffer_size) {
   Zone* zone = thread->zone();
   const char* error = nullptr;
-  kernel::Program* program = kernel::Program::ReadFromBuffer(
+  std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
       kernel_buffer, kernel_buffer_size, &error);
   if (program == nullptr) {
     const intptr_t kMessageBufferSize = 512;
@@ -89,7 +98,7 @@
     const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
     return ApiError::New(msg, Heap::kOld);
   }
-  kernel::KernelLoader loader(program, /*uri_to_source_table=*/nullptr);
+  kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
 
   Isolate* isolate = thread->isolate();
 
@@ -111,7 +120,7 @@
   // The platform binary may contain other libraries (e.g., dart:_builtin or
   // dart:io) that will not be bundled with application.  Load them now.
   const Object& result = Object::Handle(zone, loader.LoadProgram());
-  delete program;
+  program.reset();
   if (result.IsError()) {
     return Error::Cast(result).raw();
   }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 98c6129..24b6af2 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -383,8 +383,8 @@
   V(Ffi_offsetBy, 2)                                                           \
   V(Ffi_cast, 1)                                                               \
   V(Ffi_sizeOf, 0)                                                             \
-  V(Ffi_asFunction, 1)                                                         \
-  V(Ffi_fromFunction, 1)                                                       \
+  V(Ffi_asFunctionInternal, 1)                                                 \
+  V(Ffi_fromFunction, 2)                                                       \
   V(Ffi_dl_open, 1)                                                            \
   V(Ffi_dl_lookup, 2)                                                          \
   V(Ffi_dl_getHandle, 1)                                                       \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 688f192..970c7c5 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -195,14 +195,19 @@
 #if defined(DEBUG)
     for (intptr_t i = 0; i < class_array.Length(); i++) {
       cls ^= class_array.At(i);
-      ASSERT(cls.is_declaration_loaded());
+      ASSERT(cls.is_declared_in_bytecode() || cls.is_declaration_loaded());
     }
 #endif
 
     // Finalize types in all classes.
     for (intptr_t i = 0; i < class_array.Length(); i++) {
       cls ^= class_array.At(i);
-      FinalizeTypesInClass(cls);
+      if (cls.is_declared_in_bytecode()) {
+        cls.EnsureDeclarationLoaded();
+        ASSERT(cls.is_type_finalized());
+      } else {
+        FinalizeTypesInClass(cls);
+      }
     }
 
     if (FLAG_print_classes) {
@@ -407,6 +412,7 @@
   // The type class does not need to be finalized in order to finalize the type.
   // Also, the type parameters of the type class must be finalized.
   Class& type_class = Class::Handle(zone, type.type_class());
+  type_class.EnsureDeclarationLoaded();
   if (!type_class.is_type_finalized()) {
     FinalizeTypeParameters(type_class, pending_types);
   }
@@ -1003,7 +1009,7 @@
 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
-  ASSERT(cls.is_declaration_loaded());
+  cls.EnsureDeclarationLoaded();
   if (cls.is_type_finalized()) {
     return;
   }
@@ -1190,21 +1196,9 @@
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-    if (!cls.is_declaration_loaded()) {
-      // Loading of class declaration can be postponed until needed
-      // if class comes from bytecode.
-      ASSERT(cls.is_declared_in_bytecode());
-      kernel::BytecodeReader::LoadClassDeclaration(cls);
-    }
+    cls.EnsureDeclarationLoaded();
 #endif
-    // TODO(36584) : We expect is_type_finalized to be true for all classes
-    // here, but with eager reading of the constant table we get into
-    // situations where we see classes whose types have not been finalized yet,
-    // the real solution is to implement lazy evaluation of constants. This is
-    // a temporary workaround until lazy evaluation is implemented.
-    if (!cls.is_type_finalized()) {
-      FinalizeTypesInClass(cls);
-    }
+    ASSERT(cls.is_type_finalized());
     ClassFinalizer::FinalizeClass(cls);
     return Error::null();
   } else {
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 4e23dea..ae9bfd0 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -128,7 +128,8 @@
   V(NativeFunction)                                                            \
   CLASS_LIST_FFI_TYPE_MARKER(V)                                                \
   V(NativeType)                                                                \
-  V(DynamicLibrary)
+  V(DynamicLibrary)                                                            \
+  V(Struct)
 
 #define DART_CLASS_LIST_TYPED_DATA(V)                                          \
   V(Int8)                                                                      \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index eade6cc..aef1813 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -7,8 +7,8 @@
 #include "platform/assert.h"
 #include "vm/bootstrap.h"
 #include "vm/class_id.h"
+#include "vm/code_observers.h"
 #include "vm/compiler/backend/code_statistics.h"
-#include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/relocation.h"
 #include "vm/dart.h"
 #include "vm/heap/heap.h"
@@ -186,6 +186,7 @@
     s->Write<int16_t>(cls->ptr()->num_type_arguments_);
     s->Write<uint16_t>(cls->ptr()->num_native_fields_);
     s->WriteTokenPosition(cls->ptr()->token_pos_);
+    s->WriteTokenPosition(cls->ptr()->end_token_pos_);
     s->Write<uint32_t>(cls->ptr()->state_bits_);
   }
 
@@ -247,6 +248,7 @@
       cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
       cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
       cls->ptr()->token_pos_ = d->ReadTokenPosition();
+      cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
       cls->ptr()->state_bits_ = d->Read<uint32_t>();
     }
 
@@ -273,6 +275,7 @@
       cls->ptr()->num_type_arguments_ = d->Read<int16_t>();
       cls->ptr()->num_native_fields_ = d->Read<uint16_t>();
       cls->ptr()->token_pos_ = d->ReadTokenPosition();
+      cls->ptr()->end_token_pos_ = d->ReadTokenPosition();
       cls->ptr()->state_bits_ = d->Read<uint32_t>();
 
       table->AllocateIndex(class_id);
@@ -1358,14 +1361,6 @@
       info.set_libraries_cache(array);
       array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
       info.set_classes_cache(array);
-
-      static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-                    "Cleanup support for old bytecode format versions");
-      array = info.bytecode_component();
-      if (!array.IsNull()) {
-        kernel::BytecodeReader::UseBytecodeVersion(
-            kernel::BytecodeComponentData(&array).GetVersion());
-      }
     }
   }
 };
@@ -1581,6 +1576,17 @@
       code->ptr()->state_bits_ = d->Read<int32_t>();
     }
   }
+
+#if !(defined(DART_PRECOMPILED_RUNTIME) || defined(PRODUCT))
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    if (!CodeObservers::AreActive()) return;
+    Code& code = Code::Handle(zone);
+    for (intptr_t id = start_index_; id < stop_index_; id++) {
+      code ^= refs.At(id);
+      Code::NotifyCodeObservers(code, code.is_optimized());
+    }
+  }
+#endif  // !DART_PRECOMPILED_RUNTIME
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -1606,7 +1612,7 @@
   }
 
   void WriteFill(Serializer* s) {
-    ASSERT(s->kind() == Snapshot::kFullJIT);
+    ASSERT(s->kind() != Snapshot::kFullAOT);
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawBytecode* bytecode = objects_[i];
@@ -1639,7 +1645,7 @@
   }
 
   void ReadFill(Deserializer* d) {
-    ASSERT(d->kind() == Snapshot::kFullJIT);
+    ASSERT(d->kind() != Snapshot::kFullAOT);
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
@@ -1878,7 +1884,8 @@
       }
       uint32_t offset = s->GetDataOffset(object);
       s->TraceDataOffset(offset);
-      ASSERT(Utils::IsAligned(offset, kObjectAlignment));
+      ASSERT(Utils::IsAligned(
+          offset, compiler::target::ObjectAlignment::kObjectAlignment));
       ASSERT(offset > running_offset);
       s->WriteUnsigned((offset - running_offset) >>
                        compiler::target::ObjectAlignment::kObjectAlignmentLog2);
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 7832900..6aab6e7 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -15,6 +15,30 @@
 intptr_t CodeObservers::observers_length_ = 0;
 CodeObserver** CodeObservers::observers_ = NULL;
 
+class ExternalCodeObserverAdapter : public CodeObserver {
+ public:
+  explicit ExternalCodeObserverAdapter(Dart_CodeObserver* delegate)
+      : delegate_(delegate) {}
+
+  virtual bool IsActive() const { return true; }
+
+  virtual void Notify(const char* name,
+                      uword base,
+                      uword prologue_offset,
+                      uword size,
+                      bool optimized,
+                      const CodeComments* comments) {
+    return delegate_->on_new_code(delegate_, name, base, size);
+  }
+
+ private:
+  Dart_CodeObserver* delegate_;
+};
+
+void CodeObservers::RegisterExternal(Dart_CodeObserver* observer) {
+  if (observer != nullptr) Register(new ExternalCodeObserverAdapter(observer));
+}
+
 void CodeObservers::Register(CodeObserver* observer) {
   observers_length_++;
   observers_ = reinterpret_cast<CodeObserver**>(
diff --git a/runtime/vm/code_observers.h b/runtime/vm/code_observers.h
index aa6221d..3664a02 100644
--- a/runtime/vm/code_observers.h
+++ b/runtime/vm/code_observers.h
@@ -8,6 +8,8 @@
 #include "vm/allocation.h"
 #include "vm/globals.h"
 
+#include "include/dart_api.h"
+
 namespace dart {
 
 #ifndef PRODUCT
@@ -55,6 +57,8 @@
  public:
   static void Init();
 
+  static void RegisterExternal(Dart_CodeObserver* observer);
+
   static void Register(CodeObserver* observer);
 
   // Notify all active code observers about a newly created code object.
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 1c06796..0898d42 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -131,7 +131,8 @@
                           Address ad) {
   ASSERT(rd != kNoRegister);
   ASSERT(cond != kNoCondition);
-  ASSERT(!ad.has_writeback() || (ad.rn() != rd));  // Unpredictable.
+  // Unpredictable, illegal on some microarchitectures.
+  ASSERT(!ad.has_writeback() || (ad.rn() != rd));
 
   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B26 |
                      (ad.kind() == Address::Immediate ? 0 : B25) |
@@ -146,6 +147,9 @@
                                       Address ad) {
   ASSERT(rd != kNoRegister);
   ASSERT(cond != kNoCondition);
+  // Unpredictable, illegal on some microarchitectures.
+  ASSERT(!ad.has_writeback() || (ad.rn() != rd));
+
   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | mode |
                      ArmEncode::Rd(rd) | ad.encoding3();
   Emit(encoding);
@@ -158,6 +162,8 @@
                                RegList regs) {
   ASSERT(base != kNoRegister);
   ASSERT(cond != kNoCondition);
+  // Unpredictable, illegal on some microarchitectures.
+  ASSERT(!Address::has_writeback(am) || !(regs & (1 << base)));
   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B27 |
                      am | (load ? L : 0) | ArmEncode::Rn(base) | regs;
   Emit(encoding);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 19ba44f..13ea001 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -310,6 +310,21 @@
            (mode() == NegPreIndex) || (mode() == NegPostIndex);
   }
 
+  static bool has_writeback(BlockAddressMode am) {
+    switch (am) {
+      case DA:
+      case IA:
+      case DB:
+      case IB:
+        return false;
+      case DA_W:
+      case IA_W:
+      case DB_W:
+      case IB_W:
+        return true;
+    }
+  }
+
   uint32_t encoding() const { return encoding_; }
 
   // Encoding for addressing mode 3.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index b8808f5..26f8cb9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -110,6 +110,17 @@
     Unknown,
   };
 
+  // If we are doing pre-/post-indexing, and the base and result registers are
+  // the same, then the result is unpredictable. This kind of instruction is
+  // actually illegal on some microarchitectures.
+  bool can_writeback_to(Register r) const {
+    if (type() == PreIndex || type() == PostIndex || type() == PairPreIndex ||
+        type() == PairPostIndex) {
+      return base() != r;
+    }
+    return true;
+  }
+
   // Offset is in bytes. For the unsigned imm12 case, we unscale based on the
   // operand size, and assert that offset is aligned accordingly.
   // For the smaller signed imm9 case, the offset is the number of bytes, but
@@ -869,12 +880,6 @@
       ASSERT(sz == kDoubleWord);
       EmitLoadRegLiteral(LDRpc, rt, a, sz);
     } else {
-      // If we are doing pre-/post-indexing, and the base and result registers
-      // are the same, then the result of the load will be clobbered by the
-      // writeback, which is unlikely to be useful.
-      ASSERT(((a.type() != Address::PreIndex) &&
-              (a.type() != Address::PostIndex)) ||
-             (rt != a.base()));
       if (IsSignedOperand(sz)) {
         EmitLoadStoreReg(LDRS, rt, a, sz);
       } else {
@@ -2067,6 +2072,9 @@
                         Register rt,
                         Address a,
                         OperandSize sz) {
+    // Unpredictable, illegal on some microarchitectures.
+    ASSERT((op != LDR && op != STR && op != LDRS) || a.can_writeback_to(rt));
+
     const int32_t size = Log2OperandSizeBytes(sz);
     const int32_t encoding =
         op | ((size & 0x3) << kSzShift) | Arm64Encode::Rt(rt) | a.encoding();
@@ -2089,6 +2097,10 @@
                             Register rt2,
                             Address a,
                             OperandSize sz) {
+    // Unpredictable, illegal on some microarchitectures.
+    ASSERT(a.can_writeback_to(rt) && a.can_writeback_to(rt2));
+    ASSERT(op != LDP || rt != rt2);
+
     ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
     ASSERT((rt != CSP) && (rt != R31));
     ASSERT((rt2 != CSP) && (rt2 != R31));
diff --git a/runtime/vm/compiler/assembler/disassembler_arm.cc b/runtime/vm/compiler/assembler/disassembler_arm.cc
index 888f97b..b82632d 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm.cc
@@ -1500,12 +1500,15 @@
   }
 
   *object = NULL;
+  // TODO(36839): Make DecodeLoadObjectFromPoolOrThread work on simarm_x64.
+#if !defined(IS_SIMARM_X64)
   if (!code.IsNull()) {
     *object = &Object::Handle();
     if (!DecodeLoadObjectFromPoolOrThread(pc, code, *object)) {
       *object = NULL;
     }
   }
+#endif  // !defined(IS_SIMARM_X64)
 }
 
 #endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index edd8506..85c6f48 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -160,32 +160,6 @@
   Apply(&buf, &size, instr, op1, x, "");
 }
 
-static void FormatA_D(char* buf,
-                      intptr_t size,
-                      KernelBytecode::Opcode opcode,
-                      const KBCInstr* instr,
-                      Fmt op1,
-                      Fmt op2,
-                      Fmt op3) {
-  const int32_t a = KernelBytecode::DecodeA(instr);
-  const int32_t bc = KernelBytecode::DecodeD(instr);
-  Apply(&buf, &size, instr, op1, a, ", ");
-  Apply(&buf, &size, instr, op2, bc, "");
-}
-
-static void FormatA_X(char* buf,
-                      intptr_t size,
-                      KernelBytecode::Opcode opcode,
-                      const KBCInstr* instr,
-                      Fmt op1,
-                      Fmt op2,
-                      Fmt op3) {
-  const int32_t a = KernelBytecode::DecodeA(instr);
-  const int32_t bc = KernelBytecode::DecodeX(instr);
-  Apply(&buf, &size, instr, op1, a, ", ");
-  Apply(&buf, &size, instr, op2, bc, "");
-}
-
 static void FormatA_E(char* buf,
                       intptr_t size,
                       KernelBytecode::Opcode opcode,
@@ -257,21 +231,6 @@
 
 static intptr_t GetConstantPoolIndex(const KBCInstr* instr) {
   switch (KernelBytecode::DecodeOpcode(instr)) {
-    case KernelBytecode::kLoadConstant_Old:
-    case KernelBytecode::kInstantiateTypeArgumentsTOS_Old:
-    case KernelBytecode::kAssertAssignable_Old:
-    case KernelBytecode::kPushConstant_Old:
-    case KernelBytecode::kStoreStaticTOS_Old:
-    case KernelBytecode::kPushStatic_Old:
-    case KernelBytecode::kAllocate_Old:
-    case KernelBytecode::kAllocateClosure_Old:
-    case KernelBytecode::kInstantiateType_Old:
-    case KernelBytecode::kDirectCall_Old:
-    case KernelBytecode::kInterfaceCall_Old:
-    case KernelBytecode::kUncheckedInterfaceCall_Old:
-    case KernelBytecode::kDynamicCall_Old:
-      return KernelBytecode::DecodeD(instr);
-
     case KernelBytecode::kLoadConstant:
     case KernelBytecode::kLoadConstant_Wide:
     case KernelBytecode::kInstantiateTypeArgumentsTOS:
@@ -378,7 +337,8 @@
                       sizeof(human_buffer), &instruction_length, bytecode,
                       &object, pc);
     formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
-                                  sizeof(human_buffer), object, pc);
+                                  sizeof(human_buffer), object,
+                                  FLAG_disassemble_relative ? pc - start : pc);
     pc += instruction_length;
   }
 #else
@@ -393,7 +353,8 @@
   Zone* zone = Thread::Current()->zone();
   const Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode());
   THR_Print("Bytecode for function '%s' {\n", function_fullname);
-  uword start = bytecode.PayloadStart();
+  const uword start = bytecode.PayloadStart();
+  const uword base = FLAG_disassemble_relative ? 0 : start;
   DisassembleToStdout stdout_formatter;
   LogBlock lb;
   Disassemble(start, start + bytecode.Size(), &stdout_formatter, bytecode);
@@ -415,29 +376,59 @@
     const int addr_width = (kBitsPerWord / 4) + 2;
     // "*" in a printf format specifier tells it to read the field width from
     // the printf argument list.
-    THR_Print("%-*s\ttok-ix\n", addr_width, "pc");
+    THR_Print("%-*s\tpos\n", addr_width, "pc");
     kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
     while (iter.MoveNext()) {
-      THR_Print("%#-*" Px "\t%s\n", addr_width,
-                bytecode.PayloadStart() + iter.PcOffset(),
+      THR_Print("%#-*" Px "\t%s\n", addr_width, base + iter.PcOffset(),
                 iter.TokenPos().ToCString());
     }
     THR_Print("}\n");
   }
 
+  if (FLAG_print_variable_descriptors && bytecode.HasLocalVariablesInfo()) {
+    THR_Print("Local variables info for function '%s' {\n", function_fullname);
+    kernel::BytecodeLocalVariablesIterator iter(zone, bytecode);
+    while (iter.MoveNext()) {
+      switch (iter.Kind()) {
+        case kernel::BytecodeLocalVariablesIterator::kScope: {
+          THR_Print("scope 0x%" Px "-0x%" Px " pos %s-%s\tlev %" Pd "\n",
+                    base + iter.StartPC(), base + iter.EndPC(),
+                    iter.StartTokenPos().ToCString(),
+                    iter.EndTokenPos().ToCString(), iter.ContextLevel());
+        } break;
+        case kernel::BytecodeLocalVariablesIterator::kVariableDeclaration: {
+          THR_Print("var   0x%" Px "-0x%" Px " pos %s-%s\tidx %" Pd
+                    "\tdecl %s\t%s %s %s\n",
+                    base + iter.StartPC(), base + iter.EndPC(),
+                    iter.StartTokenPos().ToCString(),
+                    iter.EndTokenPos().ToCString(), iter.Index(),
+                    iter.DeclarationTokenPos().ToCString(),
+                    String::Handle(
+                        zone, AbstractType::Handle(zone, iter.Type()).Name())
+                        .ToCString(),
+                    String::Handle(zone, iter.Name()).ToCString(),
+                    iter.IsCaptured() ? "captured" : "");
+        } break;
+        case kernel::BytecodeLocalVariablesIterator::kContextVariable: {
+          THR_Print("ctxt  0x%" Px "\tidx %" Pd "\n", base + iter.StartPC(),
+                    iter.Index());
+        } break;
+      }
+    }
+    THR_Print("}\n");
+
+    THR_Print("Local variable descriptors for function '%s' {\n",
+              function_fullname);
+    const auto& var_descriptors =
+        LocalVarDescriptors::Handle(zone, bytecode.GetLocalVarDescriptors());
+    THR_Print("%s}\n", var_descriptors.ToCString());
+  }
+
   THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
   const ExceptionHandlers& handlers =
       ExceptionHandlers::Handle(zone, bytecode.exception_handlers());
   THR_Print("%s}\n", handlers.ToCString());
 
-  if (FLAG_print_variable_descriptors) {
-    THR_Print("Local variable descriptors for function '%s' {\n",
-              function_fullname);
-    const auto& var_descriptors =
-        LocalVarDescriptors::Handle(zone, bytecode.GetLocalVarDescriptors());
-    THR_Print("%s\n}\n", var_descriptors.ToCString());
-  }
-
 #else
   UNREACHABLE();
 #endif
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
index 94b566a..28c5d1e 100644
--- a/runtime/vm/compiler/backend/block_builder.h
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -30,7 +30,7 @@
 
   template <typename T>
   T* AddDefinition(T* def) {
-    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    flow_graph_->AllocateSSAIndexes(def);
     AddInstruction(def);
     return def;
   }
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
index 4660d82..7d20887 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.cc
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -351,6 +351,23 @@
   // ASSERT(constant->GetBlock() == flow_graph_->graph_entry());
 }
 
+void FlowGraphChecker::VisitInstanceCall(InstanceCallInstr* instr) {
+  const Function& function = flow_graph_->function();
+
+  // Force-optimized functions may not have instance calls inside them because
+  // we do not reset ICData for these.
+  ASSERT(!function.ForceOptimize());
+}
+
+void FlowGraphChecker::VisitPolymorphicInstanceCall(
+    PolymorphicInstanceCallInstr* instr) {
+  const Function& function = flow_graph_->function();
+
+  // Force-optimized functions may not have instance calls inside them because
+  // we do not reset ICData for these.
+  ASSERT(!function.ForceOptimize());
+}
+
 void FlowGraphChecker::VisitPhi(PhiInstr* phi) {
   // Make sure the definition of each input value of a Phi dominates
   // the corresponding incoming edge, as defined by order.
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.h b/runtime/vm/compiler/backend/flow_graph_checker.h
index 088ad3e..63a77bd 100644
--- a/runtime/vm/compiler/backend/flow_graph_checker.h
+++ b/runtime/vm/compiler/backend/flow_graph_checker.h
@@ -56,6 +56,9 @@
   void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
   void VisitBranch(BranchInstr* branch) override;
   void VisitRedefinition(RedefinitionInstr* def) override;
+  void VisitInstanceCall(InstanceCallInstr* instr) override;
+  void VisitPolymorphicInstanceCall(
+      PolymorphicInstanceCallInstr* instr) override;
 
   FlowGraph* const flow_graph_;
   BlockEntryInstr* current_block_;
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index d6e6059..b207ce7 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -3197,7 +3197,7 @@
 
   ConstantInstr* c = value()->definition()->AsConstant();
   if ((c != NULL) && c->value().IsSmi()) {
-    if (!is_truncating() && (kSmiBits > 32)) {
+    if (!is_truncating()) {
       // Check that constant fits into 32-bit integer.
       const int64_t value = static_cast<int64_t>(Smi::Cast(c->value()).Value());
       if (!Utils::IsInt(32, value)) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 21d4bf9..bee636b 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5109,9 +5109,6 @@
   DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
 };
 
-// TODO(vegorov) the name of the instruction is confusing. At some point
-// it used to allocate uninitialized storage, but this is no longer true.
-// These days it allocates null initialized storage.
 class AllocateUninitializedContextInstr
     : public TemplateAllocation<0, NoThrow> {
  public:
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
index a219c2a..1e56f5a 100644
--- a/runtime/vm/compiler/backend/il_test_helper.cc
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -45,6 +45,10 @@
 }
 
 void Invoke(const Library& lib, const char* name) {
+  // These tests rely on running unoptimized code to collect type feedback. The
+  // interpreter does not collect type feedback for interface calls.
+  SetFlagScope<bool> sfs(&FLAG_enable_interpreter, false);
+
   Thread* thread = Thread::Current();
   Dart_Handle api_lib = Api::NewHandle(thread, lib.raw());
   TransitionVMToNative transition(thread);
diff --git a/runtime/vm/compiler/backend/loops_test.cc b/runtime/vm/compiler/backend/loops_test.cc
index 4b208f8..b2b2e23 100644
--- a/runtime/vm/compiler/backend/loops_test.cc
+++ b/runtime/vm/compiler/backend/loops_test.cc
@@ -307,7 +307,7 @@
       "  WRAP(-99, LIN(0 + -1 * i))\n"  // d
       "  LIN(1 + 1 * i)\n"              // add
       "  ]\n";
-  EXPECT_STREQ(ComputeInduction(thread, script_chars), expected);
+  EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
 ISOLATE_UNIT_TEST_CASE(PeriodicAndDerived) {
@@ -342,7 +342,7 @@
       "  PERIOD(95, 5)\n"       // p2
       "  LIN(1 + 1 * i)\n"      // add
       "  ]\n";
-  EXPECT_STREQ(ComputeInduction(thread, script_chars), expected);
+  EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
 //
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 1b93d0d..420bdbf 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1088,6 +1088,11 @@
 
   intptr_t cid = value().GetClassId();
 
+  if (cid == kSmiCid && !compiler::target::IsSmi(Smi::Cast(value()).Value())) {
+    return CompileType::Create(kMintCid,
+                               AbstractType::ZoneHandle(Type::MintType()));
+  }
+
   if ((cid != kTypeArgumentsCid) && value().IsInstance()) {
     // Allocate in old-space since this may be invoked from the
     // background compiler.
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 7cf2dc1..0626731 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -1692,7 +1692,11 @@
 }
 
 void TypedDataSpecializer::VisitStaticCall(StaticCallInstr* call) {
-  TryInlineCall(call);
+  const Function& function = call->function();
+  if (!function.is_static()) {
+    ASSERT(call->ArgumentCount() > 0);
+    TryInlineCall(call);
+  }
 }
 
 void TypedDataSpecializer::TryInlineCall(TemplateDartCall<0>* call) {
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index bac526c..2d8c1f2 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -152,9 +152,12 @@
 #
 # Not that this diverges from our convention to build every file on every OS
 # but have ifdef guards which make the files empty on some configurations.
-if (is_linux || is_mac) {
+if (!is_win) {
   # MASM on Windows does not support c preproccesor style flags.
-  compiler_sources += [ "ffi_dbc_trampoline_x64_linux_mac.S" ]
+  compiler_sources += [
+    "ffi_dbc_trampoline_arm64.S",
+    "ffi_dbc_trampoline_x64_linux_mac.S",
+  ]
 }
 
 compiler_sources_tests = [
diff --git a/runtime/vm/compiler/ffi.cc b/runtime/vm/compiler/ffi.cc
index 665382a..a2e83a7 100644
--- a/runtime/vm/compiler/ffi.cc
+++ b/runtime/vm/compiler/ffi.cc
@@ -10,7 +10,9 @@
 #include "vm/compiler/backend/locations.h"
 #include "vm/compiler/runtime_api.h"
 #include "vm/growable_array.h"
+#include "vm/object_store.h"
 #include "vm/stack_frame.h"
+#include "vm/symbols.h"
 
 namespace dart {
 
@@ -71,8 +73,10 @@
       return kUnboxedInt64;
     case kFfiIntPtrCid:
     case kFfiPointerCid:
-    default:  // Subtypes of Pointer.
+    case kFfiVoidCid:
       return kUnboxedFfiIntPtr;
+    default:
+      UNREACHABLE();
   }
 }
 
@@ -96,24 +100,7 @@
 }
 
 bool NativeTypeIsPointer(const AbstractType& result_type) {
-  switch (result_type.type_class_id()) {
-    case kFfiVoidCid:
-    case kFfiFloatCid:
-    case kFfiDoubleCid:
-    case kFfiInt8Cid:
-    case kFfiInt16Cid:
-    case kFfiInt32Cid:
-    case kFfiUint8Cid:
-    case kFfiUint16Cid:
-    case kFfiUint32Cid:
-    case kFfiInt64Cid:
-    case kFfiUint64Cid:
-    case kFfiIntPtrCid:
-      return false;
-    case kFfiPointerCid:
-    default:
-      return true;
-  }
+  return result_type.type_class_id() == kFfiPointerCid;
 }
 
 // Converts a Ffi [signature] to a list of Representations.
@@ -442,6 +429,45 @@
 #endif
 }
 
+// TODO(36607): Cache the trampolines.
+RawFunction* TrampolineFunction(const Function& dart_signature,
+                                const Function& c_signature) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  String& name = String::Handle(zone, Symbols::New(thread, "FfiTrampoline"));
+  const Library& lib = Library::Handle(zone, Library::FfiLibrary());
+  const Class& owner_class = Class::Handle(zone, lib.toplevel_class());
+  Function& function =
+      Function::Handle(zone, Function::New(name, RawFunction::kFfiTrampoline,
+                                           /*is_static=*/true,
+                                           /*is_const=*/false,
+                                           /*is_abstract=*/false,
+                                           /*is_external=*/false,
+                                           /*is_native=*/false, owner_class,
+                                           TokenPosition::kMinSource));
+  function.set_is_debuggable(false);
+  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
+  function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
+  function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
+
+  // The signature function won't have any names for the parameters. We need to
+  // assign unique names for scope building and error messages.
+  const intptr_t num_params = dart_signature.num_fixed_parameters();
+  const Array& parameter_names = Array::Handle(Array::New(num_params));
+  for (intptr_t i = 0; i < num_params; ++i) {
+    if (i == 0) {
+      name = Symbols::ClosureParameter().raw();
+    } else {
+      name = Symbols::NewFormatted(thread, ":ffi_param%" Pd, i);
+    }
+    parameter_names.SetAt(i, name);
+  }
+  function.set_parameter_names(parameter_names);
+  function.SetFfiCSignature(c_signature);
+
+  return function.raw();
+}
+
 // Accounts for alignment, where some stack slots are used as padding.
 template <class Location>
 intptr_t TemplateNumStackSlots(const ZoneGrowableArray<Location>& locations) {
@@ -547,6 +573,27 @@
 
 #endif  // defined(TARGET_ARCH_DBC)
 
+bool IsAsFunctionInternal(Zone* zone, Isolate* isolate, const Function& func) {
+  Object& asFunctionInternal =
+      Object::Handle(zone, isolate->object_store()->ffi_as_function_internal());
+  if (asFunctionInternal.raw() == Object::null()) {
+    // Cache the reference.
+    Library& ffi =
+        Library::Handle(zone, isolate->object_store()->ffi_library());
+    asFunctionInternal =
+        ffi.LookupFunctionAllowPrivate(Symbols::AsFunctionInternal());
+    // Cannot assert that 'asFunctionInternal' is found because it may have been
+    // tree-shaken.
+    if (asFunctionInternal.IsNull()) {
+      // Set the entry in the object store to a sentinel so we don't try to look
+      // it up again.
+      asFunctionInternal = Object::sentinel().raw();
+    }
+    isolate->object_store()->set_ffi_as_function_internal(asFunctionInternal);
+  }
+  return func.raw() == asFunctionInternal.raw();
+}
+
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 }  // namespace ffi
diff --git a/runtime/vm/compiler/ffi.h b/runtime/vm/compiler/ffi.h
index 846775a..9c9810a 100644
--- a/runtime/vm/compiler/ffi.h
+++ b/runtime/vm/compiler/ffi.h
@@ -41,6 +41,9 @@
 // Location for the result of a C signature function.
 Location ResultLocation(Representation result_rep);
 
+RawFunction* TrampolineFunction(const Function& dart_signature,
+                                const Function& c_signature);
+
 #if !defined(TARGET_ARCH_DBC)
 
 // Unboxed representations of the arguments to a C signature function.
@@ -133,6 +136,8 @@
   intptr_t argument_slots_required_ = 0;
 };
 
+bool IsAsFunctionInternal(Zone* zone, Isolate* isolate, const Function& func);
+
 }  // namespace ffi
 
 }  // namespace compiler
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline.h b/runtime/vm/compiler/ffi_dbc_trampoline.h
index 656d1e1..578fc7f 100644
--- a/runtime/vm/compiler/ffi_dbc_trampoline.h
+++ b/runtime/vm/compiler/ffi_dbc_trampoline.h
@@ -9,7 +9,8 @@
 
 namespace dart {
 
-#if defined(HOST_ARCH_X64) && !defined(HOST_OS_WINDOWS)
+#if !defined(HOST_OS_WINDOWS) &&                                               \
+    (defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
 
 // Generic Trampoline for DBC dart:ffi calls. Argument needs to be layed out as
 // a FfiMarshalledArguments.
diff --git a/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S b/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S
new file mode 100644
index 0000000..3c24411
--- /dev/null
+++ b/runtime/vm/compiler/ffi_dbc_trampoline_arm64.S
@@ -0,0 +1,76 @@
+#if defined(__aarch64__) /* HOST_ARCH_ARM64 */
+
+.text
+
+#if defined(__ANDROID__) || defined(__linux__) || defined(__FreeBSD__)
+/* HOST_OS_ANDROID || HOST_OS_LINUX */
+.global FfiTrampolineCall
+.align 2
+FfiTrampolineCall:
+#else /* HOST_OS_MACOS */
+.global _FfiTrampolineCall
+.align 2
+_FfiTrampolineCall:
+#endif
+
+/* Save argument in scratch register. */
+stp   x19,  x20, [sp, #-16]! /* Push x19 and x20, we use x19 as scratch. */
+mov   x19,  x0              /* Save argument in scratch register. */
+
+/* Enter frame. */
+stp   fp,   lr, [sp, #-16]!
+mov   fp,   sp
+
+/* Reserve framespace for arguments. */
+ldr   x9,   [x19, #(8*18)]  /* Load number of stack arguments. */
+lsl   x9,   x9,  #3         /* Multiply by size (8 bytes). */
+sub   sp,   sp,  x9         /* Reserve num_stack_args stack slots. */
+
+/* Stack alignment. */
+ldr   x10,  [x19, #(8*17)]  /* Load stack alignment mask. */
+mov   x11,  sp
+and   x11,  x11,  x10       /* Align stack. */
+mov   sp,   x11
+
+/* Copy stack arguments. */
+cmp   x9,   #0              /* Check if number of stack arguments is 0. */
+beq   .done                 /* Skip loop if no stack arguments. */
+add   x19,  x19, #(8*19)    /* Offset r19 to point to stack arguments. */
+.align 2
+.loop:                      /* Copy stack arguments loop. */
+sub   x9,   x9,   #8        /* Decrement stack argument iterator. */
+ldr   x10,  [x19, x9]       /* Load value from ffi_marshalled_args. */
+str   x10,  [sp,  x9]       /* Store value on stack. */
+cmp   x9,   #0              /* Compare iterator with 0 */
+bne   .loop                 /* Loop while iterator is not 0 */
+sub   x19,  x19, #(8*19)    /* Restore r19 to original value. */
+.align 2
+.done:                      /* End stack arguments loop. */
+
+/* Copy registers and fpu registers. */
+ldp   x0, x1, [x19, #(8*1)] /* and #(8*2) */
+ldp   x2, x3, [x19, #(8*3)] /* and #(8*4) */
+ldp   x4, x5, [x19, #(8*5)] /* ... */
+ldp   x6, x7, [x19, #(8*7)]
+ldp   d0, d1, [x19, #(8*9)]
+ldp   d2, d3, [x19, #(8*11)]
+ldp   d4, d5, [x19, #(8*13)]
+ldp   d6, d7, [x19, #(8*15)]
+
+/* Do call. */
+ldr   x9,   [x19]           /* Load function address. */
+blr   x9                    /* Call the function. */
+
+/* Copy results back. */
+str   x0,   [x19, #(8*0)]   /* Move integer result in kOffsetIntResult. */
+str   d0,   [x19, #(8*1)]   /* Move double result in kOffsetDoubleResult. */
+
+/* Leave frame. */
+mov   sp,   fp
+ldp   fp,   lr,  [sp], #16
+
+/* Restore caller saved register. */
+ldp   x19,  x20, [sp], #16   /* Pop x19 and x20. */
+ret
+
+#endif /* HOST_ARCH_ARM64 */
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index c133f75..0753967 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -601,9 +601,14 @@
   Value::AddToList(new (Z) Value(definition), &stack_);
 }
 
-Definition* BaseFlowGraphBuilder::Peek() {
-  ASSERT(stack_ != NULL);
-  return stack_->definition();
+Definition* BaseFlowGraphBuilder::Peek(intptr_t depth) {
+  Value* head = stack_;
+  for (intptr_t i = 0; i < depth; ++i) {
+    ASSERT(head != nullptr);
+    head = head->next_use();
+  }
+  ASSERT(head != nullptr);
+  return head->definition();
 }
 
 Value* BaseFlowGraphBuilder::Pop() {
@@ -813,6 +818,62 @@
   return Fragment(load);
 }
 
+Fragment BaseFlowGraphBuilder::AllocateObject(TokenPosition position,
+                                              const Class& klass,
+                                              intptr_t argument_count) {
+  ArgumentArray arguments = GetArguments(argument_count);
+  AllocateObjectInstr* allocate =
+      new (Z) AllocateObjectInstr(position, klass, arguments);
+  Push(allocate);
+  return Fragment(allocate);
+}
+
+Fragment BaseFlowGraphBuilder::BuildFfiAsFunctionInternalCall(
+    const TypeArguments& signatures) {
+  ASSERT(signatures.IsInstantiated() && signatures.Length() == 2);
+
+  const AbstractType& dart_type = AbstractType::Handle(signatures.TypeAt(0));
+  const AbstractType& native_type = AbstractType::Handle(signatures.TypeAt(1));
+
+  ASSERT(dart_type.IsFunctionType() && native_type.IsFunctionType());
+  const Function& target =
+      Function::ZoneHandle(compiler::ffi::TrampolineFunction(
+          Function::Handle(Z, Type::Cast(dart_type).signature()),
+          Function::Handle(Z, Type::Cast(native_type).signature())));
+
+  Fragment code;
+  code += LoadNativeField(Slot::Pointer_c_memory_address());
+  LocalVariable* address = MakeTemporary();
+
+  auto& context_variables = CompilerState::Current().GetDummyContextVariables(
+      /*context_id=*/0, /*num_variables=*/1);
+  code += AllocateContext(context_variables);
+  LocalVariable* context = MakeTemporary();
+
+  code += LoadLocal(context);
+  code += LoadLocal(address);
+  code += StoreInstanceField(
+      TokenPosition::kNoSource,
+      Slot::GetContextVariableSlotFor(thread_, *context_variables[0]));
+
+  code += AllocateClosure(TokenPosition::kNoSource, target);
+  LocalVariable* closure = MakeTemporary();
+
+  code += LoadLocal(closure);
+  code += LoadLocal(context);
+  code += StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_context());
+
+  code += LoadLocal(closure);
+  code += Constant(target);
+  code +=
+      StoreInstanceField(TokenPosition::kNoSource, Slot::Closure_function());
+
+  // Drop address and context.
+  code += DropTempsPreserveTop(2);
+
+  return code;
+}
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index a800743..330b03a 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -169,7 +169,7 @@
   Fragment StoreIndexed(intptr_t class_id);
 
   void Push(Definition* definition);
-  Definition* Peek();
+  Definition* Peek(intptr_t depth = 0);
   Value* Pop();
   Fragment Drop();
   // Drop given number of temps from the stack but preserve top of the stack.
@@ -292,6 +292,15 @@
     return stack_ == nullptr ? 0 : stack_->definition()->temp_index() + 1;
   }
 
+  // Builds the graph for an invocation of '_asFunctionInternal'.
+  //
+  // 'signatures' contains the pair [<dart signature>, <native signature>].
+  Fragment BuildFfiAsFunctionInternalCall(const TypeArguments& signatures);
+
+  Fragment AllocateObject(TokenPosition position,
+                          const Class& klass,
+                          intptr_t argument_count);
+
  protected:
   intptr_t AllocateBlockId() { return ++last_used_block_id_; }
 
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index fd2dd5d..5cd23a4 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -5,6 +5,7 @@
 #include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
 
 #include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/ffi.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/prologue_builder.h"
 #include "vm/compiler/jit/compiler.h"
@@ -252,6 +253,110 @@
   parsed_function()->SetRawParameters(parameters);
 }
 
+const KBCInstr*
+BytecodeFlowGraphBuilder::AllocateParametersAndLocalsForEntryOptional() {
+  ASSERT(KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_));
+
+  const intptr_t num_fixed_params = DecodeOperandA().value();
+  const intptr_t num_opt_pos_params = DecodeOperandB().value();
+  const intptr_t num_opt_named_params = DecodeOperandC().value();
+
+  ASSERT(num_fixed_params == function().num_fixed_parameters());
+  ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters());
+  ASSERT(num_opt_named_params == function().NumOptionalNamedParameters());
+
+  ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
+  const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
+
+  const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_);
+  const KBCInstr* frame_instr = instr;
+  for (intptr_t i = 0; i < num_load_const; ++i) {
+    frame_instr = KernelBytecode::Next(frame_instr);
+  }
+  ASSERT(KernelBytecode::IsFrameOpcode(frame_instr));
+  const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr);
+  const intptr_t num_params =
+      num_fixed_params + num_opt_pos_params + num_opt_named_params;
+  const intptr_t total_locals = num_params + num_extra_locals;
+
+  AllocateLocalVariables(Operand(total_locals), num_params);
+
+  ZoneGrowableArray<const Instance*>* default_values =
+      new (Z) ZoneGrowableArray<const Instance*>(
+          Z, num_opt_pos_params + num_opt_named_params);
+  ZoneGrowableArray<LocalVariable*>* raw_parameters =
+      new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
+
+  intptr_t param = 0;
+  for (; param < num_fixed_params; ++param) {
+    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+    raw_parameters->Add(param_var);
+  }
+
+  for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
+    const KBCInstr* load_value_instr = instr;
+    instr = KernelBytecode::Next(instr);
+    ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
+    ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
+    const Object& default_value =
+        ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value();
+
+    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
+    raw_parameters->Add(param_var);
+    default_values->Add(
+        &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())));
+  }
+
+  if (num_opt_named_params > 0) {
+    default_values->EnsureLength(num_opt_named_params, nullptr);
+    raw_parameters->EnsureLength(num_params, nullptr);
+
+    ASSERT(scratch_var_ != nullptr);
+
+    for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
+      const KBCInstr* load_name_instr = instr;
+      const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr);
+      instr = KernelBytecode::Next(load_value_instr);
+      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
+      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
+      const String& param_name = String::Cast(
+          ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr)))
+              .value());
+      ASSERT(param_name.IsSymbol());
+      const Object& default_value =
+          ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr)))
+              .value();
+
+      intptr_t param_index = num_fixed_params;
+      for (; param_index < num_params; ++param_index) {
+        if (function().ParameterNameAt(param_index) == param_name.raw()) {
+          break;
+        }
+      }
+      ASSERT(param_index < num_params);
+
+      ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
+      (*default_values)[param_index - num_fixed_params] =
+          &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()));
+
+      const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr);
+      ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr));
+
+      LocalVariable* param_var =
+          AllocateParameter(param_index, VariableIndex(-param));
+      ASSERT(raw_parameters->At(param_index) == nullptr);
+      (*raw_parameters)[param_index] = param_var;
+    }
+  }
+
+  ASSERT(instr == frame_instr);
+
+  parsed_function()->set_default_parameter_values(default_values);
+  parsed_function()->SetRawParameters(raw_parameters);
+
+  return KernelBytecode::Next(frame_instr);
+}
+
 LocalVariable* BytecodeFlowGraphBuilder::LocalVariableAt(intptr_t local_index) {
   ASSERT(!is_generating_interpreter());
   if (local_index < 0) {
@@ -388,12 +493,10 @@
 #define BUILD_BYTECODE_CASE(name, encoding, kind, op1, op2, op3)               \
   BUILD_BYTECODE_CASE_##kind(name, encoding)
 
-#define BUILD_BYTECODE_CASE_OLD(name, encoding)
 #define BUILD_BYTECODE_CASE_WIDE(name, encoding)
 #define BUILD_BYTECODE_CASE_RESV(name, encoding)
 #define BUILD_BYTECODE_CASE_ORDN(name, encoding)                               \
   case KernelBytecode::k##name:                                                \
-  case KernelBytecode::k##name##_Old:                                          \
     WIDE_CASE_##encoding(name) Build##name();                                  \
     break;
 
@@ -410,7 +513,6 @@
 #undef WIDE_CASE_D_F
 #undef WIDE_CASE_A_B_C
 #undef BUILD_BYTECODE_CASE
-#undef BUILD_BYTECODE_CASE_OLD
 #undef BUILD_BYTECODE_CASE_WIDE
 #undef BUILD_BYTECODE_CASE_RESV
 #undef BUILD_BYTECODE_CASE_ORDN
@@ -472,104 +574,14 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
-  const intptr_t num_fixed_params = DecodeOperandA().value();
-  const intptr_t num_opt_pos_params = DecodeOperandB().value();
-  const intptr_t num_opt_named_params = DecodeOperandC().value();
-  ASSERT(num_fixed_params == function().num_fixed_parameters());
-  ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters());
-  ASSERT(num_opt_named_params == function().NumOptionalNamedParameters());
+  const KBCInstr* next_instr = AllocateParametersAndLocalsForEntryOptional();
 
-  ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0));
-  const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params;
-
-  const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_);
-  const KBCInstr* frame_instr = instr;
-  for (intptr_t i = 0; i < num_load_const; ++i) {
-    frame_instr = KernelBytecode::Next(frame_instr);
-  }
-  ASSERT(KernelBytecode::IsFrameOpcode(frame_instr));
-  const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr);
-  const intptr_t num_params =
-      num_fixed_params + num_opt_pos_params + num_opt_named_params;
-  const intptr_t total_locals = num_params + num_extra_locals;
-
-  AllocateLocalVariables(Operand(total_locals), num_params);
-
-  ZoneGrowableArray<const Instance*>* default_values =
-      new (Z) ZoneGrowableArray<const Instance*>(
-          Z, num_opt_pos_params + num_opt_named_params);
-  ZoneGrowableArray<LocalVariable*>* raw_parameters =
-      new (Z) ZoneGrowableArray<LocalVariable*>(Z, num_params);
   LocalVariable* temp_var = nullptr;
-
-  intptr_t param = 0;
-  for (; param < num_fixed_params; ++param) {
-    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
-    raw_parameters->Add(param_var);
-  }
-
-  for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) {
-    const KBCInstr* load_value_instr = instr;
-    instr = KernelBytecode::Next(instr);
-    ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
-    ASSERT(KernelBytecode::DecodeA(load_value_instr) == param);
-    const Object& default_value =
-        ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value();
-
-    LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param));
-    raw_parameters->Add(param_var);
-    default_values->Add(
-        &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())));
-  }
-
-  if (num_opt_named_params > 0) {
-    default_values->EnsureLength(num_opt_named_params, nullptr);
-    raw_parameters->EnsureLength(num_params, nullptr);
-
+  if (function().HasOptionalNamedParameters()) {
     ASSERT(scratch_var_ != nullptr);
     temp_var = scratch_var_;
-
-    for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) {
-      const KBCInstr* load_name_instr = instr;
-      const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr);
-      instr = KernelBytecode::Next(load_value_instr);
-      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr));
-      ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr));
-      const String& param_name = String::Cast(
-          ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr)))
-              .value());
-      ASSERT(param_name.IsSymbol());
-      const Object& default_value =
-          ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr)))
-              .value();
-
-      intptr_t param_index = num_fixed_params;
-      for (; param_index < num_params; ++param_index) {
-        if (function().ParameterNameAt(param_index) == param_name.raw()) {
-          break;
-        }
-      }
-      ASSERT(param_index < num_params);
-
-      ASSERT(default_values->At(param_index - num_fixed_params) == nullptr);
-      (*default_values)[param_index - num_fixed_params] =
-          &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()));
-
-      const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr);
-      ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr));
-
-      LocalVariable* param_var =
-          AllocateParameter(param_index, VariableIndex(-param));
-      ASSERT(raw_parameters->At(param_index) == nullptr);
-      (*raw_parameters)[param_index] = param_var;
-    }
   }
 
-  ASSERT(instr == frame_instr);
-
-  parsed_function()->set_default_parameter_values(default_values);
-  parsed_function()->SetRawParameters(raw_parameters);
-
   Fragment copy_args_prologue;
 
   // Code generated for EntryOptional is considered a prologue code.
@@ -602,7 +614,7 @@
       PrologueInfo(prologue_entry->block_id(), prologue_exit->block_id() - 1);
 
   // Skip LoadConstant and Frame instructions.
-  next_pc_ = pc_ + (KernelBytecode::Next(instr) - bytecode_instr_);
+  next_pc_ = pc_ + (next_instr - bytecode_instr_);
 
   ASSERT(IsStackEmpty());
 }
@@ -765,6 +777,11 @@
   const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
   const intptr_t argc = DecodeOperandF().value();
 
+  if (compiler::ffi::IsAsFunctionInternal(Z, Isolate::Current(), target)) {
+    BuildFfiAsFunction();
+    return;
+  }
+
   // Recognize identical() call.
   // Note: similar optimization is performed in AST flow graph builder - see
   // StreamingFlowGraphBuilder::BuildStaticInvocation, special_case_identical.
@@ -895,194 +912,17 @@
   }
 
   ASSERT(function().is_native());
+  B->InlineBailout("BytecodeFlowGraphBuilder::BuildNativeCall");
 
-  // TODO(alexmarkov): find a way to avoid code duplication with
-  // FlowGraphBuilder::NativeFunctionBody.
-  const MethodRecognizer::Kind kind =
-      MethodRecognizer::RecognizeKind(function());
-  switch (kind) {
-    case MethodRecognizer::kObjectEquals:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StrictCompare(Token::kEQ_STRICT);
-      break;
-    case MethodRecognizer::kStringBaseLength:
-    case MethodRecognizer::kStringBaseIsEmpty:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::String_length());
-      if (kind == MethodRecognizer::kStringBaseIsEmpty) {
-        code_ += B->IntConstant(0);
-        code_ += B->StrictCompare(Token::kEQ_STRICT);
-      }
-      break;
-    case MethodRecognizer::kGrowableArrayLength:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::GrowableObjectArray_length());
-      break;
-    case MethodRecognizer::kObjectArrayLength:
-    case MethodRecognizer::kImmutableArrayLength:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::Array_length());
-      break;
-    case MethodRecognizer::kTypedListLength:
-    case MethodRecognizer::kTypedListViewLength:
-    case MethodRecognizer::kByteDataViewLength:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::TypedDataBase_length());
-      break;
-    case MethodRecognizer::kClassIDgetID:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadClassId();
-      break;
-    case MethodRecognizer::kGrowableArrayCapacity:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::GrowableObjectArray_data());
-      code_ += B->LoadNativeField(Slot::Array_length());
-      break;
-    case MethodRecognizer::kListFactory: {
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric() &&
-             function().HasOptionalParameters());
-      ASSERT(scratch_var_ != nullptr);
-      // Generate code that performs:
-      //
-      // factory List<E>([int length]) {
-      //   return (:arg_desc.positional_count == 2) ? new _List<E>(length)
-      //                                            : new _GrowableList<E>(0);
-      // }
-      const auto& core_lib = Library::Handle(Z, Library::CoreLibrary());
-
-      TargetEntryInstr *allocate_non_growable, *allocate_growable;
-
-      code_ += B->Drop();  // Drop 'length'.
-      code_ += B->Drop();  // Drop 'type arguments'.
-      code_ += B->LoadArgDescriptor();
-      code_ += B->LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
-      code_ += B->IntConstant(2);
-      code_ +=
-          B->BranchIfStrictEqual(&allocate_non_growable, &allocate_growable);
-
-      JoinEntryInstr* join = B->BuildJoinEntry();
-
-      {
-        const auto& cls = Class::Handle(
-            Z, core_lib.LookupClass(
-                   Library::PrivateCoreLibName(Symbols::_List())));
-        ASSERT(!cls.IsNull());
-        const auto& func = Function::ZoneHandle(
-            Z, cls.LookupFactoryAllowPrivate(Symbols::_ListFactory()));
-        ASSERT(!func.IsNull());
-
-        code_ = Fragment(allocate_non_growable);
-        code_ += B->LoadLocal(LocalVariableAt(0));
-        code_ += B->LoadLocal(LocalVariableAt(1));
-        auto* call = new (Z) StaticCallInstr(
-            TokenPosition::kNoSource, func, 0, Array::null_array(),
-            GetArguments(2), *ic_data_array_, B->GetNextDeoptId(),
-            ICData::kStatic);
-        code_ <<= call;
-        B->Push(call);
-        code_ += B->StoreLocal(TokenPosition::kNoSource, scratch_var_);
-        code_ += B->Drop();
-        code_ += B->Goto(join);
-      }
-
-      {
-        const auto& cls = Class::Handle(
-            Z, core_lib.LookupClass(
-                   Library::PrivateCoreLibName(Symbols::_GrowableList())));
-        ASSERT(!cls.IsNull());
-        const auto& func = Function::ZoneHandle(
-            Z, cls.LookupFactoryAllowPrivate(Symbols::_GrowableListFactory()));
-        ASSERT(!func.IsNull());
-
-        code_ = Fragment(allocate_growable);
-        code_ += B->LoadLocal(LocalVariableAt(0));
-        code_ += B->IntConstant(0);
-        auto* call = new (Z) StaticCallInstr(
-            TokenPosition::kNoSource, func, 0, Array::null_array(),
-            GetArguments(2), *ic_data_array_, B->GetNextDeoptId(),
-            ICData::kStatic);
-        code_ <<= call;
-        B->Push(call);
-        code_ += B->StoreLocal(TokenPosition::kNoSource, scratch_var_);
-        code_ += B->Drop();
-        code_ += B->Goto(join);
-      }
-
-      code_ = Fragment(join);
-      code_ += B->LoadLocal(scratch_var_);
-      break;
-    }
-    case MethodRecognizer::kObjectArrayAllocate:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->CreateArray();
-      break;
-    case MethodRecognizer::kLinkedHashMap_getIndex:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::LinkedHashMap_index());
-      break;
-    case MethodRecognizer::kLinkedHashMap_setIndex:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StoreInstanceField(TokenPosition::kNoSource,
-                                     Slot::LinkedHashMap_index());
-      code_ += B->NullConstant();
-      break;
-    case MethodRecognizer::kLinkedHashMap_getData:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::LinkedHashMap_data());
-      break;
-    case MethodRecognizer::kLinkedHashMap_setData:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StoreInstanceField(TokenPosition::kNoSource,
-                                     Slot::LinkedHashMap_data());
-      code_ += B->NullConstant();
-      break;
-    case MethodRecognizer::kLinkedHashMap_getHashMask:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::LinkedHashMap_hash_mask());
-      break;
-    case MethodRecognizer::kLinkedHashMap_setHashMask:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StoreInstanceField(TokenPosition::kNoSource,
-                                     Slot::LinkedHashMap_hash_mask(),
-                                     kNoStoreBarrier);
-      code_ += B->NullConstant();
-      break;
-    case MethodRecognizer::kLinkedHashMap_getUsedData:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::LinkedHashMap_used_data());
-      break;
-    case MethodRecognizer::kLinkedHashMap_setUsedData:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StoreInstanceField(TokenPosition::kNoSource,
-                                     Slot::LinkedHashMap_used_data(),
-                                     kNoStoreBarrier);
-      code_ += B->NullConstant();
-      break;
-    case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
-      ASSERT((function().NumParameters() == 1) && !function().IsGeneric());
-      code_ += B->LoadNativeField(Slot::LinkedHashMap_deleted_keys());
-      break;
-    case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
-      ASSERT((function().NumParameters() == 2) && !function().IsGeneric());
-      code_ += B->StoreInstanceField(TokenPosition::kNoSource,
-                                     Slot::LinkedHashMap_deleted_keys(),
-                                     kNoStoreBarrier);
-      code_ += B->NullConstant();
-      break;
-    default: {
-      B->InlineBailout("BytecodeFlowGraphBuilder::BuildNativeCall");
-      const auto& name = String::ZoneHandle(Z, function().native_name());
-      const intptr_t num_args =
-          function().NumParameters() + (function().IsGeneric() ? 1 : 0);
-      ArgumentArray arguments = GetArguments(num_args);
-      auto* call =
-          new (Z) NativeCallInstr(&name, &function(), FLAG_link_natives_lazily,
-                                  function().end_token_pos(), arguments);
-      code_ <<= call;
-      B->Push(call);
-      break;
-    }
-  }
+  const auto& name = String::ZoneHandle(Z, function().native_name());
+  const intptr_t num_args =
+      function().NumParameters() + (function().IsGeneric() ? 1 : 0);
+  ArgumentArray arguments = GetArguments(num_args);
+  auto* call =
+      new (Z) NativeCallInstr(&name, &function(), FLAG_link_natives_lazily,
+                              function().end_token_pos(), arguments);
+  code_ <<= call;
+  B->Push(call);
 }
 
 void BytecodeFlowGraphBuilder::BuildAllocate() {
@@ -1726,6 +1566,22 @@
   code_ += B->AllocateClosure(position_, target);
 }
 
+// Builds graph for a call to 'dart:ffi::_asFunctionInternal'. The stack must
+// look like:
+//
+// <receiver> => pointer argument
+// <type arguments vector> => signatures
+// ...
+void BytecodeFlowGraphBuilder::BuildFfiAsFunction() {
+  // The bytecode FGB doesn't eagerly insert PushArguments, so the type
+  // arguments won't be wrapped in a PushArgumentsInstr.
+  const TypeArguments& type_args =
+      TypeArguments::Cast(B->Peek(/*depth=*/1)->AsConstant()->value());
+  // Drop type arguments, preserving pointer.
+  code_ += B->DropTempsPreserveTop(1);
+  code_ += B->BuildFfiAsFunctionInternalCall(type_args);
+}
+
 static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
   if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) {
     return false;
@@ -1804,16 +1660,13 @@
 bool BytecodeFlowGraphBuilder::RequiresScratchVar(const KBCInstr* instr) {
   switch (KernelBytecode::DecodeOpcode(instr)) {
     case KernelBytecode::kEntryOptional:
-    case KernelBytecode::kEntryOptional_Old:
       return KernelBytecode::DecodeC(instr) > 0;
 
     case KernelBytecode::kEqualsNull:
-    case KernelBytecode::kEqualsNull_Old:
       return true;
 
     case KernelBytecode::kNativeCall:
     case KernelBytecode::kNativeCall_Wide:
-    case KernelBytecode::kNativeCall_Old:
       return MethodRecognizer::RecognizeKind(function()) ==
              MethodRecognizer::kListFactory;
 
@@ -1900,6 +1753,25 @@
   }
 }
 
+void BytecodeFlowGraphBuilder::CreateParameterVariables() {
+  const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
+  object_pool_ = bytecode.object_pool();
+  bytecode_instr_ = reinterpret_cast<const KBCInstr*>(bytecode.PayloadStart());
+
+  if (KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_)) {
+    scratch_var_ = parsed_function_->EnsureExpressionTemp();
+    AllocateParametersAndLocalsForEntryOptional();
+  } else if (KernelBytecode::IsEntryOpcode(bytecode_instr_)) {
+    AllocateLocalVariables(DecodeOperandD());
+    AllocateFixedParameters();
+  } else if (KernelBytecode::IsEntryFixedOpcode(bytecode_instr_)) {
+    AllocateLocalVariables(DecodeOperandE());
+    AllocateFixedParameters();
+  } else {
+    UNREACHABLE();
+  }
+}
+
 FlowGraph* BytecodeFlowGraphBuilder::BuildGraph() {
   const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode());
 
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
index 833deb2..e03a502 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h
@@ -44,6 +44,9 @@
 
   FlowGraph* BuildGraph();
 
+  // Create parameter variables without building a flow graph.
+  void CreateParameterVariables();
+
  protected:
   // Returns `true` if building a flow graph for a bytecode interpreter, or
   // `false` if compiling a function from bytecode.
@@ -122,6 +125,12 @@
   LocalVariable* AllocateParameter(intptr_t param_index,
                                    VariableIndex var_index);
   void AllocateFixedParameters();
+
+  // Allocates parameters and local variables in case of EntryOptional.
+  // Returns pointer to the instruction after EntryOptional/LoadConstant/Frame
+  // bytecodes.
+  const KBCInstr* AllocateParametersAndLocalsForEntryOptional();
+
   LocalVariable* LocalVariableAt(intptr_t local_index);
   void StoreLocal(Operand local_index);
   void LoadLocal(Operand local_index);
@@ -141,6 +150,7 @@
   void BuildInterfaceCallCommon(bool is_unchecked_call);
 
   void BuildInstruction(KernelBytecode::Opcode opcode);
+  void BuildFfiAsFunction();
 
 #define DECLARE_BUILD_METHOD(name, encoding, kind, op1, op2, op3)              \
   void Build##name();
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 5d3ba7d..660375c 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -137,7 +137,7 @@
       &Array::Handle(helper_->zone_, GetBytecodeComponent()));
   BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component);
   AlternativeReadingScope alt(&bytecode_reader.reader(),
-                              library.bytecode_offset());
+                              bytecode_component.GetLibraryIndexOffset());
   bytecode_reader.FindAndReadSpecificLibrary(
       library, bytecode_component.GetNumLibraries());
 }
@@ -472,6 +472,9 @@
   const int kHasOptionalNamedParamsFlag = 1 << 1;
   const int kHasTypeParamsFlag = 1 << 2;
   const int kHasSourcePositionsFlag = 1 << 3;
+  const int kIsAsyncFlag = 1 << 4;
+  const int kIsAsyncStarFlag = 1 << 5;
+  const int kIsSyncStarFlag = 1 << 6;
 
   const intptr_t flags = reader_.ReadUInt();
 
@@ -499,6 +502,19 @@
   closure.set_is_declared_in_bytecode(true);
   closure.set_end_token_pos(end_position);
 
+  if ((flags & kIsSyncStarFlag) != 0) {
+    closure.set_modifier(RawFunction::kSyncGen);
+  } else if ((flags & kIsAsyncFlag) != 0) {
+    closure.set_modifier(RawFunction::kAsync);
+    closure.set_is_inlinable(!FLAG_causal_async_stacks);
+  } else if ((flags & kIsAsyncStarFlag) != 0) {
+    closure.set_modifier(RawFunction::kAsyncGen);
+    closure.set_is_inlinable(!FLAG_causal_async_stacks);
+  }
+  if (Function::Cast(parent).IsAsyncOrGenerator()) {
+    closure.set_is_generated_body(true);
+  }
+
   closures_->SetAt(closureIndex, closure);
 
   Type& signature_type = Type::Handle(
@@ -511,6 +527,35 @@
   closure.SetSignatureType(signature_type);
 }
 
+static bool IsNonCanonical(const AbstractType& type) {
+  return type.IsTypeRef() || (type.IsType() && !type.IsCanonical());
+}
+
+static bool HasNonCanonicalTypes(Zone* zone, const Function& func) {
+  auto& type = AbstractType::Handle(zone);
+  for (intptr_t i = 0; i < func.NumParameters(); ++i) {
+    type = func.ParameterTypeAt(i);
+    if (IsNonCanonical(type)) {
+      return true;
+    }
+  }
+  type = func.result_type();
+  if (IsNonCanonical(type)) {
+    return true;
+  }
+  const auto& type_params = TypeArguments::Handle(zone, func.type_parameters());
+  if (!type_params.IsNull()) {
+    for (intptr_t i = 0; i < type_params.Length(); ++i) {
+      type = type_params.TypeAt(i);
+      type = TypeParameter::Cast(type).bound();
+      if (IsNonCanonical(type)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 RawType* BytecodeReaderHelper::ReadFunctionSignature(
     const Function& func,
     bool has_optional_positional_params,
@@ -565,7 +610,14 @@
 
   // Finalize function type.
   type = func.SignatureType();
-  type = ClassFinalizer::FinalizeType(*(active_class_->klass), type);
+  ClassFinalizer::FinalizationKind finalization = ClassFinalizer::kCanonicalize;
+  if (pending_recursive_types_ != nullptr && HasNonCanonicalTypes(Z, func)) {
+    // This function type is a part of recursive type. Avoid canonicalization
+    // as not all TypeRef objects are filled up at this point.
+    finalization = ClassFinalizer::kFinalize;
+  }
+  type =
+      ClassFinalizer::FinalizeType(*(active_class_->klass), type, finalization);
   return Type::Cast(type).raw();
 }
 
@@ -809,15 +861,8 @@
   TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
                     "BytecodeReaderHelper::ReadBytecode");
 #endif  // defined(SUPPORT_TIMELINE)
-  intptr_t size = reader_.ReadUInt();
-  intptr_t offset = reader_.offset();
-
-  static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-                "Cleanup support for old bytecode format versions");
-  if (bytecode_component_->GetVersion() < 7) {
-    const intptr_t kAlignment = 4;
-    offset = Utils::RoundUp(offset, kAlignment);
-  }
+  const intptr_t size = reader_.ReadUInt();
+  const intptr_t offset = reader_.offset();
 
   const uint8_t* data = reader_.BufferAt(offset);
   reader_.set_offset(offset + size);
@@ -843,10 +888,6 @@
     ExceptionHandlerList* exception_handlers_list =
         new (Z) ExceptionHandlerList();
 
-    static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-                  "Cleanup support for old bytecode format versions");
-    const int kPCShifter = (bytecode_component_->GetVersion() < 7) ? 2 : 0;
-
     // Encoding of ExceptionsTable is described in
     // pkg/vm/lib/bytecode/exceptions.dart.
     for (intptr_t try_index = 0; try_index < try_block_count; try_index++) {
@@ -854,13 +895,13 @@
       intptr_t outer_try_index = outer_try_index_plus1 - 1;
       // PcDescriptors are expressed in terms of return addresses.
       intptr_t start_pc =
-          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
                                              /* is_return_address = */ true);
       intptr_t end_pc =
-          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
                                              /* is_return_address = */ true);
       intptr_t handler_pc =
-          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt() << kPCShifter,
+          KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(),
                                              /* is_return_address = */ false);
       uint8_t flags = reader_.ReadByte();
       const uint8_t kFlagNeedsStackTrace = 1 << 0;
@@ -941,6 +982,10 @@
     case MethodRecognizer::kTypedListLength:
     case MethodRecognizer::kTypedListViewLength:
     case MethodRecognizer::kByteDataViewLength:
+    case MethodRecognizer::kByteDataViewOffsetInBytes:
+    case MethodRecognizer::kTypedDataViewOffsetInBytes:
+    case MethodRecognizer::kByteDataViewTypedData:
+    case MethodRecognizer::kTypedDataViewTypedData:
     case MethodRecognizer::kClassIDgetID:
     case MethodRecognizer::kGrowableArrayCapacity:
     case MethodRecognizer::kListFactory:
@@ -1015,7 +1060,6 @@
            version, KernelBytecode::kMinSupportedBytecodeFormatVersion,
            KernelBytecode::kMaxSupportedBytecodeFormatVersion);
   }
-  BytecodeReader::UseBytecodeVersion(version);
 
   reader_.ReadUInt32();  // Skip stringTable.numItems
   const intptr_t string_table_offset = start_offset + reader_.ReadUInt32();
@@ -1240,7 +1284,7 @@
         }
         return cls;
       }
-      RawClass* cls = library.LookupClassAllowPrivate(class_name);
+      RawClass* cls = library.LookupLocalClass(class_name);
       NoSafepointScope no_safepoint_scope(thread_);
       if (cls == Class::null()) {
         FATAL2("Unable to find class %s in %s", class_name.ToCString(),
@@ -1577,10 +1621,7 @@
       return AbstractType::void_type().raw();
     case kSimpleType: {
       const Class& cls = Class::CheckedHandle(Z, ReadObject());
-      if (!cls.is_declaration_loaded()) {
-        ASSERT(cls.is_declared_in_bytecode());
-        BytecodeReader::LoadClassDeclaration(cls);
-      }
+      cls.EnsureDeclarationLoaded();
       return cls.DeclarationType();
     }
     case kTypeParameter: {
@@ -1611,10 +1652,7 @@
     }
     case kGenericType: {
       const Class& cls = Class::CheckedHandle(Z, ReadObject());
-      if (!cls.is_declaration_loaded()) {
-        ASSERT(cls.is_declared_in_bytecode());
-        BytecodeReader::LoadClassDeclaration(cls);
-      }
+      cls.EnsureDeclarationLoaded();
       const TypeArguments& type_arguments =
           TypeArguments::CheckedHandle(Z, ReadObject());
       const Type& type = Type::Handle(
@@ -1625,10 +1663,7 @@
     case kRecursiveGenericType: {
       const intptr_t id = reader_.ReadUInt();
       const Class& cls = Class::CheckedHandle(Z, ReadObject());
-      if (!cls.is_declaration_loaded()) {
-        ASSERT(cls.is_declared_in_bytecode());
-        BytecodeReader::LoadClassDeclaration(cls);
-      }
+      cls.EnsureDeclarationLoaded();
       const auto saved_pending_recursive_types = pending_recursive_types_;
       if (id == 0) {
         pending_recursive_types_ = &GrowableObjectArray::Handle(
@@ -1639,8 +1674,10 @@
           TypeRef::Handle(Z, TypeRef::New(AbstractType::null_abstract_type()));
       pending_recursive_types_->Add(type_ref);
 
+      reading_type_arguments_of_recursive_type_ = true;
       const TypeArguments& type_arguments =
           TypeArguments::CheckedHandle(Z, ReadObject());
+      reading_type_arguments_of_recursive_type_ = false;
 
       ASSERT(id == pending_recursive_types_->Length() - 1);
       ASSERT(pending_recursive_types_->At(id) == type_ref.raw());
@@ -1651,6 +1688,11 @@
           Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
       type_ref.set_type(type);
       type.SetIsFinalized();
+      if (id != 0) {
+        // Do not canonicalize non-root recursive types
+        // as not all TypeRef objects are filled up at this point.
+        return type.raw();
+      }
       return type.Canonicalize();
     }
     case kRecursiveTypeRef: {
@@ -1766,6 +1808,8 @@
 }
 
 RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments() {
+  const bool is_recursive = reading_type_arguments_of_recursive_type_;
+  reading_type_arguments_of_recursive_type_ = false;
   const intptr_t length = reader_.ReadUInt();
   TypeArguments& type_arguments =
       TypeArguments::ZoneHandle(Z, TypeArguments::New(length));
@@ -1774,6 +1818,14 @@
     type ^= ReadObject();
     type_arguments.SetTypeAt(i, type);
   }
+  if (is_recursive) {
+    // Avoid canonicalization of type arguments of recursive type
+    // as not all TypeRef objects are filled up at this point.
+    // Type arguments will be canoncialized when the root recursive
+    // type is canonicalized.
+    ASSERT(pending_recursive_types_ != nullptr);
+    return type_arguments.raw();
+  }
   return type_arguments.Canonicalize();
 }
 
@@ -2217,22 +2269,28 @@
   // Its cid is set in Class::New / Isolate::RegisterClass /
   // ClassTable::Register, unless it was loaded for expression evaluation.
   ASSERT(cls.is_declared_in_bytecode());
-  ASSERT(!cls.is_declaration_loaded());
+  ASSERT(!cls.is_declaration_loaded() || loading_native_wrappers_library_);
 
   const intptr_t flags = reader_.ReadUInt();
   const bool has_pragma = (flags & kHasPragmaFlag) != 0;
 
   // Set early to enable access to type_parameters().
-  cls.set_is_declaration_loaded();
+  // TODO(alexmarkov): revise early stamping of native wrapper classes
+  //  as loaded.
+  if (!cls.is_declaration_loaded()) {
+    cls.set_is_declaration_loaded();
+  }
 
   const auto& script = Script::CheckedHandle(Z, ReadObject());
   cls.set_script(script);
 
   TokenPosition position = TokenPosition::kNoSource;
+  TokenPosition end_position = TokenPosition::kNoSource;
   if ((flags & kHasSourcePositionsFlag) != 0) {
     position = reader_.ReadPosition();
-    reader_.ReadPosition();  // end_position
+    end_position = reader_.ReadPosition();
     cls.set_token_pos(position);
+    cls.set_end_token_pos(end_position);
   }
 
   cls.set_has_pragma(has_pragma);
@@ -2288,13 +2346,6 @@
 
         library.AddClassMetadata(cls, top_level_class, TokenPosition::kNoSource,
                                  0, annotations_offset);
-        if (has_pragma) {
-          // TODO(alexmarkov): read annotations right away using
-          //  annotations_offset.
-          NoOOBMessageScope no_msg_scope(thread_);
-          NoReloadScope no_reload_scope(thread_->isolate(), thread_);
-          library.GetMetadata(cls);
-        }
       }
     }
   }
@@ -2304,7 +2355,11 @@
                           bytecode_component_->GetMembersOffset());
 
   // All types are finalized if loading from bytecode.
-  cls.set_is_type_finalized();
+  // TODO(alexmarkov): revise early stamping of native wrapper classes
+  //  as type-finalized.
+  if (!cls.is_type_finalized()) {
+    cls.set_is_type_finalized();
+  }
 
   // TODO(alexmarkov): move this to class finalization.
   ClassFinalizer::RegisterClassInHierarchy(Z, cls);
@@ -2316,6 +2371,7 @@
   // pkg/vm/lib/bytecode/declarations.dart.
   const int kUsesDartMirrorsFlag = 1 << 0;
   const int kUsesDartFfiFlag = 1 << 1;
+  const int kHasExtensionsFlag = 1 << 2;
 
   ASSERT(library.is_declared_in_bytecode());
   ASSERT(!library.Loaded());
@@ -2342,6 +2398,28 @@
 
   const auto& script = Script::CheckedHandle(Z, ReadObject());
 
+  if ((flags & kHasExtensionsFlag) != 0) {
+    const intptr_t num_extensions = reader_.ReadUInt();
+    auto& import_namespace = Namespace::Handle(Z);
+    auto& native_library = Library::Handle(Z);
+    for (intptr_t i = 0; i < num_extensions; ++i) {
+      name ^= ReadObject();
+      ASSERT(name.StartsWith(Symbols::DartExtensionScheme()));
+
+      // Create a dummy library and add it as an import to the current library.
+      // Actual loading occurs in KernelLoader::LoadNativeExtensionLibraries().
+      // This also allows later to discover and reload this native extension,
+      // e.g. when running from an app-jit snapshot.
+      // See Loader::ReloadNativeExtensions(...) which relies on
+      // Dart_GetImportsOfScheme('dart-ext').
+      native_library = Library::New(name);
+      import_namespace = Namespace::New(native_library, Array::null_array(),
+                                        Array::null_array());
+      library.AddImport(import_namespace);
+    }
+    H.AddPotentialExtensionLibrary(library);
+  }
+
   // The bootstrapper will take care of creating the native wrapper classes,
   // but we will add the synthetic constructors to them here.
   if (name.raw() ==
@@ -2373,10 +2451,11 @@
       }
     } else {
       if (lookup_classes) {
-        cls = library.LookupClassAllowPrivate(name);
+        cls = library.LookupLocalClass(name);
       }
       if (lookup_classes && !cls.IsNull()) {
-        ASSERT(!cls.is_declaration_loaded());
+        ASSERT(!cls.is_declaration_loaded() ||
+               loading_native_wrappers_library_);
         cls.set_script(script);
       } else {
         cls = Class::New(library, name, script, TokenPosition::kNoSource,
@@ -2389,6 +2468,13 @@
 
     cls.set_is_declared_in_bytecode(true);
     cls.set_bytecode_offset(class_offset);
+
+    if (loading_native_wrappers_library_ || !register_class) {
+      AlternativeReadingScope alt(&reader_, class_offset);
+      ReadClassDeclaration(cls);
+      AlternativeReadingScope alt2(&reader_, cls.bytecode_offset());
+      ReadMembers(cls, /* discard_fields = */ false);
+    }
   }
 
   ASSERT(!library.Loaded());
@@ -3064,7 +3150,6 @@
             function.token_pos() <= var_info.end_pos) ||
            (function.token_pos() <= var_info.begin_pos &&
             var_info.begin_pos <= function.end_token_pos()))) {
-        var_info.scope_id++;  // One level higher in the context chain.
         vars.Add(
             VarDesc{&String::Handle(zone, parent_vars.GetName(i)), var_info});
       }
@@ -3093,6 +3178,7 @@
             desc.info.scope_id = scope_id;
             if (local_vars.Index() < 0) {
               // Parameter
+              ASSERT(local_vars.Index() < -kKBCParamEndSlotFromFp);
               desc.info.set_index(-local_vars.Index() - kKBCParamEndSlotFromFp);
             } else {
               desc.info.set_index(-local_vars.Index());
@@ -3132,28 +3218,6 @@
 }
 #endif  // !defined(PRODUCT)
 
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-              "Cleanup support for old bytecode format versions");
-void BytecodeReader::UseBytecodeVersion(intptr_t version) {
-  Isolate* isolate = Isolate::Current();
-  bool using_old = isolate->is_using_old_bytecode_instructions();
-  bool using_new = isolate->is_using_new_bytecode_instructions();
-  if (version < 7) {
-    using_old = true;
-    isolate->set_is_using_old_bytecode_instructions(true);
-  } else {
-    using_new = true;
-    isolate->set_is_using_new_bytecode_instructions(true);
-  }
-
-  if (using_old && using_new) {
-    FATAL1(
-        "Unable to use both new and old bytecode instructions in the same Dart "
-        "isolate (%s)",
-        isolate->name());
-  }
-}
-
 bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function,
                                                Zone* zone) {
   ASSERT(function.kind() == RawFunction::kImplicitStaticGetter);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index 1a8440c..386dece 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -225,6 +225,7 @@
   Class& scoped_function_class_;
   Library* expression_evaluation_library_ = nullptr;
   bool loading_native_wrappers_library_ = false;
+  bool reading_type_arguments_of_recursive_type_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper);
 };
@@ -326,20 +327,19 @@
       const Function& function,
       const Bytecode& bytecode);
 #endif
-
-  static void UseBytecodeVersion(intptr_t version);
 };
 
 class BytecodeSourcePositionsIterator : ValueObject {
  public:
+  // This constant should match corresponding constant in class SourcePositions
+  // (pkg/vm/lib/bytecode/source_positions.dart).
+  static const intptr_t kYieldPointMarker = -2;
+
   BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode)
       : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))) {
     if (bytecode.HasSourcePositions()) {
       reader_.set_offset(bytecode.source_positions_binary_offset());
       pairs_remaining_ = reader_.ReadUInt();
-      if (Isolate::Current()->is_using_old_bytecode_instructions()) {
-        pc_shifter_ = 2;
-      }
     }
   }
 
@@ -349,8 +349,14 @@
     }
     ASSERT(pairs_remaining_ > 0);
     --pairs_remaining_;
-    cur_bci_ += reader_.ReadUInt() << pc_shifter_;
+    cur_bci_ += reader_.ReadUInt();
     cur_token_pos_ += reader_.ReadSLEB128();
+    is_yield_point_ = false;
+    if (cur_token_pos_ == kYieldPointMarker) {
+      const bool result = MoveNext();
+      is_yield_point_ = true;
+      return result;
+    }
     return true;
   }
 
@@ -358,12 +364,14 @@
 
   TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
 
+  bool IsYieldPoint() const { return is_yield_point_; }
+
  private:
   Reader reader_;
   intptr_t pairs_remaining_ = 0;
-  intptr_t pc_shifter_ = 0;
   intptr_t cur_bci_ = 0;
   intptr_t cur_token_pos_ = 0;
+  bool is_yield_point_ = false;
 };
 
 #if !defined(PRODUCT)
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index a69ee37..669bdae 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -168,10 +168,12 @@
         EvaluateNullLiteral();
         break;
       case kConstantExpression:
-        EvaluateConstantExpression(tag);
+        helper_->ReadPosition();
+        helper_->SkipDartType();
+        result_ = EvaluateConstantExpression(helper_->ReadUInt());
         break;
       case kDeprecated_ConstantExpression:
-        EvaluateConstantExpression(tag);
+        result_ = EvaluateConstantExpression(helper_->ReadUInt());
         break;
       default:
         H.ReportError(
@@ -291,6 +293,245 @@
   return metadata_values.raw();
 }
 
+RawInstance* ConstantEvaluator::EvaluateConstantExpression(
+    intptr_t constant_offset) {
+  ASSERT(!H.constants().IsNull());
+  ASSERT(!H.constants_table().IsNull());  // raw bytes
+
+  // For kernel-level cache (in contrast with script-level caching),
+  // we need to access the raw constants array inside the shared
+  // KernelProgramInfo directly, so that all scripts will see the
+  // results after new insertions. These accesses at kernel-level
+  // must be locked since mutator and background compiler can
+  // access the array at the same time.
+  {
+    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    KernelConstantsMap constant_map(H.info().constants());
+    result_ ^= constant_map.GetOrNull(constant_offset);
+    ASSERT(constant_map.Release().raw() == H.info().constants());
+  }
+
+  // On miss, evaluate, and insert value.
+  if (result_.IsNull()) {
+    result_ = EvaluateConstant(constant_offset);
+    SafepointMutexLocker ml(H.thread()->isolate()->kernel_constants_mutex());
+    KernelConstantsMap constant_map(H.info().constants());
+    auto insert = constant_map.InsertNewOrGetValue(constant_offset, result_);
+    ASSERT(insert == result_.raw());
+    H.info().set_constants(constant_map.Release());  // update!
+  }
+  return result_.raw();
+}
+
+RawInstance* ConstantEvaluator::EvaluateConstant(intptr_t constant_offset) {
+  // Get reader directly into raw bytes of constant table.
+  KernelReaderHelper reader(Z, &H, script_, H.constants_table(), 0);
+  reader.ReadUInt();  // skip variable-sized int for adjusted constant offset
+  reader.SetOffset(reader.ReaderOffset() + constant_offset);
+  // Construct constant from raw bytes.
+  Instance& instance = Instance::Handle(Z);
+  const intptr_t constant_tag = reader.ReadByte();
+  switch (constant_tag) {
+    case kNullConstant:
+      instance = Instance::null();
+      break;
+    case kBoolConstant:
+      instance = reader.ReadByte() == 1 ? Object::bool_true().raw()
+                                        : Object::bool_false().raw();
+      break;
+    case kIntConstant: {
+      uint8_t payload = 0;
+      Tag integer_tag = reader.ReadTag(&payload);  // read tag.
+      switch (integer_tag) {
+        case kBigIntLiteral: {
+          const String& value = H.DartString(reader.ReadStringReference());
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kSpecializedIntLiteral: {
+          const int64_t value =
+              static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kNegativeIntLiteral: {
+          const int64_t value = -static_cast<int64_t>(reader.ReadUInt());
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        case kPositiveIntLiteral: {
+          const int64_t value = reader.ReadUInt();
+          instance = Integer::New(value, Heap::kOld);
+          break;
+        }
+        default:
+          H.ReportError(
+              script_, TokenPosition::kNoSource,
+              "Cannot lazily read integer: unexpected kernel tag %s (%d)",
+              Reader::TagName(integer_tag), integer_tag);
+      }
+      break;
+    }
+    case kDoubleConstant:
+      instance = Double::New(reader.ReadDouble(), Heap::kOld);
+      break;
+    case kStringConstant:
+      instance = H.DartSymbolPlain(reader.ReadStringReference()).raw();
+      break;
+    case kSymbolConstant: {
+      Library& library = Library::Handle(Z);
+      library = Library::InternalLibrary();
+      const auto& symbol_class =
+          Class::Handle(Z, library.LookupClass(Symbols::Symbol()));
+      const auto& symbol_name_field = Field::Handle(
+          Z, symbol_class.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+      ASSERT(!symbol_name_field.IsNull());
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      if (index == -1) {
+        library = Library::null();
+      } else {
+        library = H.LookupLibraryByKernelLibrary(index);
+      }
+      const String& symbol =
+          H.DartIdentifier(library, reader.ReadStringReference());
+      instance = Instance::New(symbol_class, Heap::kOld);
+      instance.SetField(symbol_name_field, symbol);
+      break;
+    }
+    case kListConstant: {
+      const auto& corelib = Library::Handle(Z, Library::CoreLibrary());
+      const auto& list_class =
+          Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      auto& type_arguments =
+          TypeArguments::Handle(Z, TypeArguments::New(1, Heap::kOld));
+      AbstractType& type = type_translator.BuildType();
+      type_arguments.SetTypeAt(0, type);
+      // Instantiate class.
+      type = Type::New(list_class, type_arguments, TokenPosition::kNoSource);
+      type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+                                          ClassFinalizer::kCanonicalize);
+      type_arguments = type.arguments();
+      // Fill array with constant elements.
+      const intptr_t length = reader.ReadUInt();
+      const Array& array =
+          Array::Handle(Z, ImmutableArray::New(length, Heap::kOld));
+      array.SetTypeArguments(type_arguments);
+      Instance& constant = Instance::Handle(Z);
+      for (intptr_t j = 0; j < length; ++j) {
+        // Recurse into lazily evaluating all "sub" constants
+        // needed to evaluate the current constant.
+        const intptr_t entry_offset = reader.ReadUInt();
+        ASSERT(entry_offset < constant_offset);  // DAG!
+        constant = EvaluateConstantExpression(entry_offset);
+        array.SetAt(j, constant);
+      }
+      instance = array.raw();
+      break;
+    }
+    case kInstanceConstant: {
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      const auto& klass = Class::Handle(Z, H.LookupClassByKernelClass(index));
+      const auto& obj = Object::Handle(Z, klass.EnsureIsFinalized(H.thread()));
+      ASSERT(obj.IsNull());
+      instance = Instance::New(klass, Heap::kOld);
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      const intptr_t number_of_type_arguments = reader.ReadUInt();
+      if (klass.NumTypeArguments() > 0) {
+        auto& type_arguments = TypeArguments::Handle(
+            Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+        for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+          type_arguments.SetTypeAt(j, type_translator.BuildType());
+        }
+        // Instantiate class.
+        auto& type = AbstractType::Handle(
+            Z, Type::New(klass, type_arguments, TokenPosition::kNoSource));
+        type = ClassFinalizer::FinalizeType(*active_class_->klass, type,
+                                            ClassFinalizer::kCanonicalize);
+        type_arguments = type.arguments();
+        instance.SetTypeArguments(type_arguments);
+      } else {
+        ASSERT(number_of_type_arguments == 0);
+      }
+      // Set the fields.
+      const intptr_t number_of_fields = reader.ReadUInt();
+      Field& field = Field::Handle(Z);
+      Instance& constant = Instance::Handle(Z);
+      for (intptr_t j = 0; j < number_of_fields; ++j) {
+        field = H.LookupFieldByKernelField(reader.ReadCanonicalNameReference());
+        // Recurse into lazily evaluating all "sub" constants
+        // needed to evaluate the current constant.
+        const intptr_t entry_offset = reader.ReadUInt();
+        ASSERT(entry_offset < constant_offset);  // DAG!
+        constant = EvaluateConstantExpression(entry_offset);
+        instance.SetField(field, constant);
+      }
+      break;
+    }
+    case kPartialInstantiationConstant: {
+      // Recurse into lazily evaluating the "sub" constant
+      // needed to evaluate the current constant.
+      const intptr_t entry_offset = reader.ReadUInt();
+      ASSERT(entry_offset < constant_offset);  // DAG!
+      const auto& constant =
+          Instance::Handle(Z, EvaluateConstantExpression(entry_offset));
+      ASSERT(!constant.IsNull());
+
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      const intptr_t number_of_type_arguments = reader.ReadUInt();
+      ASSERT(number_of_type_arguments > 0);
+      auto& type_arguments = TypeArguments::Handle(
+          Z, TypeArguments::New(number_of_type_arguments, Heap::kOld));
+      for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
+        type_arguments.SetTypeAt(j, type_translator.BuildType());
+      }
+      type_arguments = type_arguments.Canonicalize();
+      // Make a copy of the old closure, and set delayed type arguments.
+      Closure& closure = Closure::Handle(Z, Closure::RawCast(constant.raw()));
+      Function& function = Function::Handle(Z, closure.function());
+      const auto& type_arguments2 =
+          TypeArguments::Handle(Z, closure.instantiator_type_arguments());
+      // The function type arguments are used for type parameters from enclosing
+      // closures. Though inner closures cannot be constants. We should
+      // therefore see `null here.
+      ASSERT(closure.function_type_arguments() == TypeArguments::null());
+      Context& context = Context::Handle(Z, closure.context());
+      instance = Closure::New(type_arguments2, Object::null_type_arguments(),
+                              type_arguments, function, context, Heap::kOld);
+      break;
+    }
+    case kTearOffConstant: {
+      const NameIndex index = reader.ReadCanonicalNameReference();
+      Function& function =
+          Function::Handle(Z, H.LookupStaticMethodByKernelProcedure(index));
+      function = function.ImplicitClosureFunction();
+      instance = function.ImplicitStaticClosure();
+      break;
+    }
+    case kTypeLiteralConstant: {
+      // Build type from the raw bytes (needs temporary translator).
+      TypeTranslator type_translator(&reader, active_class_, true);
+      instance = type_translator.BuildType().raw();
+      break;
+    }
+    default:
+      // Set literals (kSetConstant) are currently desugared in the frontend
+      // and will not reach the VM. See http://dartbug.com/35124 for some
+      // discussion. Map constants (kMapConstant ) are already lowered to
+      // InstanceConstant or ListConstant. We should never see unevaluated
+      // constants (kUnevaluatedConstant) in the constant table, they should
+      // have been fully evaluated before we get them.
+      H.ReportError(script_, TokenPosition::kNoSource,
+                    "Cannot lazily read constant: unexpected kernel tag (%" Pd
+                    ")",
+                    constant_tag);
+  }
+  return H.Canonicalize(instance);
+}
+
 void ConstantEvaluator::BailoutIfBackgroundCompilation() {
   if (Compiler::IsBackgroundCompilation()) {
     Compiler::AbortBackgroundCompilation(
@@ -331,7 +572,7 @@
                                                 TokenPosition position) {
   EvaluateExpression(expression_offset);
   if (result_.IsString()) {
-    const String& str = String::Handle(Z, String::RawCast(result_.raw()));
+    const auto& str = String::Handle(Z, String::RawCast(result_.raw()));
     result_ = Integer::New(str.Length(), H.allocation_space());
   } else {
     H.ReportError(
@@ -382,7 +623,7 @@
   ASSERT(Error::Handle(Z, H.thread()->sticky_error()).IsNull());
 
   if (H.IsField(target)) {
-    const Field& field = Field::Handle(Z, H.LookupFieldByKernelField(target));
+    const auto& field = Field::Handle(Z, H.LookupFieldByKernelField(target));
     if (!field.is_const()) {
       H.ReportError(script_, position, "Not a constant field.");
     }
@@ -394,7 +635,7 @@
       H.ReportError(script_, position, "Not a constant expression.");
     } else if (field.StaticValue() == Object::sentinel().raw()) {
       field.SetStaticValue(Object::transition_sentinel());
-      const Object& value = Object::Handle(Z, field.EvaluateInitializer());
+      const auto& value = Object::Handle(Z, field.EvaluateInitializer());
       if (value.IsError()) {
         field.SetStaticValue(Object::null_instance());
         H.ReportError(Error::Cast(value), script_, position,
@@ -418,12 +659,12 @@
       result_ = field.StaticValue();
     }
   } else if (H.IsProcedure(target)) {
-    const Function& function =
-        Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
+    const auto& function =
+        Function::Handle(Z, H.LookupStaticMethodByKernelProcedure(target));
 
     if (H.IsMethod(target)) {
-      Function& closure_function =
-          Function::ZoneHandle(Z, function.ImplicitClosureFunction());
+      const auto& closure_function =
+          Function::Handle(Z, function.ImplicitClosureFunction());
       result_ = closure_function.ImplicitStaticClosure();
       result_ = H.Canonicalize(result_);
     } else if (H.IsGetter(target)) {
@@ -437,7 +678,7 @@
 void ConstantEvaluator::EvaluateMethodInvocation() {
   TokenPosition position = helper_->ReadPosition();  // read position.
   // This method call wasn't cached, so receiver et al. isn't cached either.
-  const Instance& receiver = Instance::Handle(
+  const auto& receiver = Instance::Handle(
       Z, EvaluateExpression(helper_->ReaderOffset(), false));  // read receiver.
   Class& klass =
       Class::Handle(Z, isolate_->class_table()->At(receiver.GetClassId()));
@@ -463,13 +704,13 @@
 void ConstantEvaluator::EvaluateDirectMethodInvocation() {
   TokenPosition position = helper_->ReadPosition();  // read position.
 
-  const Instance& receiver = Instance::Handle(
+  const auto& receiver = Instance::Handle(
       Z, EvaluateExpression(helper_->ReaderOffset(), false));  // read receiver.
 
   NameIndex kernel_name =
       helper_->ReadCanonicalNameReference();  // read target_reference.
 
-  const Function& function = Function::ZoneHandle(
+  const auto& function = Function::Handle(
       Z, H.LookupMethodByMember(kernel_name, H.DartProcedureName(kernel_name)));
 
   // Read arguments, run the method and canonicalize the result.
@@ -493,7 +734,7 @@
   ASSERT(!klass.IsNull());
 
   const String& method_name = helper_->ReadNameAsMethodName();  // read name.
-  Function& function =
+  const auto& function =
       Function::Handle(Z, H.LookupDynamicFunction(klass, method_name));
 
   // The frontend should guarantee that [MethodInvocation]s inside constant
@@ -513,7 +754,7 @@
   NameIndex procedure_reference =
       helper_->ReadCanonicalNameReference();  // read procedure reference.
 
-  const Function& function = Function::ZoneHandle(
+  const auto& function = Function::Handle(
       Z, H.LookupStaticMethodByKernelProcedure(procedure_reference));
   Class& klass = Class::Handle(Z, function.Owner());
 
@@ -535,7 +776,7 @@
   TokenPosition position = helper_->ReadPosition();  // read position.
 
   NameIndex target = helper_->ReadCanonicalNameReference();  // read target.
-  const Function& constructor =
+  const auto& constructor =
       Function::Handle(Z, H.LookupConstructorByKernelConstructor(target));
   Class& klass = Class::Handle(Z, constructor.Owner());
 
@@ -547,12 +788,12 @@
       TranslateTypeArguments(constructor, &klass);  // read argument types.
 
   if (klass.NumTypeArguments() > 0 && !klass.IsGeneric()) {
-    Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw());
+    auto& type = Type::Handle(Z, T.ReceiverType(klass).raw());
     // TODO(27590): Can we move this code into [ReceiverType]?
     type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type,
                                          ClassFinalizer::kFinalize);
-    TypeArguments& canonicalized_type_arguments =
-        TypeArguments::ZoneHandle(Z, type.arguments());
+    auto& canonicalized_type_arguments =
+        TypeArguments::Handle(Z, type.arguments());
     canonicalized_type_arguments = canonicalized_type_arguments.Canonicalize();
     type_arguments = &canonicalized_type_arguments;
   }
@@ -627,7 +868,7 @@
 
   const AbstractType& type = T.BuildType();
   if (!type.IsInstantiated()) {
-    const String& type_str = String::Handle(type.UserVisibleName());
+    const auto& type_str = String::Handle(type.UserVisibleName());
     H.ReportError(
         script_, position,
         "Not a constant expression: right hand side of an implicit "
@@ -635,14 +876,14 @@
         type_str.ToCString());
   }
 
-  const TypeArguments& instantiator_type_arguments = TypeArguments::Handle();
-  const TypeArguments& function_type_arguments = TypeArguments::Handle();
+  const auto& instantiator_type_arguments = TypeArguments::Handle();
+  const auto& function_type_arguments = TypeArguments::Handle();
   if (!result_.IsInstanceOf(type, instantiator_type_arguments,
                             function_type_arguments)) {
     const AbstractType& rtype =
         AbstractType::Handle(result_.GetType(Heap::kNew));
-    const String& result_str = String::Handle(rtype.UserVisibleName());
-    const String& type_str = String::Handle(type.UserVisibleName());
+    const auto& result_str = String::Handle(rtype.UserVisibleName());
+    const auto& type_str = String::Handle(type.UserVisibleName());
     H.ReportError(
         script_, position,
         "Not a constant expression: Type '%s' is not a subtype of type '%s'",
@@ -683,13 +924,13 @@
     const Class& cls =
         Class::Handle(Z, Library::LookupCoreClass(Symbols::StringBase()));
     ASSERT(!cls.IsNull());
-    const Function& func = Function::Handle(
+    const auto& func = Function::Handle(
         Z, cls.LookupStaticFunction(
                Library::PrivateCoreLibName(Symbols::Interpolate())));
     ASSERT(!func.IsNull());
 
     // Build argument array to pass to the interpolation function.
-    const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
+    const auto& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
     interpolate_arg.SetAt(0, strings);
 
     // Run and canonicalize.
@@ -704,9 +945,9 @@
   const Library& lib = Library::Handle(Z, owner.library());
   String& symbol_value = H.DartIdentifier(lib, helper_->ReadStringReference());
   const Class& symbol_class =
-      Class::ZoneHandle(Z, I->object_store()->symbol_class());
+      Class::Handle(Z, I->object_store()->symbol_class());
   ASSERT(!symbol_class.IsNull());
-  const Function& symbol_constructor = Function::ZoneHandle(
+  const auto& symbol_constructor = Function::Handle(
       Z, symbol_class.LookupConstructor(Symbols::SymbolCtor()));
   ASSERT(!symbol_constructor.IsNull());
   result_ ^= EvaluateConstConstructorCall(
@@ -722,8 +963,7 @@
   helper_->ReadPosition();  // read position.
   const TypeArguments& type_arguments = T.BuildTypeArguments(1);  // read type.
   intptr_t length = helper_->ReadListLength();  // read list length.
-  const Array& const_list =
-      Array::ZoneHandle(Z, Array::New(length, Heap::kOld));
+  const auto& const_list = Array::Handle(Z, Array::New(length, Heap::kOld));
   const_list.SetTypeArguments(type_arguments);
   Instance& expression = Instance::Handle(Z);
   for (intptr_t i = 0; i < length; ++i) {
@@ -797,7 +1037,7 @@
 
 void ConstantEvaluator::EvaluatePartialTearoffInstantiation() {
   // This method call wasn't cached, so receiver et al. isn't cached either.
-  const Instance& receiver = Instance::Handle(
+  const auto& receiver = Instance::Handle(
       Z, EvaluateExpression(helper_->ReaderOffset(), false));  // read receiver.
   if (!receiver.IsClosure()) {
     H.ReportError(script_, TokenPosition::kNoSource, "Expected closure.");
@@ -868,20 +1108,6 @@
   result_ = Instance::null();
 }
 
-void ConstantEvaluator::EvaluateConstantExpression(Tag tag) {
-  // Please note that this constants array is constructed exactly once, see
-  // ReadConstantTable() and is immutable from that point on, so there is no
-  // need to guard against concurrent access between mutator and background
-  // compiler.
-  KernelConstantsMap constant_map(H.constants().raw());
-  if (tag == kConstantExpression) {
-    helper_->ReadPosition();
-    helper_->SkipDartType();
-  }
-  result_ ^= constant_map.GetOrDie(helper_->ReadUInt());
-  ASSERT(constant_map.Release().raw() == H.constants().raw());
-}
-
 // This depends on being about to read the list of positionals on arguments.
 const Object& ConstantEvaluator::RunFunction(TokenPosition position,
                                              const Function& function,
@@ -901,7 +1127,7 @@
       (receiver != NULL ? 1 : 0) + (type_args != NULL ? 1 : 0);
 
   // Build up arguments.
-  const Array& arguments = Array::Handle(
+  const auto& arguments = Array::Handle(
       Z, Array::New(extra_arguments + argument_count, H.allocation_space()));
   intptr_t pos = 0;
   if (receiver != NULL) {
@@ -941,9 +1167,9 @@
                                              const Array& names) {
   // We do not support generic methods yet.
   const int kTypeArgsLen = 0;
-  const Array& args_descriptor = Array::Handle(
+  const auto& args_descriptor = Array::Handle(
       Z, ArgumentsDescriptor::New(kTypeArgsLen, arguments.Length(), names));
-  const Object& result = Object::Handle(
+  const auto& result = Object::Handle(
       Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
   if (result.IsError()) {
     H.ReportError(Error::Cast(result), script_, position,
@@ -1003,7 +1229,7 @@
   const Array& args_descriptor =
       Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, argument_count,
                                                 Object::empty_array()));
-  const Object& result = Object::Handle(
+  const auto& result = Object::Handle(
       Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor));
   ASSERT(!result.IsError());
   if (constructor.IsFactory()) {
@@ -1093,7 +1319,7 @@
   const intptr_t kInitialConstMapSize = 16;
   ASSERT(!script_.InVMIsolateHeap());
   if (script_.compile_time_constants() == Array::null()) {
-    const Array& array = Array::Handle(
+    const auto& array = Array::Handle(
         HashTables::New<KernelConstantsMap>(kInitialConstMapSize, Heap::kNew));
     script_.set_compile_time_constants(array);
   }
@@ -1109,273 +1335,6 @@
   }
 }
 
-ConstantHelper::ConstantHelper(Zone* zone,
-                               KernelReaderHelper* helper,
-                               TypeTranslator* type_translator,
-                               ActiveClass* active_class,
-                               NameIndex skip_vmservice_library)
-    : zone_(zone),
-      helper_(*helper),
-      type_translator_(*type_translator),
-      active_class_(active_class),
-      const_evaluator_(helper, type_translator, active_class, nullptr),
-      translation_helper_(helper->translation_helper_),
-      skip_vmservice_library_(skip_vmservice_library),
-      symbol_class_(Class::Handle(zone)),
-      symbol_name_field_(Field::Handle(zone)),
-      temp_type_(AbstractType::Handle(zone)),
-      temp_type_arguments_(TypeArguments::Handle(zone)),
-      temp_type_arguments2_(TypeArguments::Handle(zone)),
-      temp_type_arguments3_(TypeArguments::Handle(zone)),
-      temp_object_(Object::Handle(zone)),
-      temp_string_(String::Handle(zone)),
-      temp_array_(Array::Handle(zone)),
-      temp_instance_(Instance::Handle(zone)),
-      temp_field_(Field::Handle(zone)),
-      temp_class_(Class::Handle(zone)),
-      temp_library_(Library::Handle(zone)),
-      temp_function_(Function::Handle(zone)),
-      temp_closure_(Closure::Handle(zone)),
-      temp_context_(Context::Handle(zone)),
-      temp_integer_(Integer::Handle(zone)) {
-  temp_library_ = Library::InternalLibrary();
-  ASSERT(!temp_library_.IsNull());
-
-  symbol_class_ = temp_library_.LookupClass(Symbols::Symbol());
-  ASSERT(!symbol_class_.IsNull());
-
-  symbol_name_field_ =
-      symbol_class_.LookupInstanceFieldAllowPrivate(Symbols::_name());
-  ASSERT(!symbol_name_field_.IsNull());
-}
-
-const Array& ConstantHelper::ReadConstantTable() {
-  const intptr_t number_of_constants = helper_.ReadUInt();
-  if (number_of_constants == 0) {
-    return Array::empty_array();
-  }
-
-  const Library& corelib = Library::Handle(Z, Library::CoreLibrary());
-  const Class& list_class =
-      Class::Handle(Z, corelib.LookupClassAllowPrivate(Symbols::_List()));
-
-  // Eagerly finalize _ImmutableList (instead of doing it on every list
-  // constant).
-  temp_class_ = I->class_table()->At(kImmutableArrayCid);
-  temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
-  ASSERT(temp_object_.IsNull());
-
-  KernelConstantsMap constants(
-      HashTables::New<KernelConstantsMap>(number_of_constants, Heap::kOld));
-
-  const intptr_t start_offset = helper_.ReaderOffset();
-
-  for (intptr_t i = 0; i < number_of_constants; ++i) {
-    const intptr_t offset = helper_.ReaderOffset();
-    const intptr_t constant_tag = helper_.ReadByte();
-    switch (constant_tag) {
-      case kNullConstant:
-        temp_instance_ = Instance::null();
-        break;
-      case kBoolConstant:
-        temp_instance_ = helper_.ReadByte() == 1 ? Object::bool_true().raw()
-                                                 : Object::bool_false().raw();
-        break;
-      case kIntConstant: {
-        temp_instance_ = const_evaluator_.EvaluateExpression(
-            helper_.ReaderOffset(), false /* reset position */);
-        break;
-      }
-      case kDoubleConstant: {
-        temp_instance_ = Double::New(helper_.ReadDouble(), Heap::kOld);
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kStringConstant: {
-        temp_instance_ =
-            H.Canonicalize(H.DartString(helper_.ReadStringReference()));
-        break;
-      }
-      case kSymbolConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (index == -1) {
-          temp_library_ = Library::null();
-        } else {
-          temp_library_ = H.LookupLibraryByKernelLibrary(index);
-        }
-        const String& symbol =
-            H.DartIdentifier(temp_library_, helper_.ReadStringReference());
-        temp_instance_ = Instance::New(symbol_class_, Heap::kOld);
-        temp_instance_.SetField(symbol_name_field_, symbol);
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kListConstant: {
-        temp_type_arguments_ = TypeArguments::New(1, Heap::kOld);
-        const AbstractType& type = type_translator_.BuildType();
-        temp_type_arguments_.SetTypeAt(0, type);
-        InstantiateTypeArguments(list_class, &temp_type_arguments_);
-
-        const intptr_t length = helper_.ReadUInt();
-        temp_array_ = ImmutableArray::New(length, Heap::kOld);
-        temp_array_.SetTypeArguments(temp_type_arguments_);
-        for (intptr_t j = 0; j < length; ++j) {
-          const intptr_t entry_offset = helper_.ReadUInt();
-          ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-          temp_object_ = constants.GetOrDie(entry_offset);
-          temp_array_.SetAt(j, temp_object_);
-        }
-
-        temp_instance_ = H.Canonicalize(temp_array_);
-        break;
-      }
-      case kSetConstant:
-        // Set literals are currently desugared in the frontend and will not
-        // reach the VM. See http://dartbug.com/35124 for discussion.
-        H.ReportError(script(), TokenPosition::kNoSource,
-                      "Unexpected set constant, this constant"
-                      " is expected to be evaluated at this point (%" Pd ")",
-                      constant_tag);
-        break;
-      case kInstanceConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (ShouldSkipConstant(index)) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        temp_class_ = H.LookupClassByKernelClass(index);
-        temp_object_ = temp_class_.EnsureIsFinalized(H.thread());
-        ASSERT(temp_object_.IsNull());
-
-        temp_instance_ = Instance::New(temp_class_, Heap::kOld);
-
-        const intptr_t number_of_type_arguments = helper_.ReadUInt();
-        if (temp_class_.NumTypeArguments() > 0) {
-          temp_type_arguments_ =
-              TypeArguments::New(number_of_type_arguments, Heap::kOld);
-          for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
-            temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
-          }
-          InstantiateTypeArguments(temp_class_, &temp_type_arguments_);
-          temp_instance_.SetTypeArguments(temp_type_arguments_);
-        } else {
-          ASSERT(number_of_type_arguments == 0);
-        }
-
-        const intptr_t number_of_fields = helper_.ReadUInt();
-        for (intptr_t j = 0; j < number_of_fields; ++j) {
-          temp_field_ =
-              H.LookupFieldByKernelField(helper_.ReadCanonicalNameReference());
-          const intptr_t entry_offset = helper_.ReadUInt();
-          ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-          temp_object_ = constants.GetOrDie(entry_offset);
-          temp_instance_.SetField(temp_field_, temp_object_);
-        }
-
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kPartialInstantiationConstant: {
-        const intptr_t entry_offset = helper_.ReadUInt();
-        ASSERT(entry_offset < (offset - start_offset));  // We have a DAG!
-        temp_object_ = constants.GetOrDie(entry_offset);
-
-        // Happens if the tearoff was in the vmservice library and we have
-        // [skip_vm_service_library] enabled.
-        if (temp_object_.IsNull()) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        const intptr_t number_of_type_arguments = helper_.ReadUInt();
-        ASSERT(number_of_type_arguments > 0);
-        temp_type_arguments_ =
-            TypeArguments::New(number_of_type_arguments, Heap::kOld);
-        for (intptr_t j = 0; j < number_of_type_arguments; ++j) {
-          temp_type_arguments_.SetTypeAt(j, type_translator_.BuildType());
-        }
-        temp_type_arguments_ = temp_type_arguments_.Canonicalize();
-
-        // Make a copy of the old closure, with the delayed type arguments
-        // set to [temp_type_arguments_].
-        temp_closure_ = Closure::RawCast(temp_object_.raw());
-        temp_function_ = temp_closure_.function();
-        temp_type_arguments2_ = temp_closure_.instantiator_type_arguments();
-        temp_type_arguments3_ = temp_closure_.function_type_arguments();
-        temp_context_ = temp_closure_.context();
-        temp_closure_ = Closure::New(
-            temp_type_arguments2_, Object::null_type_arguments(),
-            temp_type_arguments_, temp_function_, temp_context_, Heap::kOld);
-        temp_instance_ = H.Canonicalize(temp_closure_);
-        break;
-      }
-      case kTearOffConstant: {
-        const NameIndex index = helper_.ReadCanonicalNameReference();
-        if (ShouldSkipConstant(index)) {
-          temp_instance_ = Instance::null();
-          break;
-        }
-
-        temp_function_ = H.LookupStaticMethodByKernelProcedure(index);
-        temp_function_ = temp_function_.ImplicitClosureFunction();
-        temp_instance_ = temp_function_.ImplicitStaticClosure();
-        temp_instance_ = H.Canonicalize(temp_instance_);
-        break;
-      }
-      case kTypeLiteralConstant: {
-        temp_instance_ = type_translator_.BuildType().raw();
-        break;
-      }
-      case kMapConstant:
-        // Note: This is already lowered to InstanceConstant/ListConstant.
-        H.ReportError(script(), TokenPosition::kNoSource,
-                      "Unexpected map constant, this constant"
-                      " is expected to be evaluated at this point (%" Pd ")",
-                      constant_tag);
-        break;
-      case kUnevaluatedConstant:
-        // We should not see unevaluated constants in the constant table, they
-        // should have been fully evaluated before we get them.
-        H.ReportError(
-            script(), TokenPosition::kNoSource,
-            "Unexpected unevaluated constant, All constant expressions"
-            " are expected to be evaluated at this point (%" Pd ")",
-            constant_tag);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    constants.InsertNewOrGetValue(offset - start_offset, temp_instance_);
-  }
-  return Array::Handle(Z, constants.Release().raw());
-}
-
-void ConstantHelper::InstantiateTypeArguments(const Class& receiver_class,
-                                              TypeArguments* type_arguments) {
-  // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
-  // finalize the argument types.
-  // (This can for example make the [type_arguments] vector larger)
-  temp_type_ =
-      Type::New(receiver_class, *type_arguments, TokenPosition::kNoSource);
-  temp_type_ = ClassFinalizer::FinalizeType(*active_class_->klass, temp_type_,
-                                            ClassFinalizer::kCanonicalize);
-  *type_arguments = temp_type_.arguments();
-}
-
-// If [index] has `dart:vm_service` as a parent and we are skipping the VM
-// service library, this method returns `true`, otherwise `false`.
-bool ConstantHelper::ShouldSkipConstant(NameIndex index) {
-  if (index == NameIndex::kInvalidName) {
-    return false;
-  }
-  while (!H.IsLibrary(index)) {
-    index = H.CanonicalNameParent(index);
-  }
-  ASSERT(H.IsLibrary(index));
-  return index == skip_vmservice_library_;
-}
-
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.h b/runtime/vm/compiler/frontend/constant_evaluator.h
index 0483baa..7981835 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.h
+++ b/runtime/vm/compiler/frontend/constant_evaluator.h
@@ -56,7 +56,13 @@
   RawObject* EvaluateExpressionSafe(intptr_t offset);
   RawObject* EvaluateAnnotations();
 
+  // Evaluates a constant at the given offset (possibly by recursing
+  // into sub-constants).
+  RawInstance* EvaluateConstantExpression(intptr_t constant_offset);
+
  private:
+  RawInstance* EvaluateConstant(intptr_t constant_offset);
+
   void BailoutIfBackgroundCompilation();
 
   bool IsBuildingFlowGraph() const;
@@ -88,7 +94,6 @@
   void EvaluateDoubleLiteral();
   void EvaluateBoolLiteral(bool value);
   void EvaluateNullLiteral();
-  void EvaluateConstantExpression(Tag tag);
 
   void EvaluateGetStringLength(intptr_t expression_offset,
                                TokenPosition position);
@@ -140,59 +145,6 @@
   DISALLOW_COPY_AND_ASSIGN(ConstantEvaluator);
 };
 
-// Helper class that reads a kernel Constant from binary.
-class ConstantHelper {
- public:
-  ConstantHelper(Zone* zone,
-                 KernelReaderHelper* helper,
-                 TypeTranslator* type_translator,
-                 ActiveClass* active_class,
-                 NameIndex skip_vmservice_library);
-
-  // Reads the constant table from the binary.
-  //
-  // This method assumes the Reader is positioned already at the constant table
-  // and an active class scope is setup.
-  const Array& ReadConstantTable();
-
- private:
-  const Script& script() const { return helper_.script_; }
-
-  void InstantiateTypeArguments(const Class& receiver_class,
-                                TypeArguments* type_arguments);
-
-  // If [index] has `dart:vm_service` as a parent and we are skipping the VM
-  // service library, this method returns `true`, otherwise `false`.
-  bool ShouldSkipConstant(NameIndex index);
-
-  Zone* zone_;
-  KernelReaderHelper& helper_;
-  TypeTranslator& type_translator_;
-  ActiveClass* const active_class_;
-  ConstantEvaluator const_evaluator_;
-  TranslationHelper& translation_helper_;
-  NameIndex skip_vmservice_library_;
-  Class& symbol_class_;
-  Field& symbol_name_field_;
-  AbstractType& temp_type_;
-  TypeArguments& temp_type_arguments_;
-  TypeArguments& temp_type_arguments2_;
-  TypeArguments& temp_type_arguments3_;
-  Object& temp_object_;
-  String& temp_string_;
-  Array& temp_array_;
-  Instance& temp_instance_;
-  Field& temp_field_;
-  Class& temp_class_;
-  Library& temp_library_;
-  Function& temp_function_;
-  Closure& temp_closure_;
-  Context& temp_context_;
-  Integer& temp_integer_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConstantHelper);
-};
-
 class KernelConstMapKeyEqualsTraits : public AllStatic {
  public:
   static const char* Name() { return "KernelConstMapKeyEqualsTraits"; }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d018655..b046ba6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4,6 +4,7 @@
 
 #include "vm/compiler/frontend/kernel_binary_flowgraph.h"
 
+#include "vm/compiler/ffi.h"
 #include "vm/compiler/frontend/bytecode_flow_graph_builder.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/flow_graph_builder.h"  // For dart::FlowGraphBuilder::SimpleInstanceOfType.
@@ -774,12 +775,6 @@
     bool is_constructor) {
   const Function& dart_function = parsed_function()->function();
 
-  // The prologue builder needs the default parameter values.
-  SetupDefaultParameterValues();
-  // TypeArgumentsHandling / BuildDefaultTypeHandling needs
-  // default function type arguments.
-  ReadDefaultFunctionTypeArguments(dart_function);
-
   intptr_t type_parameters_offset = 0;
   LocalVariable* first_parameter = nullptr;
   TokenPosition token_position = TokenPosition::kNoSource;
@@ -961,9 +956,16 @@
     }
 
     ASSERT(function.HasBytecode());
+
     BytecodeFlowGraphBuilder bytecode_compiler(
         flow_graph_builder_, parsed_function(),
         &(flow_graph_builder_->ic_data_array_));
+
+    if (B->IsRecognizedMethodForFlowGraph(function)) {
+      bytecode_compiler.CreateParameterVariables();
+      return B->BuildGraphOfRecognizedMethod(function);
+    }
+
     return bytecode_compiler.BuildGraph();
   }
 
@@ -983,13 +985,12 @@
     case RawFunction::kRegularFunction:
     case RawFunction::kGetterFunction:
     case RawFunction::kSetterFunction:
-    case RawFunction::kClosureFunction: {
-      ReadUntilFunctionNode();
-      return BuildGraphOfFunction(false);
-    }
+    case RawFunction::kClosureFunction:
     case RawFunction::kConstructor: {
-      ReadUntilFunctionNode();
-      return BuildGraphOfFunction(!function.IsFactory());
+      if (B->IsRecognizedMethodForFlowGraph(function)) {
+        return B->BuildGraphOfRecognizedMethod(function);
+      }
+      return BuildGraphOfFunction(function.IsGenerativeConstructor());
     }
     case RawFunction::kImplicitGetter:
     case RawFunction::kImplicitStaticGetter:
@@ -1053,6 +1054,11 @@
     case RawFunction::kSetterFunction:
     case RawFunction::kClosureFunction:
     case RawFunction::kConstructor:
+    case RawFunction::kImplicitClosureFunction:
+      ReadUntilFunctionNode();
+      SetupDefaultParameterValues();
+      ReadDefaultFunctionTypeArguments(function);
+      break;
     case RawFunction::kImplicitGetter:
     case RawFunction::kImplicitStaticGetter:
     case RawFunction::kImplicitSetter:
@@ -1062,11 +1068,6 @@
     case RawFunction::kInvokeFieldDispatcher:
     case RawFunction::kFfiTrampoline:
       break;
-    case RawFunction::kImplicitClosureFunction:
-      ReadUntilFunctionNode();
-      SetupDefaultParameterValues();
-      ReadDefaultFunctionTypeArguments(function);
-      break;
     case RawFunction::kDynamicInvocationForwarder:
       if (PeekTag() != kField) {
         ReadUntilFunctionNode();
@@ -3048,6 +3049,10 @@
     ++argument_count;
   }
 
+  if (compiler::ffi::IsAsFunctionInternal(Z, Isolate::Current(), target)) {
+    return BuildFfiAsFunctionInternal();
+  }
+
   Fragment instructions;
   LocalVariable* instance_variable = NULL;
 
@@ -3776,10 +3781,8 @@
   }
   if (position != nullptr) *position = p;
   const intptr_t constant_offset = ReadUInt();
-  KernelConstantsMap constant_map(H.constants().raw());
-  Fragment result =
-      Constant(Object::ZoneHandle(Z, constant_map.GetOrDie(constant_offset)));
-  ASSERT(constant_map.Release().raw() == H.constants().raw());
+  Fragment result = Constant(Object::ZoneHandle(
+      Z, constant_evaluator_.EvaluateConstantExpression(constant_offset)));
   return result;
 }
 
@@ -5002,6 +5005,25 @@
   return instructions;
 }
 
+Fragment StreamingFlowGraphBuilder::BuildFfiAsFunctionInternal() {
+  const intptr_t argc = ReadUInt();               // read argument count.
+  ASSERT(argc == 1);                              // pointer
+  const intptr_t list_length = ReadListLength();  // read types list length.
+  ASSERT(list_length == 2);  // dart signature, then native signature
+  const TypeArguments& type_arguments =
+      T.BuildTypeArguments(list_length);  // read types.
+  Fragment code;
+  const intptr_t positional_count =
+      ReadListLength();  // read positional argument count
+  ASSERT(positional_count == 1);
+  code += BuildExpression();  // build first positional argument (pointer)
+  const intptr_t named_args_len =
+      ReadListLength();  // skip (empty) named arguments list
+  ASSERT(named_args_len == 0);
+  code += B->BuildFfiAsFunctionInternalCall(type_arguments);
+  return code;
+}
+
 }  // namespace kernel
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 2006924..ad86af8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -350,6 +350,10 @@
   Fragment BuildFunctionNode(TokenPosition parent_position,
                              StringIndex name_index);
 
+  // Build build FG for '_asFunctionInternal'. Reads an Arguments from the
+  // Kernel buffer and pushes the resulting closure.
+  Fragment BuildFfiAsFunctionInternal();
+
   FlowGraphBuilder* flow_graph_builder_;
   ActiveClass* const active_class_;
   TypeTranslator type_translator_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 8fa5799..04f2e53 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -216,16 +216,6 @@
   return instructions;
 }
 
-Fragment FlowGraphBuilder::AllocateObject(TokenPosition position,
-                                          const Class& klass,
-                                          intptr_t argument_count) {
-  ArgumentArray arguments = GetArguments(argument_count);
-  AllocateObjectInstr* allocate =
-      new (Z) AllocateObjectInstr(position, klass, arguments);
-  Push(allocate);
-  return Fragment(allocate);
-}
-
 Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
                                            intptr_t handler_index,
                                            bool needs_stacktrace,
@@ -741,13 +731,99 @@
 Fragment FlowGraphBuilder::NativeFunctionBody(const Function& function,
                                               LocalVariable* first_parameter) {
   ASSERT(function.is_native());
-  // We explicitly build the graph for native functions in the same way that the
-  // from-source backend does.  We should find a way to have a single component
-  // to build these graphs so that this code is not duplicated.
+  ASSERT(!IsRecognizedMethodForFlowGraph(function));
 
   Fragment body;
+  String& name = String::ZoneHandle(Z, function.native_name());
+  if (function.IsGeneric()) {
+    body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
+    body += PushArgument();
+  }
+  for (intptr_t i = 0; i < function.NumParameters(); ++i) {
+    body += LoadLocal(parsed_function_->RawParameterVariable(i));
+    body += PushArgument();
+  }
+  body += NativeCall(&name, &function);
+  // We typecheck results of native calls for type safety.
+  body +=
+      Return(TokenPosition::kNoSource, /* omit_result_type_check = */ false);
+  return body;
+}
+
+bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph(
+    const Function& function) {
   const MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
-  bool omit_result_type_check = true;
+
+  switch (kind) {
+// On simdbc we fall back to natives.
+#if !defined(TARGET_ARCH_DBC)
+    case MethodRecognizer::kTypedData_ByteDataView_factory:
+    case MethodRecognizer::kTypedData_Int8ArrayView_factory:
+    case MethodRecognizer::kTypedData_Uint8ArrayView_factory:
+    case MethodRecognizer::kTypedData_Uint8ClampedArrayView_factory:
+    case MethodRecognizer::kTypedData_Int16ArrayView_factory:
+    case MethodRecognizer::kTypedData_Uint16ArrayView_factory:
+    case MethodRecognizer::kTypedData_Int32ArrayView_factory:
+    case MethodRecognizer::kTypedData_Uint32ArrayView_factory:
+    case MethodRecognizer::kTypedData_Int64ArrayView_factory:
+    case MethodRecognizer::kTypedData_Uint64ArrayView_factory:
+    case MethodRecognizer::kTypedData_Float32ArrayView_factory:
+    case MethodRecognizer::kTypedData_Float64ArrayView_factory:
+    case MethodRecognizer::kTypedData_Float32x4ArrayView_factory:
+    case MethodRecognizer::kTypedData_Int32x4ArrayView_factory:
+    case MethodRecognizer::kTypedData_Float64x2ArrayView_factory:
+#endif  // !defined(TARGET_ARCH_DBC)
+    case MethodRecognizer::kObjectEquals:
+    case MethodRecognizer::kStringBaseLength:
+    case MethodRecognizer::kStringBaseIsEmpty:
+    case MethodRecognizer::kGrowableArrayLength:
+    case MethodRecognizer::kObjectArrayLength:
+    case MethodRecognizer::kImmutableArrayLength:
+    case MethodRecognizer::kTypedListLength:
+    case MethodRecognizer::kTypedListViewLength:
+    case MethodRecognizer::kByteDataViewLength:
+    case MethodRecognizer::kByteDataViewOffsetInBytes:
+    case MethodRecognizer::kTypedDataViewOffsetInBytes:
+    case MethodRecognizer::kByteDataViewTypedData:
+    case MethodRecognizer::kTypedDataViewTypedData:
+    case MethodRecognizer::kClassIDgetID:
+    case MethodRecognizer::kGrowableArrayCapacity:
+    case MethodRecognizer::kListFactory:
+    case MethodRecognizer::kObjectArrayAllocate:
+    case MethodRecognizer::kLinkedHashMap_getIndex:
+    case MethodRecognizer::kLinkedHashMap_setIndex:
+    case MethodRecognizer::kLinkedHashMap_getData:
+    case MethodRecognizer::kLinkedHashMap_setData:
+    case MethodRecognizer::kLinkedHashMap_getHashMask:
+    case MethodRecognizer::kLinkedHashMap_setHashMask:
+    case MethodRecognizer::kLinkedHashMap_getUsedData:
+    case MethodRecognizer::kLinkedHashMap_setUsedData:
+    case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
+    case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+      return true;
+    default:
+      return false;
+  }
+}
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
+    const Function& function) {
+  ASSERT(IsRecognizedMethodForFlowGraph(function));
+
+  graph_entry_ =
+      new (Z) GraphEntryInstr(*parsed_function_, Compiler::kNoOSRDeoptId);
+
+  auto normal_entry = BuildFunctionEntry(graph_entry_);
+  graph_entry_->set_normal_entry(normal_entry);
+
+  PrologueInfo prologue_info(-1, -1);
+  BlockEntryInstr* instruction_cursor =
+      BuildPrologue(normal_entry, &prologue_info);
+
+  Fragment body(instruction_cursor);
+  body += CheckStackOverflowInPrologue(function.token_pos());
+
+  const MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
   switch (kind) {
 // On simdbc we fall back to natives.
 #if !defined(TARGET_ARCH_DBC)
@@ -812,13 +888,13 @@
       break;
 #endif  // !defined(TARGET_ARCH_DBC)
     case MethodRecognizer::kObjectEquals:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += StrictCompare(Token::kEQ_STRICT);
       break;
     case MethodRecognizer::kStringBaseLength:
     case MethodRecognizer::kStringBaseIsEmpty:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::String_length());
       if (kind == MethodRecognizer::kStringBaseIsEmpty) {
         body += IntConstant(0);
@@ -826,36 +902,36 @@
       }
       break;
     case MethodRecognizer::kGrowableArrayLength:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::GrowableObjectArray_length());
       break;
     case MethodRecognizer::kObjectArrayLength:
     case MethodRecognizer::kImmutableArrayLength:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::Array_length());
       break;
     case MethodRecognizer::kTypedListLength:
     case MethodRecognizer::kTypedListViewLength:
     case MethodRecognizer::kByteDataViewLength:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::TypedDataBase_length());
       break;
     case MethodRecognizer::kByteDataViewOffsetInBytes:
     case MethodRecognizer::kTypedDataViewOffsetInBytes:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::TypedDataView_offset_in_bytes());
       break;
     case MethodRecognizer::kByteDataViewTypedData:
     case MethodRecognizer::kTypedDataViewTypedData:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::TypedDataView_data());
       break;
     case MethodRecognizer::kClassIDgetID:
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadClassId();
       break;
     case MethodRecognizer::kGrowableArrayCapacity:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::GrowableObjectArray_data());
       body += LoadNativeField(Slot::Array_length());
       break;
@@ -885,9 +961,9 @@
         ASSERT(!func.IsNull());
 
         Fragment allocate(allocate_non_growable);
-        allocate += LoadLocal(scopes_->type_arguments_variable);
+        allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
         allocate += PushArgument();
-        allocate += LoadLocal(first_parameter);
+        allocate += LoadLocal(parsed_function_->RawParameterVariable(1));
         allocate += PushArgument();
         allocate +=
             StaticCall(TokenPosition::kNoSource, func, 2, ICData::kStatic);
@@ -907,7 +983,7 @@
         ASSERT(!func.IsNull());
 
         Fragment allocate(allocate_growable);
-        allocate += LoadLocal(scopes_->type_arguments_variable);
+        allocate += LoadLocal(parsed_function_->RawParameterVariable(0));
         allocate += PushArgument();
         allocate += IntConstant(0);
         allocate += PushArgument();
@@ -924,85 +1000,78 @@
       break;
     }
     case MethodRecognizer::kObjectArrayAllocate:
-      body += LoadLocal(scopes_->type_arguments_variable);
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += CreateArray();
       break;
     case MethodRecognizer::kLinkedHashMap_getIndex:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::LinkedHashMap_index());
       break;
     case MethodRecognizer::kLinkedHashMap_setIndex:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += StoreInstanceField(TokenPosition::kNoSource,
                                  Slot::LinkedHashMap_index());
       body += NullConstant();
       break;
     case MethodRecognizer::kLinkedHashMap_getData:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::LinkedHashMap_data());
       break;
     case MethodRecognizer::kLinkedHashMap_setData:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += StoreInstanceField(TokenPosition::kNoSource,
                                  Slot::LinkedHashMap_data());
       body += NullConstant();
       break;
     case MethodRecognizer::kLinkedHashMap_getHashMask:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::LinkedHashMap_hash_mask());
       break;
     case MethodRecognizer::kLinkedHashMap_setHashMask:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body +=
           StoreInstanceField(TokenPosition::kNoSource,
                              Slot::LinkedHashMap_hash_mask(), kNoStoreBarrier);
       body += NullConstant();
       break;
     case MethodRecognizer::kLinkedHashMap_getUsedData:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::LinkedHashMap_used_data());
       break;
     case MethodRecognizer::kLinkedHashMap_setUsedData:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body +=
           StoreInstanceField(TokenPosition::kNoSource,
                              Slot::LinkedHashMap_used_data(), kNoStoreBarrier);
       body += NullConstant();
       break;
     case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
-      body += LoadLocal(parsed_function_->receiver_var());
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
       body += LoadNativeField(Slot::LinkedHashMap_deleted_keys());
       break;
     case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
-      body += LoadLocal(parsed_function_->receiver_var());
-      body += LoadLocal(first_parameter);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += StoreInstanceField(TokenPosition::kNoSource,
                                  Slot::LinkedHashMap_deleted_keys(),
                                  kNoStoreBarrier);
       body += NullConstant();
       break;
     default: {
-      String& name = String::ZoneHandle(Z, function.native_name());
-      if (function.IsGeneric()) {
-        body += LoadLocal(parsed_function_->RawTypeArgumentsVariable());
-        body += PushArgument();
-      }
-      for (intptr_t i = 0; i < function.NumParameters(); ++i) {
-        body += LoadLocal(parsed_function_->RawParameterVariable(i));
-        body += PushArgument();
-      }
-      body += NativeCall(&name, &function);
-      // We typecheck results of native calls for type safety.
-      omit_result_type_check = false;
+      UNREACHABLE();
       break;
     }
   }
-  return body + Return(TokenPosition::kNoSource, omit_result_type_check);
+
+  body += Return(TokenPosition::kNoSource, /* omit_result_type_check = */ true);
+
+  return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
+                           prologue_info);
 }
 
 Fragment FlowGraphBuilder::BuildTypedDataViewFactoryConstructor(
@@ -1148,8 +1217,7 @@
   if (definition->IsAllocateObject()) {
     return !definition->AsAllocateObject()->closure_function().IsNull();
   }
-  return definition->IsLoadLocal() &&
-         !definition->AsLoadLocal()->local().IsInternal();
+  return definition->IsLoadLocal();
 }
 
 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) {
@@ -2405,38 +2473,6 @@
   return Fragment(unbox);
 }
 
-Fragment FlowGraphBuilder::LoadAddressFromFfiPointer() {
-  Fragment test;
-  TargetEntryInstr* null_entry;
-  TargetEntryInstr* not_null_entry;
-  JoinEntryInstr* join = BuildJoinEntry();
-
-  LocalVariable* result = parsed_function_->expression_temp_var();
-
-  LocalVariable* pointer = MakeTemporary();
-  test += LoadLocal(pointer);
-  test += BranchIfNull(&null_entry, &not_null_entry);
-
-  Fragment load_0(null_entry);
-  load_0 += IntConstant(0);
-  load_0 += StoreLocal(TokenPosition::kNoSource, result);
-  load_0 += Drop();
-  load_0 += Goto(join);
-
-  Fragment unbox(not_null_entry);
-  unbox += LoadLocal(pointer);
-  unbox += LoadNativeField(Slot::Pointer_c_memory_address());
-  unbox += StoreLocal(TokenPosition::kNoSource, result);
-  unbox += Drop();
-  unbox += Goto(join);
-
-  Fragment done{test.entry, join};
-  done += Drop();
-  done += LoadLocal(result);
-
-  return done;
-}
-
 Fragment FlowGraphBuilder::Box(Representation from) {
   BoxInstr* box = BoxInstr::Create(from, Pop());
   Push(box);
@@ -2455,22 +2491,6 @@
   return Fragment(extend);
 }
 
-Fragment FlowGraphBuilder::FfiExceptionalReturnValue(
-    const AbstractType& result_type,
-    Representation representation) {
-  ASSERT(optimizing_);
-  Object& result = Object::ZoneHandle(Z, Object::null());
-  if (representation == kUnboxedFloat || representation == kUnboxedDouble) {
-    result = Double::New(0.0, Heap::kOld);
-  } else {
-    result = Integer::New(0, Heap::kOld);
-  }
-  Fragment code;
-  code += Constant(result);
-  code += UnboxTruncate(representation);
-  return code;
-}
-
 #if !defined(TARGET_ARCH_DBC)
 Fragment FlowGraphBuilder::NativeReturn(Representation result) {
   auto* instr = new (Z)
@@ -2481,58 +2501,35 @@
 #endif
 
 Fragment FlowGraphBuilder::FfiPointerFromAddress(const Type& result_type) {
-  Fragment test;
-  TargetEntryInstr* null_entry;
-  TargetEntryInstr* not_null_entry;
-  JoinEntryInstr* join = BuildJoinEntry();
-
   LocalVariable* address = MakeTemporary();
   LocalVariable* result = parsed_function_->expression_temp_var();
 
-  test += LoadLocal(address);
-  test += IntConstant(0);
-  test += BranchIfEqual(&null_entry, &not_null_entry);
+  Class& result_class = Class::ZoneHandle(Z, result_type.type_class());
+  // This class might only be instantiated as a return type of ffi calls.
+  result_class.EnsureIsFinalized(thread_);
 
-  // If the result is 0, we return null because "0 means null".
-  Fragment load_null(null_entry);
-  {
-    load_null += NullConstant();
-    load_null += StoreLocal(TokenPosition::kNoSource, result);
-    load_null += Drop();
-    load_null += Goto(join);
-  }
+  TypeArguments& args = TypeArguments::ZoneHandle(Z, result_type.arguments());
 
-  Fragment box(not_null_entry);
-  {
-    Class& result_class = Class::ZoneHandle(Z, result_type.type_class());
-    // This class might only be instantiated as a return type of ffi calls.
-    result_class.EnsureIsFinalized(thread_);
+  // A kernel transform for FFI in the front-end ensures that type parameters
+  // do not appear in the type arguments to a any Pointer classes in an FFI
+  // signature.
+  ASSERT(args.IsNull() || args.IsInstantiated());
 
-    TypeArguments& args = TypeArguments::ZoneHandle(Z, result_type.arguments());
+  Fragment code;
+  code += Constant(args);
+  code += PushArgument();
+  code += AllocateObject(TokenPosition::kNoSource, result_class, 1);
+  LocalVariable* pointer = MakeTemporary();
+  code += LoadLocal(pointer);
+  code += LoadLocal(address);
+  code += StoreInstanceField(TokenPosition::kNoSource,
+                             Slot::Pointer_c_memory_address());
+  code += StoreLocal(TokenPosition::kNoSource, result);
+  code += Drop();  // StoreLocal^
+  code += Drop();  // address
+  code += LoadLocal(result);
 
-    // A kernel transform for FFI in the front-end ensures that type parameters
-    // do not appear in the type arguments to a any Pointer classes in an FFI
-    // signature.
-    ASSERT(args.IsNull() || args.IsInstantiated());
-
-    box += Constant(args);
-    box += PushArgument();
-    box += AllocateObject(TokenPosition::kNoSource, result_class, 1);
-    LocalVariable* pointer = MakeTemporary();
-    box += LoadLocal(pointer);
-    box += LoadLocal(address);
-    box += StoreInstanceField(TokenPosition::kNoSource,
-                              Slot::Pointer_c_memory_address());
-    box += StoreLocal(TokenPosition::kNoSource, result);
-    box += Drop();
-    box += Goto(join);
-  }
-
-  Fragment rest(test.entry, join);
-  rest += Drop();
-  rest += LoadLocal(result);
-
-  return rest;
+  return code;
 }
 
 Fragment FlowGraphBuilder::BitCast(Representation from, Representation to) {
@@ -2569,16 +2566,22 @@
     const AbstractType& ffi_type,
     const Representation native_representation) {
   Fragment body;
-  // Check for 'null'. Only ffi.Pointers are allowed to be null.
-  if (!compiler::ffi::NativeTypeIsPointer(ffi_type)) {
-    body += LoadLocal(MakeTemporary());
-    body <<=
-        new (Z) CheckNullInstr(Pop(), String::ZoneHandle(Z, function.name()),
-                               GetNextDeoptId(), TokenPosition::kNoSource);
+
+  // Return 0 for void.
+  if (compiler::ffi::NativeTypeIsVoid(ffi_type)) {
+    body += Drop();
+    body += IntConstant(0);
+    body += UnboxTruncate(kUnboxedFfiIntPtr);
+    return body;
   }
 
+  // Check for 'null'.
+  body += LoadLocal(MakeTemporary());
+  body <<= new (Z) CheckNullInstr(Pop(), String::ZoneHandle(Z, function.name()),
+                                  GetNextDeoptId(), TokenPosition::kNoSource);
+
   if (compiler::ffi::NativeTypeIsPointer(ffi_type)) {
-    body += LoadAddressFromFfiPointer();
+    body += LoadNativeField(Slot::Pointer_c_memory_address());
     body += UnboxTruncate(kUnboxedFfiIntPtr);
   } else {
     Representation from_rep = compiler::ffi::TypeRepresentation(ffi_type);
@@ -2725,24 +2728,12 @@
   ++catch_depth_;
   Fragment catch_body =
       CatchBlockEntry(Array::empty_array(), try_handler_index,
-                      /*needs_stacktrace=*/true, /*is_synthesized=*/true);
+                      /*needs_stacktrace=*/false, /*is_synthesized=*/true);
 
-  catch_body += LoadLocal(CurrentException());
-  catch_body += PushArgument();
-  catch_body += LoadLocal(CurrentStackTrace());
-  catch_body += PushArgument();
-
-  // Find '_handleExposedException(e, st)' from ffi_patch.dart and call it.
-  const Library& ffi_lib =
-      Library::Handle(Z, Library::LookupLibrary(thread_, Symbols::DartFfi()));
-  const Function& handler = Function::ZoneHandle(
-      Z, ffi_lib.LookupFunctionAllowPrivate(Symbols::HandleExposedException()));
-  ASSERT(!handler.IsNull());
-  catch_body += StaticCall(TokenPosition::kNoSource, handler, /*num_args=*/2,
-                           /*arg_names=*/Array::empty_array(), ICData::kStatic);
-  catch_body += Drop();
-
-  catch_body += FfiExceptionalReturnValue(ffi_type, result_rep);
+  // Return the "exceptional return" value given in 'fromFunction'.
+  catch_body += Constant(
+      Instance::ZoneHandle(Z, function.FfiCallbackExceptionalReturn()));
+  catch_body += FfiConvertArgumentToNative(function, ffi_type, result_rep);
   catch_body += NativeReturn(result_rep);
   --catch_depth_;
 
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 9ccc1a94..5b7c662 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -107,6 +107,9 @@
   Fragment NativeFunctionBody(const Function& function,
                               LocalVariable* first_parameter);
 
+  bool IsRecognizedMethodForFlowGraph(const Function& function);
+  FlowGraph* BuildGraphOfRecognizedMethod(const Function& function);
+
   Fragment BuildTypedDataViewFactoryConstructor(const Function& function,
                                                 classid_t cid);
 
@@ -124,9 +127,6 @@
   Fragment TranslateInstantiatedTypeArguments(
       const TypeArguments& type_arguments);
 
-  Fragment AllocateObject(TokenPosition position,
-                          const Class& klass,
-                          intptr_t argument_count);
   Fragment CatchBlockEntry(const Array& handler_types,
                            intptr_t handler_index,
                            bool needs_stacktrace,
@@ -226,16 +226,7 @@
   Fragment FfiUnboxedExtend(Representation representation,
                             const AbstractType& ffi_type);
 
-  // Pops an 'ffi.Pointer' off the stack.
-  // If it's null, pushes 0.
-  // Otherwise pushes the address (in boxed representation).
-  Fragment LoadAddressFromFfiPointer();
-
-  // Reverse of 'LoadPointerFromFfiPointer':
-  // Pops an integer off the the stack.
-  // If it's zero, pushes null.
-  // If it's nonzero, creates an 'ffi.Pointer' holding the address and pushes
-  // the pointer.
+  // Creates an ffi.Pointer holding a given address (TOS).
   Fragment FfiPointerFromAddress(const Type& result_type);
 
   // Pushes an (unboxed) bogus value returned when a native -> Dart callback
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 35c0178..938a22a 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -32,6 +32,7 @@
       metadata_payloads_(ExternalTypedData::Handle(Z)),
       metadata_mappings_(ExternalTypedData::Handle(Z)),
       constants_(Array::Handle(Z)),
+      constants_table_(ExternalTypedData::Handle(Z)),
       info_(KernelProgramInfo::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)) {}
 
@@ -46,6 +47,7 @@
       metadata_payloads_(ExternalTypedData::Handle(Z)),
       metadata_mappings_(ExternalTypedData::Handle(Z)),
       constants_(Array::Handle(Z)),
+      constants_table_(ExternalTypedData::Handle(Z)),
       info_(KernelProgramInfo::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)) {}
 
@@ -79,6 +81,7 @@
   SetMetadataPayloads(ExternalTypedData::Handle(Z, info.metadata_payloads()));
   SetMetadataMappings(ExternalTypedData::Handle(Z, info.metadata_mappings()));
   SetConstants(Array::Handle(Z, info.constants()));
+  SetConstantsTable(ExternalTypedData::Handle(Z, info.constants_table()));
   SetKernelProgramInfo(info);
 }
 
@@ -92,6 +95,23 @@
   return funcs.raw();
 }
 
+void TranslationHelper::AddPotentialExtensionLibrary(const Library& library) {
+  if (potential_extension_libraries_ == nullptr) {
+    potential_extension_libraries_ =
+        &GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  }
+  potential_extension_libraries_->Add(library);
+}
+
+RawGrowableObjectArray* TranslationHelper::GetPotentialExtensionLibraries() {
+  if (potential_extension_libraries_ != nullptr) {
+    GrowableObjectArray* result = potential_extension_libraries_;
+    potential_extension_libraries_ = nullptr;
+    return result->raw();
+  }
+  return GrowableObjectArray::null();
+}
+
 void TranslationHelper::SetStringOffsets(const TypedData& string_offsets) {
   ASSERT(string_offsets_.IsNull());
   string_offsets_ = string_offsets.raw();
@@ -126,6 +146,12 @@
   constants_ = constants.raw();
 }
 
+void TranslationHelper::SetConstantsTable(
+    const ExternalTypedData& constants_table) {
+  ASSERT(constants_table_.IsNull());
+  constants_table_ = constants_table.raw();
+}
+
 void TranslationHelper::SetKernelProgramInfo(const KernelProgramInfo& info) {
   info_ = info.raw();
 }
@@ -2900,9 +2926,10 @@
       }
       parameter_index -= class_types.Length();
     }
-
+    // Factory function should not be considered as procedure.
     intptr_t procedure_type_parameter_count =
-        active_class_->MemberIsProcedure()
+        (active_class_->MemberIsProcedure() &&
+         !active_class_->MemberIsFactoryProcedure())
             ? active_class_->MemberTypeParameterCount(Z)
             : 0;
     if (procedure_type_parameter_count > 0) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 1dc3f3c4..3e4340d 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -41,26 +41,40 @@
   Heap::Space allocation_space() { return allocation_space_; }
 
   // Access to strings.
-  const TypedData& string_offsets() { return string_offsets_; }
+  const TypedData& string_offsets() const { return string_offsets_; }
   void SetStringOffsets(const TypedData& string_offsets);
 
-  const ExternalTypedData& string_data() { return string_data_; }
+  const ExternalTypedData& string_data() const { return string_data_; }
   void SetStringData(const ExternalTypedData& string_data);
 
-  const TypedData& canonical_names() { return canonical_names_; }
+  const TypedData& canonical_names() const { return canonical_names_; }
   void SetCanonicalNames(const TypedData& canonical_names);
 
-  const ExternalTypedData& metadata_payloads() { return metadata_payloads_; }
+  const ExternalTypedData& metadata_payloads() const {
+    return metadata_payloads_;
+  }
   void SetMetadataPayloads(const ExternalTypedData& metadata_payloads);
 
-  const ExternalTypedData& metadata_mappings() { return metadata_mappings_; }
+  const ExternalTypedData& metadata_mappings() const {
+    return metadata_mappings_;
+  }
   void SetMetadataMappings(const ExternalTypedData& metadata_mappings);
 
+  // Access to previously evaluated constants from the constants table.
   const Array& constants() { return constants_; }
   void SetConstants(const Array& constants);
 
+  // Access to the raw bytes of the constants table.
+  const ExternalTypedData& constants_table() const { return constants_table_; }
+  void SetConstantsTable(const ExternalTypedData& constants_table);
+
+  KernelProgramInfo& info() { return info_; }
+
   RawGrowableObjectArray* EnsurePotentialPragmaFunctions();
 
+  void AddPotentialExtensionLibrary(const Library& library);
+  RawGrowableObjectArray* GetPotentialExtensionLibraries();
+
   void SetKernelProgramInfo(const KernelProgramInfo& info);
   const KernelProgramInfo& GetKernelProgramInfo() const { return info_; }
 
@@ -206,8 +220,10 @@
   ExternalTypedData& metadata_payloads_;
   ExternalTypedData& metadata_mappings_;
   Array& constants_;
+  ExternalTypedData& constants_table_;
   KernelProgramInfo& info_;
   Smi& name_index_handle_;
+  GrowableObjectArray* potential_extension_libraries_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(TranslationHelper);
 };
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 66e293f..16b59b8 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -98,9 +98,6 @@
 
     FLAG_background_compilation = false;
     FLAG_enable_mirrors = false;
-    // TODO(dacoharkes): Ffi support in AOT
-    // https://github.com/dart-lang/sdk/issues/35765
-    FLAG_enable_ffi = false;
     FLAG_fields_may_be_reset = true;
     FLAG_interpret_irregexp = true;
     FLAG_lazy_dispatchers = false;
@@ -378,9 +375,7 @@
   // CreateDeoptInfo uses the object pool and needs to be done before
   // FinalizeCode.
   Array& deopt_info_array = Array::Handle(zone, Object::empty_array().raw());
-  if (!function.ForceOptimize()) {
-    deopt_info_array = graph_compiler->CreateDeoptInfo(assembler);
-  }
+  deopt_info_array = graph_compiler->CreateDeoptInfo(assembler);
 
   // Allocates instruction object. Since this occurs only at safepoint,
   // there can be no concurrent access to the instruction page.
@@ -408,9 +403,8 @@
 
   if (function.ForceOptimize()) {
     ASSERT(optimized() && thread()->IsMutatorThread());
-    code.set_is_optimized(false);
+    code.set_is_force_optimized(true);
     function.AttachCode(code);
-    function.set_unoptimized_code(code);
     function.SetWasCompiled(true);
   } else if (optimized()) {
     // Installs code while at safepoint.
@@ -947,6 +941,7 @@
 
 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
                                           const Function& function) {
+  ASSERT(!function.ForceOptimize());
   if (function.unoptimized_code() != Object::null()) {
     return Error::null();
   }
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index aec5b3e..af363e6 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -275,8 +275,9 @@
 
     offset_into_target += (entry_point - destination_payload);
 
-    const intptr_t text_offset =
-        code_text_offset + Instructions::HeaderSize() + offset;
+    const intptr_t text_offset = code_text_offset +
+                                 compiler::target::Instructions::HeaderSize() +
+                                 offset;
     UnresolvedCall unresolved_call(code.raw(), offset, text_offset,
                                    destination_.raw(), offset_into_target);
     if (!TryResolveBackwardsCall(&unresolved_call)) {
@@ -502,7 +503,8 @@
     const RawInstructions* destination,
     intptr_t offset_into_target) {
   auto destination_offset = text_offsets_.LookupValue(destination);
-  return destination_offset + Instructions::HeaderSize() + offset_into_target;
+  return destination_offset + compiler::target::Instructions::HeaderSize() +
+         offset_into_target;
 }
 
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 0c35ced..ff30fd9 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/compiler/runtime_api.h"
+#include "platform/utils.h"
 
 namespace dart {
 namespace compiler {
@@ -10,6 +11,10 @@
 
 #include "vm/compiler/runtime_offsets_extracted.h"
 
+bool IsSmi(int64_t v) {
+  return Utils::IsInt(kSmiBits + 1, v);
+}
+
 }  // namespace target
 }  // namespace compiler
 }  // namespace dart
@@ -561,11 +566,7 @@
     "Expected that size of Smi on HOST is at least as large as on target.");
 
 bool IsSmi(const dart::Object& a) {
-  return a.IsSmi() && Utils::IsInt(kSmiBits + 1, dart::Smi::Cast(a).Value());
-}
-
-bool IsSmi(int64_t v) {
-  return Utils::IsInt(kSmiBits + 1, v);
+  return a.IsSmi() && IsSmi(dart::Smi::Cast(a).Value());
 }
 
 word ToRawSmi(const dart::Object& a) {
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index bf791bc..a3ceb18 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -74,10 +74,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    102;
+    106;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 92;
+    Class_type_arguments_field_offset_in_words_offset = 96;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
@@ -427,10 +427,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     112;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    186;
+    190;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 176;
+    Class_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
@@ -781,10 +781,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    102;
+    106;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 92;
+    Class_type_arguments_field_offset_in_words_offset = 96;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
@@ -1130,10 +1130,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     112;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    186;
+    190;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 176;
+    Class_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
@@ -1487,10 +1487,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     112;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    186;
+    190;
 static constexpr dart::compiler::target::word Class_super_type_offset = 88;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 176;
+    Class_type_arguments_field_offset_in_words_offset = 180;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
@@ -1771,10 +1771,10 @@
 static constexpr dart::compiler::target::word Class_declaration_type_offset =
     56;
 static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
-    102;
+    106;
 static constexpr dart::compiler::target::word Class_super_type_offset = 44;
 static constexpr dart::compiler::target::word
-    Class_type_arguments_field_offset_in_words_offset = 92;
+    Class_type_arguments_field_offset_in_words_offset = 96;
 static constexpr dart::compiler::target::word
     ClassHeapStats_TraceAllocationMask = 1;
 static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 2f3b1b0..26d8c00 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -782,6 +782,12 @@
       COMPILE_ASSERT(R25 > CODE_REG);
       __ ldr(R25, Address(FP, 2 * target::kWordSize));
       __ str(R25, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+    } else if (r == R15) {
+      // Because we save registers in decreasing order, IP0 will already be
+      // saved.
+      COMPILE_ASSERT(IP0 == R16);
+      __ mov(IP0, R15);
+      __ str(IP0, Address(SP, -1 * target::kWordSize, Address::PreIndex));
     } else {
       __ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
     }
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 8bf0e39..e0b1193 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -202,8 +202,7 @@
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   Dart_Handle obj_handle =
       Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL);
-  EXPECT(!Dart_IsNull(obj_handle));
-  EXPECT(!Dart_IsError(obj_handle));
+  EXPECT_VALID(obj_handle);
   TransitionNativeToVM transition(thread);
   const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
   EXPECT(!obj.IsNull());
diff --git a/runtime/vm/constants_kbc.cc b/runtime/vm/constants_kbc.cc
index d5ed600..adbe0421 100644
--- a/runtime/vm/constants_kbc.cc
+++ b/runtime/vm/constants_kbc.cc
@@ -7,10 +7,6 @@
 
 namespace dart {
 
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-              "Cleanup support for old bytecode format versions");
-static const intptr_t kOldInstructionSize = 4;
-
 static const intptr_t kInstructionSize0 = 1;
 static const intptr_t kInstructionSizeA = 2;
 static const intptr_t kInstructionSizeD = 2;
@@ -28,13 +24,11 @@
 static const intptr_t kInstructionSizeA_B_C = 4;
 
 const intptr_t KernelBytecode::kInstructionSize[] = {
-#define SIZE_OLD(encoding) kOldInstructionSize
 #define SIZE_ORDN(encoding) kInstructionSize##encoding
 #define SIZE_WIDE(encoding) kInstructionSizeWide##encoding
 #define SIZE_RESV(encoding) SIZE_ORDN(encoding)
 #define SIZE(name, encoding, kind, op1, op2, op3) SIZE_##kind(encoding),
     KERNEL_BYTECODES_LIST(SIZE)
-#undef SIZE_OLD
 #undef SIZE_ORDN
 #undef SIZE_WIDE
 #undef SIZE_RESV
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 5c422d8..0849572 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -453,9 +453,9 @@
 //     V(BytecodeName, OperandForm, BytecodeKind, Op1, Op2, Op3)
 //
 // - OperandForm specifies operand encoding and should be one of 0, A, D, X, T,
-//   A_D (old), A_X (old), A_E, A_Y, D_F or A_B_C (see ENCODING section above).
+//   A_E, A_Y, D_F or A_B_C (see ENCODING section above).
 //
-// - BytecodeKind is one of OLD, WIDE, RESV (reserved), ORDN (ordinary)
+// - BytecodeKind is one of WIDE, RESV (reserved), ORDN (ordinary)
 //
 // - Op1, Op2, Op3 specify operand meaning. Possible values:
 //
@@ -471,91 +471,91 @@
 //               and before decoding.
 //
 #define PUBLIC_KERNEL_BYTECODES_LIST(V)                                        \
-  V(Trap_Old,                              0,  OLD, ___, ___, ___)             \
-  V(Entry_Old,                             D,  OLD, num, ___, ___)             \
-  V(EntryFixed_Old,                      A_D,  OLD, num, num, ___)             \
-  V(EntryOptional_Old,                 A_B_C,  OLD, num, num, num)             \
-  V(LoadConstant_Old,                    A_D,  OLD, reg, lit, ___)             \
-  V(Frame_Old,                             D,  OLD, num, ___, ___)             \
-  V(CheckFunctionTypeArgs_Old,           A_D,  OLD, num, reg, ___)             \
-  V(CheckStack_Old,                        A,  OLD, num, ___, ___)             \
-  V(Allocate_Old,                          D,  OLD, lit, ___, ___)             \
-  V(AllocateT_Old,                         0,  OLD, ___, ___, ___)             \
-  V(CreateArrayTOS_Old,                    0,  OLD, ___, ___, ___)             \
-  V(AllocateContext_Old,                   D,  OLD, num, ___, ___)             \
-  V(CloneContext_Old,                      D,  OLD, num, ___, ___)             \
-  V(LoadContextParent_Old,                 0,  OLD, ___, ___, ___)             \
-  V(StoreContextParent_Old,                0,  OLD, ___, ___, ___)             \
-  V(LoadContextVar_Old,                    D,  OLD, num, ___, ___)             \
-  V(StoreContextVar_Old,                   D,  OLD, num, ___, ___)             \
-  V(PushConstant_Old,                      D,  OLD, lit, ___, ___)             \
-  V(PushNull_Old,                          0,  OLD, ___, ___, ___)             \
-  V(PushTrue_Old,                          0,  OLD, ___, ___, ___)             \
-  V(PushFalse_Old,                         0,  OLD, ___, ___, ___)             \
-  V(PushInt_Old,                           X,  OLD, num, ___, ___)             \
-  V(Drop1_Old,                             0,  OLD, ___, ___, ___)             \
-  V(Push_Old,                              X,  OLD, xeg, ___, ___)             \
-  V(PopLocal_Old,                          X,  OLD, xeg, ___, ___)             \
-  V(StoreLocal_Old,                        X,  OLD, xeg, ___, ___)             \
-  V(LoadFieldTOS_Old,                      D,  OLD, lit, ___, ___)             \
-  V(StoreFieldTOS_Old,                     D,  OLD, lit, ___, ___)             \
-  V(StoreIndexedTOS_Old,                   0,  OLD, ___, ___, ___)             \
-  V(PushStatic_Old,                        D,  OLD, lit, ___, ___)             \
-  V(StoreStaticTOS_Old,                    D,  OLD, lit, ___, ___)             \
-  V(Jump_Old,                              T,  OLD, tgt, ___, ___)             \
-  V(JumpIfNoAsserts_Old,                   T,  OLD, tgt, ___, ___)             \
-  V(JumpIfNotZeroTypeArgs_Old,             T,  OLD, tgt, ___, ___)             \
-  V(JumpIfEqStrict_Old,                    T,  OLD, tgt, ___, ___)             \
-  V(JumpIfNeStrict_Old,                    T,  OLD, tgt, ___, ___)             \
-  V(JumpIfTrue_Old,                        T,  OLD, tgt, ___, ___)             \
-  V(JumpIfFalse_Old,                       T,  OLD, tgt, ___, ___)             \
-  V(JumpIfNull_Old,                        T,  OLD, tgt, ___, ___)             \
-  V(JumpIfNotNull_Old,                     T,  OLD, tgt, ___, ___)             \
-  V(Unused00_Old,                          0, RESV, num, num, ___)             \
-  V(InterfaceCall_Old,                   A_D,  OLD, num, num, ___)             \
-  V(DynamicCall_Old,                     A_D,  OLD, num, num, ___)             \
-  V(NativeCall_Old,                        D,  OLD, lit, ___, ___)             \
-  V(ReturnTOS_Old,                         0,  OLD, ___, ___, ___)             \
-  V(AssertAssignable_Old,                A_D,  OLD, num, lit, ___)             \
-  V(AssertBoolean_Old,                     A,  OLD, num, ___, ___)             \
-  V(AssertSubtype_Old,                     0,  OLD, ___, ___, ___)             \
-  V(LoadTypeArgumentsField_Old,            D,  OLD, lit, ___, ___)             \
-  V(InstantiateType_Old,                   D,  OLD, lit, ___, ___)             \
-  V(InstantiateTypeArgumentsTOS_Old,     A_D,  OLD, num, lit, ___)             \
-  V(Throw_Old,                             A,  OLD, num, ___, ___)             \
-  V(MoveSpecial_Old,                     A_X,  OLD, num, xeg, ___)             \
-  V(SetFrame_Old,                          A,  OLD, num, ___, num)             \
-  V(BooleanNegateTOS_Old,                  0,  OLD, ___, ___, ___)             \
-  V(EqualsNull_Old,                        0,  OLD, ___, ___, ___)             \
-  V(NegateInt_Old,                         0,  OLD, ___, ___, ___)             \
-  V(AddInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(SubInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(MulInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(TruncDivInt_Old,                       0,  OLD, ___, ___, ___)             \
-  V(ModInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(BitAndInt_Old,                         0,  OLD, ___, ___, ___)             \
-  V(BitOrInt_Old,                          0,  OLD, ___, ___, ___)             \
-  V(BitXorInt_Old,                         0,  OLD, ___, ___, ___)             \
-  V(ShlInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(ShrInt_Old,                            0,  OLD, ___, ___, ___)             \
-  V(CompareIntEq_Old,                      0,  OLD, ___, ___, ___)             \
-  V(CompareIntGt_Old,                      0,  OLD, ___, ___, ___)             \
-  V(CompareIntLt_Old,                      0,  OLD, ___, ___, ___)             \
-  V(CompareIntGe_Old,                      0,  OLD, ___, ___, ___)             \
-  V(CompareIntLe_Old,                      0,  OLD, ___, ___, ___)             \
-  V(DirectCall_Old,                      A_D,  OLD, num, num, ___)             \
-  V(AllocateClosure_Old,                   D,  OLD, lit, ___, ___)             \
-  V(UncheckedInterfaceCall_Old,          A_D,  OLD, num, num, ___)             \
-  V(NegateDouble_Old,                      0,  OLD, ___, ___, ___)             \
-  V(AddDouble_Old,                         0,  OLD, ___, ___, ___)             \
-  V(SubDouble_Old,                         0,  OLD, ___, ___, ___)             \
-  V(MulDouble_Old,                         0,  OLD, ___, ___, ___)             \
-  V(DivDouble_Old,                         0,  OLD, ___, ___, ___)             \
-  V(CompareDoubleEq_Old,                   0,  OLD, ___, ___, ___)             \
-  V(CompareDoubleGt_Old,                   0,  OLD, ___, ___, ___)             \
-  V(CompareDoubleLt_Old,                   0,  OLD, ___, ___, ___)             \
-  V(CompareDoubleGe_Old,                   0,  OLD, ___, ___, ___)             \
-  V(CompareDoubleLe_Old,                   0,  OLD, ___, ___, ___)             \
+  V(UnusedOpcode000,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode001,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode002,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode003,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode004,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode005,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode006,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode007,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode008,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode009,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode010,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode011,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode012,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode013,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode014,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode015,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode016,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode017,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode018,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode019,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode020,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode021,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode022,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode023,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode024,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode025,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode026,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode027,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode028,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode029,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode030,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode031,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode032,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode033,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode034,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode035,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode036,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode037,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode038,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode039,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode040,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode041,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode042,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode043,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode044,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode045,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode046,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode047,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode048,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode049,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode050,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode051,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode052,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode053,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode054,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode055,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode056,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode057,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode058,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode059,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode060,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode061,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode062,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode063,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode064,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode065,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode066,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode067,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode068,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode069,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode070,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode071,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode072,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode073,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode074,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode075,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode076,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode077,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode078,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode079,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode080,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode081,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode082,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode083,                       0, RESV, ___, ___, ___)             \
+  V(UnusedOpcode084,                       0, RESV, ___, ___, ___)             \
   V(Trap,                                  0, ORDN, ___, ___, ___)             \
   V(Entry,                                 D, ORDN, num, ___, ___)             \
   V(Entry_Wide,                            D, WIDE, num, ___, ___)             \
@@ -579,18 +579,18 @@
   V(CreateArrayTOS,                        0, ORDN, ___, ___, ___)             \
   V(AllocateClosure,                       D, ORDN, lit, ___, ___)             \
   V(AllocateClosure_Wide,                  D, WIDE, lit, ___, ___)             \
-  V(AllocateContext,                     A_E, ORDN, num, ___, ___)             \
-  V(AllocateContext_Wide,                A_E, WIDE, num, ___, ___)             \
-  V(CloneContext,                        A_E, ORDN, num, ___, ___)             \
-  V(CloneContext_Wide,                   A_E, WIDE, num, ___, ___)             \
+  V(AllocateContext,                     A_E, ORDN, num, num, ___)             \
+  V(AllocateContext_Wide,                A_E, WIDE, num, num, ___)             \
+  V(CloneContext,                        A_E, ORDN, num, num, ___)             \
+  V(CloneContext_Wide,                   A_E, WIDE, num, num, ___)             \
   V(LoadContextParent,                     0, ORDN, ___, ___, ___)             \
   V(StoreContextParent,                    0, ORDN, ___, ___, ___)             \
-  V(LoadContextVar,                      A_E, ORDN, num, ___, ___)             \
-  V(LoadContextVar_Wide,                 A_E, WIDE, num, ___, ___)             \
+  V(LoadContextVar,                      A_E, ORDN, num, num, ___)             \
+  V(LoadContextVar_Wide,                 A_E, WIDE, num, num, ___)             \
   V(Unused04,                              0, RESV, ___, ___, ___)             \
   V(Unused05,                              0, RESV, ___, ___, ___)             \
-  V(StoreContextVar,                     A_E, ORDN, num, ___, ___)             \
-  V(StoreContextVar_Wide,                A_E, WIDE, num, ___, ___)             \
+  V(StoreContextVar,                     A_E, ORDN, num, num, ___)             \
+  V(StoreContextVar_Wide,                A_E, WIDE, num, num, ___)             \
   V(PushConstant,                          D, ORDN, lit, ___, ___)             \
   V(PushConstant_Wide,                     D, WIDE, lit, ___, ___)             \
   V(Unused06,                              0, RESV, ___, ___, ___)             \
@@ -745,11 +745,11 @@
   // Magic value of bytecode files.
   static const intptr_t kMagicValue = 0x44424332;  // 'DBC2'
   // Minimum bytecode format version supported by VM.
-  static const intptr_t kMinSupportedBytecodeFormatVersion = 3;
+  static const intptr_t kMinSupportedBytecodeFormatVersion = 7;
   // Maximum bytecode format version supported by VM.
   // The range of supported versions should include version produced by bytecode
   // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
-  static const intptr_t kMaxSupportedBytecodeFormatVersion = 10;
+  static const intptr_t kMaxSupportedBytecodeFormatVersion = 12;
 
   enum Opcode {
 #define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name,
@@ -777,12 +777,6 @@
  private:
   static const intptr_t kWideModifier = 1;
 
-  static_assert(kMinSupportedBytecodeFormatVersion < 7,
-                "Cleanup support for old bytecode format versions");
-  DART_FORCE_INLINE static bool IsOld(const KBCInstr* instr) {
-    return DecodeOpcode(instr) < kTrap;
-  }
-
   // Should be used only on instructions with wide variants.
   DART_FORCE_INLINE static bool IsWide(const KBCInstr* instr) {
     return ((DecodeOpcode(instr) & kWideModifier) != 0);
@@ -796,9 +790,7 @@
   DART_FORCE_INLINE static uint8_t DecodeC(const KBCInstr* bc) { return bc[3]; }
 
   DART_FORCE_INLINE static uint32_t DecodeD(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return static_cast<uint32_t>(bc[1]) |
              (static_cast<uint32_t>(bc[2]) << 8) |
              (static_cast<uint32_t>(bc[3]) << 16) |
@@ -809,10 +801,7 @@
   }
 
   DART_FORCE_INLINE static int32_t DecodeX(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
-                                  (static_cast<uint16_t>(bc[3]) << 8));
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return static_cast<int32_t>(static_cast<uint32_t>(bc[1]) |
                                   (static_cast<uint32_t>(bc[2]) << 8) |
                                   (static_cast<uint32_t>(bc[3]) << 16) |
@@ -823,12 +812,7 @@
   }
 
   DART_FORCE_INLINE static int32_t DecodeT(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
-                                  (static_cast<uint32_t>(bc[2]) << 16) |
-                                  (static_cast<uint32_t>(bc[3]) << 24)) >>
-             (8 - 2);
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return static_cast<int32_t>((static_cast<uint32_t>(bc[1]) << 8) |
                                   (static_cast<uint32_t>(bc[2]) << 16) |
                                   (static_cast<uint32_t>(bc[3]) << 24)) >>
@@ -839,9 +823,7 @@
   }
 
   DART_FORCE_INLINE static uint32_t DecodeE(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return static_cast<uint16_t>(bc[2]) | (static_cast<uint16_t>(bc[3]) << 8);
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return static_cast<uint32_t>(bc[2]) |
              (static_cast<uint32_t>(bc[3]) << 8) |
              (static_cast<uint32_t>(bc[4]) << 16) |
@@ -852,10 +834,7 @@
   }
 
   DART_FORCE_INLINE static int32_t DecodeY(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return static_cast<int16_t>(static_cast<uint16_t>(bc[2]) |
-                                  (static_cast<uint16_t>(bc[3]) << 8));
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return static_cast<int32_t>(static_cast<uint32_t>(bc[2]) |
                                   (static_cast<uint32_t>(bc[3]) << 8) |
                                   (static_cast<uint32_t>(bc[4]) << 16) |
@@ -866,9 +845,7 @@
   }
 
   DART_FORCE_INLINE static uint8_t DecodeF(const KBCInstr* bc) {
-    if (IsOld(bc)) {
-      return bc[1];
-    } else if (IsWide(bc)) {
+    if (IsWide(bc)) {
       return bc[5];
     } else {
       return bc[2];
@@ -885,15 +862,6 @@
 
   DART_FORCE_INLINE static bool IsJumpOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kJump_Old:
-      case KernelBytecode::kJumpIfNoAsserts_Old:
-      case KernelBytecode::kJumpIfNotZeroTypeArgs_Old:
-      case KernelBytecode::kJumpIfEqStrict_Old:
-      case KernelBytecode::kJumpIfNeStrict_Old:
-      case KernelBytecode::kJumpIfTrue_Old:
-      case KernelBytecode::kJumpIfFalse_Old:
-      case KernelBytecode::kJumpIfNull_Old:
-      case KernelBytecode::kJumpIfNotNull_Old:
       case KernelBytecode::kJump:
       case KernelBytecode::kJump_Wide:
       case KernelBytecode::kJumpIfNoAsserts:
@@ -923,7 +891,6 @@
     switch (DecodeOpcode(instr)) {
       case KernelBytecode::kLoadConstant:
       case KernelBytecode::kLoadConstant_Wide:
-      case KernelBytecode::kLoadConstant_Old:
         return true;
       default:
         return false;
@@ -931,9 +898,23 @@
   }
 
   DART_FORCE_INLINE static bool IsCheckStackOpcode(const KBCInstr* instr) {
+    return DecodeOpcode(instr) == KernelBytecode::kCheckStack;
+  }
+
+  DART_FORCE_INLINE static bool IsEntryOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kCheckStack:
-      case KernelBytecode::kCheckStack_Old:
+      case KernelBytecode::kEntry:
+      case KernelBytecode::kEntry_Wide:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  DART_FORCE_INLINE static bool IsEntryFixedOpcode(const KBCInstr* instr) {
+    switch (DecodeOpcode(instr)) {
+      case KernelBytecode::kEntryFixed:
+      case KernelBytecode::kEntryFixed_Wide:
         return true;
       default:
         return false;
@@ -941,20 +922,13 @@
   }
 
   DART_FORCE_INLINE static bool IsEntryOptionalOpcode(const KBCInstr* instr) {
-    switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kEntryOptional:
-      case KernelBytecode::kEntryOptional_Old:
-        return true;
-      default:
-        return false;
-    }
+    return DecodeOpcode(instr) == KernelBytecode::kEntryOptional;
   }
 
   DART_FORCE_INLINE static bool IsFrameOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
       case KernelBytecode::kFrame:
       case KernelBytecode::kFrame_Wide:
-      case KernelBytecode::kFrame_Old:
         return true;
       default:
         return false;
@@ -962,33 +936,13 @@
   }
 
   DART_FORCE_INLINE static bool IsSetFrameOpcode(const KBCInstr* instr) {
-    switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kSetFrame:
-      case KernelBytecode::kSetFrame_Old:
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  DART_FORCE_INLINE static bool IsCallOpcode_Old(const KBCInstr* instr) {
-    switch (DecodeOpcode(instr)) {
-      case KernelBytecode::kDirectCall_Old:
-      case KernelBytecode::kInterfaceCall_Old:
-      case KernelBytecode::kUncheckedInterfaceCall_Old:
-      case KernelBytecode::kDynamicCall_Old:
-        return true;
-
-      default:
-        return false;
-    }
+    return DecodeOpcode(instr) == KernelBytecode::kSetFrame;
   }
 
   DART_FORCE_INLINE static bool IsNativeCallOpcode(const KBCInstr* instr) {
     switch (DecodeOpcode(instr)) {
       case KernelBytecode::kNativeCall:
       case KernelBytecode::kNativeCall_Wide:
-      case KernelBytecode::kNativeCall_Old:
         return true;
       default:
         return false;
@@ -1026,19 +980,6 @@
 
   static const uint8_t kNativeCallToGrowableListArgc = 2;
 
-  DART_FORCE_INLINE static uint8_t DecodeArgc_Old(const KBCInstr* ret_addr) {
-    const intptr_t kOldInstructionSize = 4;
-    const KBCInstr* call = ret_addr - kOldInstructionSize;
-    ASSERT(IsOld(call));
-    if (DecodeOpcode(call) == KernelBytecode::kNativeCall_Old) {
-      // The only NativeCall redirecting to a bytecode function is the call
-      // to new _GrowableList<E>(0).
-      return kNativeCallToGrowableListArgc;
-    }
-    ASSERT(IsCallOpcode_Old(call));
-    return DecodeA(call);
-  }
-
   // Returns a fake return address which points after the 2-argument
   // bytecode call, followed by ReturnTOS instructions.
   static const KBCInstr* GetNativeCallToGrowableListReturnTrampoline();
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 4910847..53d63d0 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -15,7 +15,7 @@
 #include "vm/object.h"
 #include "vm/simulator.h"
 
-#if !defined(USING_SIMULATOR)
+#if !defined(TARGET_HOST_MISMATCH)
 #include <sys/syscall.h> /* NOLINT */
 #include <unistd.h>      /* NOLINT */
 #endif
@@ -81,7 +81,7 @@
             "Use integer division instruction if supported");
 #endif
 
-#if defined(USING_SIMULATOR)
+#if defined(TARGET_HOST_MISMATCH)
 #if defined(TARGET_ARCH_ARM_5TE) || defined(TARGET_OS_ANDROID) \
     || defined(TARGET_OS_IOS)
 DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the hardfp ABI.");
@@ -96,7 +96,7 @@
   UNREACHABLE();
 #endif
 
-#if !defined(USING_SIMULATOR) && !HOST_OS_IOS
+#if !defined(TARGET_HOST_MISMATCH) && HOST_ARCH_ARM && !HOST_OS_IOS
   // Nothing to do. Flushing no instructions.
   if (size == 0) {
     return;
@@ -120,9 +120,9 @@
 
 const char* CPU::Id() {
   return
-#if defined(USING_SIMULATOR)
+#if defined(TARGET_HOST_MISMATCH)
       "sim"
-#endif  // defined(USING_SIMULATOR)
+#endif  // defined(TARGET_HOST_MISMATCH)
       "arm";
 }
 
@@ -137,7 +137,7 @@
 bool HostCPUFeatures::initialized_ = false;
 #endif
 
-#if !defined(USING_SIMULATOR)
+#if !defined(TARGET_HOST_MISMATCH)
 #if HOST_OS_IOS
 void HostCPUFeatures::Init() {
   // TODO(24743): Actually check the CPU features and fail if we're missing
@@ -292,7 +292,7 @@
   hardware_ = NULL;
   CpuInfo::Cleanup();
 }
-#endif  // !defined(USING_SIMULATOR)
+#endif  // !defined(TARGET_HOST_MISMATCH)
 
 }  // namespace dart
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index ce05348..e43381d 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -87,6 +87,7 @@
 };
 
 static void CheckOffsets() {
+#if !defined(IS_SIMARM_X64)
   // These offsets are embedded in precompiled instructions. We need the
   // compiler and the runtime to agree.
   bool ok = true;
@@ -124,6 +125,7 @@
 #undef CHECK_RANGE
 #undef CHECK_CONSTANT
 #undef CHECK_OFFSET
+#endif  // !defined(IS_SIMARM_X64)
 }
 
 char* Dart::Init(const uint8_t* vm_isolate_snapshot,
@@ -138,7 +140,8 @@
                  Dart_FileCloseCallback file_close,
                  Dart_EntropySource entropy_source,
                  Dart_GetVMServiceAssetsArchive get_service_assets,
-                 bool start_kernel_isolate) {
+                 bool start_kernel_isolate,
+                 Dart_CodeObserver* observer) {
   CheckOffsets();
   // TODO(iposva): Fix race condition here.
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
@@ -192,6 +195,7 @@
   set_entropy_source_callback(entropy_source);
   OS::Init();
   NOT_IN_PRODUCT(CodeObservers::Init());
+  NOT_IN_PRODUCT(CodeObservers::RegisterExternal(observer));
   start_time_micros_ = OS::GetCurrentMonotonicMicros();
   VirtualMemory::Init();
   OSThread::Init();
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index aba4a28..64d10f9 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -38,7 +38,8 @@
                     Dart_FileCloseCallback file_close,
                     Dart_EntropySource entropy_source,
                     Dart_GetVMServiceAssetsArchive get_service_assets,
-                    bool start_kernel_isolate);
+                    bool start_kernel_isolate,
+                    Dart_CodeObserver* observer);
 
   // Returns null if cleanup succeeds, otherwise returns an error message
   // (caller owns error message and has to free it).
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index ee31194..35306a3 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5,6 +5,8 @@
 #include "include/dart_api.h"
 #include "include/dart_native_api.h"
 
+#include <memory>
+
 #include "lib/stacktrace.h"
 #include "platform/assert.h"
 #include "vm/class_finalizer.h"
@@ -1009,7 +1011,7 @@
                     params->thread_exit, params->file_open, params->file_read,
                     params->file_write, params->file_close,
                     params->entropy_source, params->get_service_assets,
-                    params->start_kernel_isolate);
+                    params->start_kernel_isolate, params->code_observer);
 }
 
 DART_EXPORT char* Dart_Cleanup() {
@@ -5042,13 +5044,13 @@
   BumpAllocateScope bump_allocate_scope(T);
 
   const char* error = nullptr;
-  kernel::Program* program =
+  std::unique_ptr<kernel::Program> program =
       kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
-  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program);
-  delete program;
+  const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
+  program.reset();
 
   if (tmp.IsError()) {
     return Api::NewHandle(T, tmp.raw());
@@ -5104,6 +5106,7 @@
     return Api::NewError("Class '%s' not found in library '%s'.",
                          cls_name.ToCString(), lib_name.ToCString());
   }
+  cls.EnsureDeclarationLoaded();
   CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
   return Api::NewHandle(T, cls.RareType());
 }
@@ -5133,6 +5136,7 @@
     return Api::NewError("Type '%s' not found in library '%s'.",
                          name_str.ToCString(), lib_name.ToCString());
   }
+  cls.EnsureDeclarationLoaded();
   CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
   if (cls.NumTypeArguments() == 0) {
     if (number_of_type_arguments != 0) {
@@ -5288,14 +5292,14 @@
   BumpAllocateScope bump_allocate_scope(T);
 
   const char* error = nullptr;
-  kernel::Program* program =
+  std::unique_ptr<kernel::Program> program =
       kernel::Program::ReadFromBuffer(buffer, buffer_size, &error);
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
   const Object& result =
-      kernel::KernelLoader::LoadEntireProgram(program, false);
-  delete program;
+      kernel::KernelLoader::LoadEntireProgram(program.get(), false);
+  program.reset();
 
   return Api::NewHandle(T, result.raw());
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index ca74fa7..2d8ad35 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -300,8 +300,9 @@
 #if defined(TARGET_ARCH_DBC) && !defined(ARCH_IS_64_BIT)
     // TODO(36809): Support SimDBC32.
     return false;
-#elif defined(TARGET_ARCH_DBC) && !defined(HOST_ARCH_X64)
-    // TODO(35773): Support ia32, arm64, and arm.
+#elif defined(TARGET_ARCH_DBC) &&                                              \
+    !(defined(HOST_ARCH_X64) || defined(HOST_ARCH_ARM64))
+    // TODO(36809): Support ia32 and arm.
     return false;
 #elif defined(TARGET_ARCH_DBC) && defined(HOST_ARCH_X64) &&                    \
     defined(HOST_OS_WINDOWS)
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 4841f0d..2035e4a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -57,6 +57,37 @@
   EXPECT(Dart_Cleanup() == NULL);
 }
 
+UNIT_TEST_CASE(DartAPI_DartInitializeCallsCodeObserver) {
+  EXPECT(Dart_SetVMFlags(TesterState::argc, TesterState::argv) == NULL);
+  Dart_InitializeParams params;
+  memset(&params, 0, sizeof(Dart_InitializeParams));
+  params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
+  params.vm_snapshot_data = TesterState::vm_snapshot_data;
+  params.create = TesterState::create_callback;
+  params.shutdown = TesterState::shutdown_callback;
+  params.cleanup = TesterState::cleanup_callback;
+  params.start_kernel_isolate = true;
+
+  bool was_called = false;
+  Dart_CodeObserver code_observer;
+  code_observer.data = &was_called;
+  code_observer.on_new_code = [](Dart_CodeObserver* observer, const char* name,
+                                 uintptr_t base, uintptr_t size) {
+    *static_cast<bool*>(observer->data) = true;
+  };
+  params.code_observer = &code_observer;
+
+  // Reinitialize and ensure we can execute Dart code.
+  EXPECT(Dart_Initialize(&params) == NULL);
+
+  // Wait for 5 seconds to let the kernel service load the snapshot,
+  // which should trigger calls to the code observer.
+  OS::Sleep(5);
+
+  EXPECT(was_called);
+  EXPECT(Dart_Cleanup() == NULL);
+}
+
 TEST_CASE(DartAPI_ErrorHandleBasics) {
   const char* kScriptChars =
       "void testMain() {\n"
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 43f2d64..13bd393 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -391,6 +391,21 @@
     current_ += len;
   }
 
+  void WriteTargetWord(uword value) {
+#if defined(IS_SIMARM_X64)
+    RELEASE_ASSERT(Utils::IsInt(32, static_cast<word>(value)));
+    const intptr_t len = sizeof(uint32_t);
+    if ((end_ - current_) < len) {
+      Resize(len);
+    }
+    ASSERT((end_ - current_) >= len);
+    *reinterpret_cast<uint32_t*>(current_) = static_cast<uint32_t>(value);
+    current_ += len;
+#else   // defined(IS_SIMARM_X64)
+    WriteWord(value);
+#endif  // defined(IS_SIMARM_X64)
+  }
+
   void Print(const char* format, ...) {
     va_list args;
     va_start(args, format);
@@ -430,6 +445,17 @@
     WriteByte(static_cast<uint8_t>(v + kEndByteMarker));
   }
 
+  template <typename T>
+  void WriteFixed(T value) {
+    const intptr_t len = sizeof(T);
+    if ((end_ - current_) < len) {
+      Resize(len);
+    }
+    ASSERT((end_ - current_) >= len);
+    *reinterpret_cast<T*>(current_) = static_cast<T>(value);
+    current_ += len;
+  }
+
  private:
   DART_FORCE_INLINE void WriteByte(uint8_t value) {
     if (current_ >= end_) {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index af1ca5c..5a8709b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -304,6 +304,8 @@
   }
 #endif
   if (bytecode_.IsNull()) {
+    // Force-optimize functions should not be debuggable.
+    ASSERT(!function_.ForceOptimize());
     function_.EnsureHasCompiledUnoptimizedCode();
     code_ = function_.unoptimized_code();
   }
@@ -732,14 +734,17 @@
         PrintDescriptorsError("Missing local variables info");
       }
       intptr_t pc_offset = pc_ - bytecode.PayloadStart();
+      // Look for innermost scope, i.e. with the highest context level.
+      // Since scopes are ordered by StartPC(), the last scope which includes
+      // pc_offset will be the innermost one.
       kernel::BytecodeLocalVariablesIterator local_vars(zone, bytecode);
       while (local_vars.MoveNext()) {
         if (local_vars.Kind() ==
             kernel::BytecodeLocalVariablesIterator::kScope) {
           if (local_vars.StartPC() <= pc_offset &&
               pc_offset < local_vars.EndPC()) {
+            ASSERT(context_level_ <= local_vars.ContextLevel());
             context_level_ = local_vars.ContextLevel();
-            break;
           }
         }
       }
@@ -747,7 +752,6 @@
         // Obtain the context level from the parent function.
         // TODO(alexmarkov): Define scope which includes the whole closure body.
         Function& parent = Function::Handle(zone, function().parent_function());
-        intptr_t depth = 1;
         do {
           bytecode = parent.bytecode();
           kernel::BytecodeLocalVariablesIterator local_vars(zone, bytecode);
@@ -756,14 +760,13 @@
                 kernel::BytecodeLocalVariablesIterator::kScope) {
               if (local_vars.StartTokenPos() <= TokenPos() &&
                   TokenPos() <= local_vars.EndTokenPos()) {
-                context_level_ = local_vars.ContextLevel() + depth;
-                break;
+                ASSERT(context_level_ <= local_vars.ContextLevel());
+                context_level_ = local_vars.ContextLevel();
               }
             }
           }
           if (context_level_ >= 0) break;
           parent = parent.parent_function();
-          depth++;
         } while (!parent.IsNull());
       }
       if (context_level_ < 0) {
@@ -946,23 +949,7 @@
   return false;
 }
 
-void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
-  // Attempt to determine the token pos and try index from the async closure.
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  const Script& script = Script::Handle(zone, function().script());
-
-  ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
-  // This should only be called on frames that aren't active on the stack.
-  ASSERT(fp() == 0);
-
-  ASSERT(script.kind() == RawScript::kKernelTag);
-  const Array& await_to_token_map =
-      Array::Handle(zone, script.yield_positions());
-  if (await_to_token_map.IsNull()) {
-    // No mapping.
-    return;
-  }
+intptr_t ActivationFrame::GetAwaitJumpVariable() {
   GetVarDescriptors();
   intptr_t var_desc_len = var_descriptors_.Length();
   intptr_t await_jump_var = -1;
@@ -978,6 +965,59 @@
       await_jump_var = Smi::Cast(await_jump_index).Value();
     }
   }
+  return await_jump_var;
+}
+
+void ActivationFrame::ExtractTokenPositionFromAsyncClosure() {
+  // Attempt to determine the token pos and try index from the async closure.
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  const Script& script = Script::Handle(zone, function().script());
+
+  ASSERT(function_.IsAsyncGenClosure() || function_.IsAsyncClosure());
+  // This should only be called on frames that aren't active on the stack.
+  ASSERT(fp() == 0);
+
+  if (function_.is_declared_in_bytecode()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    const auto& bytecode = Bytecode::Handle(zone, function_.bytecode());
+    if (!bytecode.HasSourcePositions()) {
+      return;
+    }
+    const intptr_t await_jump_var = GetAwaitJumpVariable();
+    if (await_jump_var < 0) {
+      return;
+    }
+    // Yield points are counted from 1 (0 is reserved for normal entry).
+    intptr_t yield_point_index = 1;
+    kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
+    while (iter.MoveNext()) {
+      if (iter.IsYieldPoint()) {
+        if (yield_point_index == await_jump_var) {
+          token_pos_ = iter.TokenPos();
+          token_pos_initialized_ = true;
+          try_index_ = bytecode.GetTryIndexAtPc(bytecode.PayloadStart() +
+                                                iter.PcOffset());
+          return;
+        }
+        ++yield_point_index;
+      }
+    }
+    return;
+#else
+    UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  }
+
+  ASSERT(!IsInterpreted());
+  ASSERT(script.kind() == RawScript::kKernelTag);
+  const Array& await_to_token_map =
+      Array::Handle(zone, script.yield_positions());
+  if (await_to_token_map.IsNull()) {
+    // No mapping.
+    return;
+  }
+  const intptr_t await_jump_var = GetAwaitJumpVariable();
   if (await_jump_var < 0) {
     return;
   }
@@ -1009,29 +1049,6 @@
   ASSERT(token_pos.IsSmi());
   token_pos_ = TokenPosition(Smi::Cast(token_pos).Value());
   token_pos_initialized_ = true;
-  if (IsInterpreted()) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    // In order to determine the try index, we need to map the token position
-    // to a pc offset, and then a pc offset to the try index.
-    // TODO(regis): Should we set the token position fields in pc descriptors?
-    uword pc_offset = kUwordMax;
-    kernel::BytecodeSourcePositionsIterator iter(zone, bytecode());
-    while (iter.MoveNext()) {
-      // PcOffsets are monotonic in source positions, so we get the lowest one.
-      if (iter.TokenPos() == token_pos_) {
-        pc_offset = iter.PcOffset();
-        break;
-      }
-    }
-    if (pc_offset < kUwordMax) {
-      try_index_ =
-          bytecode().GetTryIndexAtPc(bytecode().PayloadStart() + pc_offset);
-    }
-#else
-    UNREACHABLE();
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-    return;
-  }
   GetPcDescriptors();
   PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
   while (iter.MoveNext()) {
@@ -1985,6 +2002,12 @@
         for (intptr_t pos = 0; pos < num_functions; pos++) {
           function ^= functions.At(pos);
           ASSERT(!function.IsNull());
+          // Force-optimized functions don't have unoptimized code and can't
+          // deoptimize. Their optimized codes are still valid.
+          if (function.ForceOptimize()) {
+            ASSERT(!function.HasImplicitClosureFunction());
+            continue;
+          }
           if (function.HasOptimizedCode()) {
             function.SwitchToUnoptimizedCode();
           }
@@ -2316,6 +2339,7 @@
                               Thread::Current(),
                               StackFrameIterator::kNoCrossThreadIteration);
 
+  Object& code_object = Object::Handle(zone);
   Code& code = Code::Handle(zone);
   Bytecode& bytecode = Bytecode::Handle(zone);
   Smi& offset = Smi::Handle(zone);
@@ -2513,17 +2537,24 @@
         // the readability of the trace.
         i++;
       } else {
-        code = Code::RawCast(async_stack_trace.CodeAtFrame(i));
+        code_object = async_stack_trace.CodeAtFrame(i);
         offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
-        uword pc = code.PayloadStart() + offset.Value();
-        if (code.is_optimized()) {
-          for (InlinedFunctionsIterator it(code, pc); !it.Done();
-               it.Advance()) {
-            inlined_code = it.code();
-            stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
-          }
+        if (code_object.IsBytecode()) {
+          bytecode ^= code_object.raw();
+          uword pc = bytecode.PayloadStart() + offset.Value();
+          stack_trace->AddAsyncCausalFrame(pc, bytecode);
         } else {
-          stack_trace->AddAsyncCausalFrame(pc, code);
+          code ^= code_object.raw();
+          uword pc = code.PayloadStart() + offset.Value();
+          if (code.is_optimized()) {
+            for (InlinedFunctionsIterator it(code, pc); !it.Done();
+                 it.Advance()) {
+              inlined_code = it.code();
+              stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
+            }
+          } else {
+            stack_trace->AddAsyncCausalFrame(pc, code);
+          }
         }
       }
     }
@@ -3523,7 +3554,11 @@
 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
                                            bool single_shot) {
   ASSERT(!target_function.IsNull());
-  if (!target_function.is_debuggable()) {
+  // AsyncFunction is marked not debuggable. When target_function is an async
+  // function, it is actually referring the inner async_op. Allow the
+  // breakpoint to be set, it will get resolved correctly when inner async_op
+  // gets compiled.
+  if (!target_function.is_debuggable() && !target_function.IsAsyncFunction()) {
     return NULL;
   }
   const Script& script = Script::Handle(target_function.script());
@@ -4154,6 +4189,23 @@
   if (!closure_or_null.IsNull()) {
     ASSERT(closure_or_null.IsInstance());
     ASSERT(Instance::Cast(closure_or_null).IsClosure());
+    if (top_frame->function().is_declared_in_bytecode()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      const auto& bytecode =
+          Bytecode::Handle(zone, top_frame->function().bytecode());
+      const TokenPosition token_pos = top_frame->TokenPos();
+      kernel::BytecodeSourcePositionsIterator iter(zone, bytecode);
+      while (iter.MoveNext()) {
+        if (iter.IsYieldPoint() && (iter.TokenPos() == token_pos)) {
+          return true;
+        }
+      }
+      return false;
+#else
+      UNREACHABLE();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    }
+    ASSERT(!top_frame->IsInterpreted());
     const Script& script = Script::Handle(zone, top_frame->SourceScript());
     ASSERT(script.kind() == RawScript::kKernelTag);
     // Are we at a yield point (previous await)?
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 39a2c89..09e6c83 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -388,6 +388,7 @@
   RawObject* GetAsyncStreamControllerStream();
   RawObject* GetAsyncCompleterAwaiter(const Object& completer);
   RawObject* GetAsyncCompleter();
+  intptr_t GetAwaitJumpVariable();
   void ExtractTokenPositionFromAsyncClosure();
 
   bool IsAsyncMachinery() const;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 1a71bf6..b28c397 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -1165,6 +1165,7 @@
         deopt_instr =
             new (zone()) DeoptUint32Instr(ToCpuRegisterSource(source_loc));
         break;
+      case kUnboxedFloat:
       case kUnboxedDouble:
         deopt_instr = new (zone()) DeoptDoubleInstr(
             ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 2852a43..eb8434a 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -32,6 +32,12 @@
 constexpr bool kDartPrecompiledRuntime = false;
 #endif
 
+#if defined(DART_USE_BYTECODE)
+constexpr bool kDartUseBytecode = true;
+#else
+constexpr bool kDartUseBytecode = false;
+#endif
+
 // List of all flags in the VM.
 // Flags can be one of three categories:
 // * P roduct flags: Can be set in any of the deployment modes, including in
@@ -191,7 +197,7 @@
   D(trace_zones, bool, false, "Traces allocation sizes in the zone.")          \
   P(truncating_left_shift, bool, true,                                         \
     "Optimize left shift to truncate if possible")                             \
-  P(use_bytecode_compiler, bool, false, "Compile from bytecode")               \
+  P(use_bytecode_compiler, bool, kDartUseBytecode, "Compile from bytecode")    \
   P(use_compactor, bool, false, "Compact the heap during old-space GC.")       \
   P(use_cha_deopt, bool, true,                                                 \
     "Use class hierarchy analysis even if it can cause deoptimization.")       \
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 1734984c..682ee90 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -96,7 +96,7 @@
 #define SUPPORT_TIMELINE 1
 #endif
 
-#if defined(ARCH_IS_64_BIT)
+#if defined(ARCH_IS_64_BIT) && !defined(IS_SIMARM_X64)
 #define HASH_IN_OBJECT_HEADER 1
 #endif
 
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index fe46279..f216ef0 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -182,9 +182,88 @@
   return offset;
 }
 
+#if defined(IS_SIMARM_X64)
+static intptr_t StackMapSizeInSnapshot(intptr_t len_in_bits) {
+  const intptr_t len_in_bytes =
+      Utils::RoundUp(len_in_bits, kBitsPerByte) / kBitsPerByte;
+  const intptr_t unrounded_size_in_bytes =
+      3 * compiler::target::kWordSize + len_in_bytes;
+  return Utils::RoundUp(unrounded_size_in_bytes,
+                        compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t StringPayloadSize(intptr_t len, bool isOneByteString) {
+  return len * (isOneByteString ? OneByteString::kBytesPerElement
+                                : TwoByteString::kBytesPerElement);
+}
+
+static intptr_t StringSizeInSnapshot(intptr_t len, bool isOneByteString) {
+  const intptr_t unrounded_size_in_bytes =
+      (String::kSizeofRawString / 2) + StringPayloadSize(len, isOneByteString);
+  return Utils::RoundUp(unrounded_size_in_bytes,
+                        compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t CodeSourceMapSizeInSnapshot(intptr_t len) {
+  const intptr_t unrounded_size_in_bytes =
+      2 * compiler::target::kWordSize + len;
+  return Utils::RoundUp(unrounded_size_in_bytes,
+                        compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static intptr_t PcDescriptorsSizeInSnapshot(intptr_t len) {
+  const intptr_t unrounded_size_in_bytes =
+      2 * compiler::target::kWordSize + len;
+  return Utils::RoundUp(unrounded_size_in_bytes,
+                        compiler::target::ObjectAlignment::kObjectAlignment);
+}
+
+static constexpr intptr_t kSimarmX64InstructionsAlignment =
+    2 * compiler::target::ObjectAlignment::kObjectAlignment;
+static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
+  const intptr_t header_size = Utils::RoundUp(3 * compiler::target::kWordSize,
+                                              kSimarmX64InstructionsAlignment);
+  return header_size + Utils::RoundUp(len, kSimarmX64InstructionsAlignment);
+}
+
+intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
+  const classid_t cid = raw_object->GetClassId();
+
+  switch (cid) {
+    case kStackMapCid: {
+      RawStackMap* raw_map = static_cast<RawStackMap*>(raw_object);
+      return StackMapSizeInSnapshot(raw_map->ptr()->length_);
+    }
+    case kOneByteStringCid:
+    case kTwoByteStringCid: {
+      RawString* raw_str = static_cast<RawString*>(raw_object);
+      return StringSizeInSnapshot(Smi::Value(raw_str->ptr()->length_),
+                                  cid == kOneByteStringCid);
+    }
+    case kCodeSourceMapCid: {
+      RawCodeSourceMap* raw_map = static_cast<RawCodeSourceMap*>(raw_object);
+      return CodeSourceMapSizeInSnapshot(raw_map->ptr()->length_);
+    }
+    case kPcDescriptorsCid: {
+      RawPcDescriptors* raw_desc = static_cast<RawPcDescriptors*>(raw_object);
+      return PcDescriptorsSizeInSnapshot(raw_desc->ptr()->length_);
+    }
+    case kInstructionsCid: {
+      RawInstructions* raw_insns = static_cast<RawInstructions*>(raw_object);
+      return InstructionsSizeInSnapshot(Instructions::Size(raw_insns));
+    }
+    default: {
+      const Class& clazz = Class::Handle(Object::Handle(raw_object).clazz());
+      FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
+      return 0;
+    }
+  }
+}
+#else   // defined(IS_SIMARM_X64)
 intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
   return raw_object->HeapSize();
 }
+#endif  // defined(IS_SIMARM_X64)
 
 bool ImageWriter::GetSharedDataOffsetFor(RawObject* raw_object,
                                          uint32_t* offset) {
@@ -348,12 +427,76 @@
 #if defined(HASH_IN_OBJECT_HEADER)
     marked_tags |= static_cast<uword>(obj.raw()->ptr()->hash_) << 32;
 #endif
+
+#if defined(IS_SIMARM_X64)
+    if (obj.IsStackMap()) {
+      const StackMap& map = StackMap::Cast(obj);
+
+      // Header layout is the same between 32-bit and 64-bit architecture, but
+      // we need to recalcuate the size in words.
+      const intptr_t len_in_bits = map.Length();
+      const intptr_t len_in_bytes =
+          Utils::RoundUp(len_in_bits, kBitsPerByte) / kBitsPerByte;
+      const intptr_t size_in_bytes = StackMapSizeInSnapshot(len_in_bits);
+      marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+      stream->WriteTargetWord(marked_tags);
+      stream->WriteFixed<uint32_t>(map.PcOffset());
+      stream->WriteFixed<uint16_t>(map.Length());
+      stream->WriteFixed<uint16_t>(map.SlowPathBitCount());
+      stream->WriteBytes(map.raw()->ptr()->data(), len_in_bytes);
+      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+
+    } else if (obj.IsString()) {
+      const String& str = String::Cast(obj);
+      RELEASE_ASSERT(String::GetCachedHash(str.raw()) != 0);
+      RELEASE_ASSERT(str.IsOneByteString() || str.IsTwoByteString());
+      const intptr_t size_in_bytes =
+          StringSizeInSnapshot(str.Length(), str.IsOneByteString());
+      marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+      stream->WriteTargetWord(marked_tags);
+      stream->WriteTargetWord(
+          reinterpret_cast<uword>(str.raw()->ptr()->length_));
+      stream->WriteTargetWord(reinterpret_cast<uword>(str.raw()->ptr()->hash_));
+      stream->WriteBytes(
+          reinterpret_cast<const void*>(start + String::kSizeofRawString),
+          StringPayloadSize(str.Length(), str.IsOneByteString()));
+      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+    } else if (obj.IsCodeSourceMap()) {
+      const CodeSourceMap& map = CodeSourceMap::Cast(obj);
+
+      const intptr_t size_in_bytes = CodeSourceMapSizeInSnapshot(map.Length());
+      marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+      stream->WriteTargetWord(marked_tags);
+      stream->WriteTargetWord(map.Length());
+      stream->WriteBytes(map.Data(), map.Length());
+      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+    } else if (obj.IsPcDescriptors()) {
+      const PcDescriptors& desc = PcDescriptors::Cast(obj);
+
+      const intptr_t size_in_bytes = PcDescriptorsSizeInSnapshot(desc.Length());
+      marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+
+      stream->WriteTargetWord(marked_tags);
+      stream->WriteTargetWord(desc.Length());
+      stream->WriteBytes(desc.raw()->ptr()->data(), desc.Length());
+      stream->Align(compiler::target::ObjectAlignment::kObjectAlignment);
+    } else {
+      const Class& clazz = Class::Handle(obj.clazz());
+      FATAL1("Unsupported class %s in rodata section.\n", clazz.ToCString());
+    }
+    USE(start);
+    USE(end);
+#else   // defined(IS_SIMARM_X64)
     stream->WriteWord(marked_tags);
     start += sizeof(uword);
     for (uword* cursor = reinterpret_cast<uword*>(start);
          cursor < reinterpret_cast<uword*>(end); cursor++) {
       stream->WriteWord(*cursor);
     }
+#endif  // defined(IS_SIMARM_X64)
   }
 }
 
@@ -774,10 +917,28 @@
     marked_tags |= static_cast<uword>(insns.raw_ptr()->hash_) << 32;
 #endif
 
+#if defined(IS_SIMARM_X64)
+    const intptr_t start_offset = instructions_blob_stream_.bytes_written();
+    const intptr_t size_in_bytes = InstructionsSizeInSnapshot(insns.Size());
+    marked_tags = RawObject::SizeTag::update(size_in_bytes * 2, marked_tags);
+    instructions_blob_stream_.WriteTargetWord(marked_tags);
+    instructions_blob_stream_.WriteFixed<uint32_t>(
+        insns.raw_ptr()->size_and_flags_);
+    instructions_blob_stream_.WriteFixed<uint32_t>(
+        insns.raw_ptr()->unchecked_entrypoint_pc_offset_);
+    instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
+    instructions_blob_stream_.WriteBytes(
+        reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
+    instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
+    const intptr_t end_offset = instructions_blob_stream_.bytes_written();
+    text_offset += (end_offset - start_offset);
+    USE(end);
+#else   // defined(IS_SIMARM_X64)
     instructions_blob_stream_.WriteWord(marked_tags);
     text_offset += sizeof(uword);
     beginning += sizeof(uword);
     text_offset += WriteByteSequence(beginning, end);
+#endif  // defined(IS_SIMARM_X64)
 
     ASSERT((text_offset - instr_start) ==
            ImageWriter::SizeInSnapshot(insns.raw()));
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index c83e454..b466015 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -256,6 +256,28 @@
   return RawObject::FromAddr(addr);
 }
 
+DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
+                                          intptr_t class_id,
+                                          intptr_t instance_size,
+                                          RawObject** result) {
+  const uword start = thread->top();
+#ifndef PRODUCT
+  ClassTable* table = thread->isolate()->class_table();
+  if (UNLIKELY(table->TraceAllocationFor(class_id))) {
+    return false;
+  }
+#endif
+  if (LIKELY((start + instance_size) < thread->end())) {
+    thread->set_top(start + instance_size);
+#ifndef PRODUCT
+    table->UpdateAllocatedNew(class_id, instance_size);
+#endif
+    *result = InitializeHeader(start, class_id, instance_size);
+    return true;
+  }
+  return false;
+}
+
 void LookupCache::Clear() {
   for (intptr_t i = 0; i < kNumEntries; i++) {
     entries_[i].receiver_cid = kIllegalCid;
@@ -382,9 +404,9 @@
   Thread* thread = Thread::Current();
   Interpreter* interpreter = thread->interpreter();
   if (interpreter == nullptr) {
-    TransitionGeneratedToVM transition(thread);
+    NoSafepointScope no_safepoint;
     interpreter = new Interpreter();
-    Thread::Current()->set_interpreter(interpreter);
+    thread->set_interpreter(interpreter);
   }
   return interpreter;
 }
@@ -910,20 +932,11 @@
 
 #define BYTECODE_ENTRY_LABEL(Name) bc##Name:
 #define BYTECODE_WIDE_ENTRY_LABEL(Name) bc##Name##_Wide:
-#define BYTECODE_OLD_ENTRY_LABEL(Name) bc##Name##_Old:
 #define BYTECODE_IMPL_LABEL(Name) bc##Name##Impl:
 #define GOTO_BYTECODE_IMPL(Name) goto bc##Name##Impl;
 
 // Define entry point that handles bytecode Name with the given operand format.
-#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands##_WITH_OLD(Name)
-
-// TODO(alexmarkov): switch BYTECODE macro to BYTECODE_NEW implementation
-// and replace BYTECODE_NEW with BYTECODE when old instructions are gone.
-// Cleanup BYTECODE_HEADER_*_WITH_OLD macros and drop _WITH_OLD.
-static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-              "Cleanup support for old bytecode format versions");
-
-#define BYTECODE_NEW(Name, Operands) BYTECODE_HEADER_##Operands(Name)
+#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands(Name)
 
 // Helpers to decode common instruction formats. Used in conjunction with
 // BYTECODE() macro.
@@ -932,32 +945,16 @@
   BYTECODE_ENTRY_LABEL(Name)                                                   \
   pc += 1;
 
-#define BYTECODE_HEADER_0_WITH_OLD(Name)                                       \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
-  BYTECODE_HEADER_0(Name)                                                      \
-  BYTECODE_IMPL_LABEL(Name)
-
-#define BYTECODE_HEADER_A_WITH_OLD(Name)                                       \
+#define BYTECODE_HEADER_A(Name)                                                \
   uint32_t rA;                                                                 \
   USE(rA);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rA = pc[1];                                                                  \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_ENTRY_LABEL(Name)                                                   \
   rA = pc[1];                                                                  \
-  pc += 2;                                                                     \
-  BYTECODE_IMPL_LABEL(Name)
+  pc += 2;
 
-#define BYTECODE_HEADER_D_WITH_OLD(Name)                                       \
+#define BYTECODE_HEADER_D(Name)                                                \
   uint32_t rD;                                                                 \
   USE(rD);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) |    \
        (static_cast<uint32_t>(pc[3]) << 16) |                                  \
@@ -969,14 +966,9 @@
   pc += 2;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_X_WITH_OLD(Name)                                       \
+#define BYTECODE_HEADER_X(Name)                                                \
   int32_t rX;                                                                  \
   USE(rX);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rX = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) |                     \
-                            (static_cast<uint16_t>(pc[3]) << 8));              \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rX = static_cast<int32_t>(static_cast<uint32_t>(pc[1]) |                     \
                             (static_cast<uint32_t>(pc[2]) << 8) |              \
@@ -989,16 +981,9 @@
   pc += 2;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_T_WITH_OLD(Name)                                       \
+#define BYTECODE_HEADER_T(Name)                                                \
   const KBCInstr* rT;                                                          \
   USE(rT);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) |        \
-                                  (static_cast<uint32_t>(pc[2]) << 16) |       \
-                                  (static_cast<uint32_t>(pc[3]) << 24)) >>     \
-             (8 - 2));                                                         \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rT = pc + (static_cast<int32_t>((static_cast<uint32_t>(pc[1]) << 8) |        \
                                   (static_cast<uint32_t>(pc[2]) << 16) |       \
@@ -1011,15 +996,10 @@
   pc += 2;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_A_E_WITH_OLD(Name)                                     \
+#define BYTECODE_HEADER_A_E(Name)                                              \
   uint32_t rA, rE;                                                             \
   USE(rA);                                                                     \
   USE(rE);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rA = pc[1];                                                                  \
-  rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rA = pc[1];                                                                  \
   rE = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8) |    \
@@ -1033,17 +1013,11 @@
   pc += 3;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_A_Y_WITH_OLD(Name)                                     \
+#define BYTECODE_HEADER_A_Y(Name)                                              \
   uint32_t rA;                                                                 \
   int32_t rY;                                                                  \
   USE(rA);                                                                     \
   USE(rY);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rA = pc[1];                                                                  \
-  rY = static_cast<int16_t>(static_cast<uint16_t>(pc[2]) |                     \
-                            (static_cast<uint16_t>(pc[3]) << 8));              \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rA = pc[1];                                                                  \
   rY = static_cast<int32_t>(static_cast<uint32_t>(pc[2]) |                     \
@@ -1058,15 +1032,10 @@
   pc += 3;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_D_F_WITH_OLD(Name)                                     \
+#define BYTECODE_HEADER_D_F(Name)                                              \
   uint32_t rD, rF;                                                             \
   USE(rD);                                                                     \
   USE(rF);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
-  rF = pc[1];                                                                  \
-  rD = static_cast<uint32_t>(pc[2]) | (static_cast<uint32_t>(pc[3]) << 8);     \
-  pc += 4;                                                                     \
-  GOTO_BYTECODE_IMPL(Name);                                                    \
   BYTECODE_WIDE_ENTRY_LABEL(Name)                                              \
   rD = static_cast<uint32_t>(pc[1]) | (static_cast<uint32_t>(pc[2]) << 8) |    \
        (static_cast<uint32_t>(pc[3]) << 16) |                                  \
@@ -1080,12 +1049,11 @@
   pc += 3;                                                                     \
   BYTECODE_IMPL_LABEL(Name)
 
-#define BYTECODE_HEADER_A_B_C_WITH_OLD(Name)                                   \
+#define BYTECODE_HEADER_A_B_C(Name)                                            \
   uint32_t rA, rB, rC;                                                         \
   USE(rA);                                                                     \
   USE(rB);                                                                     \
   USE(rC);                                                                     \
-  BYTECODE_OLD_ENTRY_LABEL(Name)                                               \
   BYTECODE_ENTRY_LABEL(Name)                                                   \
   rA = pc[1];                                                                  \
   rB = pc[2];                                                                  \
@@ -1405,12 +1373,9 @@
                                              RawObject** FP,
                                              RawObject** SP) {
   ASSERT(!Smi::IsValid(value));
-  const intptr_t instance_size = Mint::InstanceSize();
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawMint* result =
-        Mint::RawCast(InitializeHeader(start, kMintCid, instance_size));
+  RawMint* result;
+  if (TryAllocate(thread, kMintCid, Mint::InstanceSize(),
+                  reinterpret_cast<RawObject**>(&result))) {
     result->ptr()->value_ = value;
     SP[0] = result;
     return true;
@@ -1435,12 +1400,9 @@
                                                const KBCInstr* pc,
                                                RawObject** FP,
                                                RawObject** SP) {
-  const intptr_t instance_size = Double::InstanceSize();
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawDouble* result =
-        Double::RawCast(InitializeHeader(start, kDoubleCid, instance_size));
+  RawDouble* result;
+  if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(),
+                  reinterpret_cast<RawObject**>(&result))) {
     result->ptr()->value_ = value;
     SP[0] = result;
     return true;
@@ -1465,12 +1427,9 @@
                                                   const KBCInstr* pc,
                                                   RawObject** FP,
                                                   RawObject** SP) {
-  const intptr_t instance_size = Float32x4::InstanceSize();
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawFloat32x4* result = Float32x4::RawCast(
-        InitializeHeader(start, kFloat32x4Cid, instance_size));
+  RawFloat32x4* result;
+  if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(),
+                  reinterpret_cast<RawObject**>(&result))) {
     value.writeTo(result->ptr()->value_);
     SP[0] = result;
     return true;
@@ -1495,12 +1454,9 @@
                                                   const KBCInstr* pc,
                                                   RawObject** FP,
                                                   RawObject** SP) {
-  const intptr_t instance_size = Float64x2::InstanceSize();
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawFloat64x2* result = Float64x2::RawCast(
-        InitializeHeader(start, kFloat64x2Cid, instance_size));
+  RawFloat64x2* result;
+  if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(),
+                  reinterpret_cast<RawObject**>(&result))) {
     value.writeTo(result->ptr()->value_);
     SP[0] = result;
     return true;
@@ -1529,12 +1485,9 @@
   if (LIKELY(!length_object->IsHeapObject())) {
     const intptr_t length = Smi::Value(Smi::RawCast(length_object));
     if (LIKELY(Array::IsValidLength(length))) {
-      const intptr_t instance_size = Array::InstanceSize(length);
-      const uword start = thread->top();
-      if (LIKELY((start + instance_size) < thread->end())) {
-        thread->set_top(start + instance_size);
-        RawArray* result =
-            Array::RawCast(InitializeHeader(start, kArrayCid, instance_size));
+      RawArray* result;
+      if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length),
+                      reinterpret_cast<RawObject**>(&result))) {
         result->ptr()->type_arguments_ = type_args;
         result->ptr()->length_ = Smi::New(length);
         for (intptr_t i = 0; i < length; i++) {
@@ -1561,19 +1514,15 @@
                                   const KBCInstr* pc,
                                   RawObject** FP,
                                   RawObject** SP) {
-  const intptr_t instance_size = Context::InstanceSize(num_context_variables);
-  ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawContext* result =
-        Context::RawCast(InitializeHeader(start, kContextCid, instance_size));
+  RawContext* result;
+  if (TryAllocate(thread, kContextCid,
+                  Context::InstanceSize(num_context_variables),
+                  reinterpret_cast<RawObject**>(&result))) {
     result->ptr()->num_variables_ = num_context_variables;
     RawObject* null_value = Object::null();
     result->ptr()->parent_ = static_cast<RawContext*>(null_value);
-    for (intptr_t offset = sizeof(RawContext); offset < instance_size;
-         offset += kWordSize) {
-      *reinterpret_cast<RawObject**>(start + offset) = null_value;
+    for (intptr_t i = 0; i < num_context_variables; i++) {
+      result->ptr()->data()[i] = null_value;
     }
     SP[0] = result;
     return true;
@@ -1593,11 +1542,10 @@
                                   RawObject** FP,
                                   RawObject** SP) {
   const intptr_t instance_size = Closure::InstanceSize();
-  const uword start = thread->top();
-  if (LIKELY((start + instance_size) < thread->end())) {
-    thread->set_top(start + instance_size);
-    RawClosure* result =
-        Closure::RawCast(InitializeHeader(start, kClosureCid, instance_size));
+  RawClosure* result;
+  if (TryAllocate(thread, kClosureCid, instance_size,
+                  reinterpret_cast<RawObject**>(&result))) {
+    uword start = RawObject::ToAddr(result);
     RawObject* null_value = Object::null();
     for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
          offset += kWordSize) {
@@ -2112,32 +2060,38 @@
         }
       } break;
       case MethodRecognizer::kGrowableArrayLength: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
-            instance->ptr())[GrowableObjectArray::length_offset() / kWordSize];
+        RawGrowableObjectArray* instance =
+            reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+        SP[0] = instance->ptr()->length_;
       } break;
       case MethodRecognizer::kObjectArrayLength:
       case MethodRecognizer::kImmutableArrayLength: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
-            instance->ptr())[Array::length_offset() / kWordSize];
+        RawArray* instance = reinterpret_cast<RawArray*>(SP[0]);
+        SP[0] = instance->ptr()->length_;
       } break;
       case MethodRecognizer::kTypedListLength:
       case MethodRecognizer::kTypedListViewLength:
       case MethodRecognizer::kByteDataViewLength: {
-        RawInstance* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
-        SP[0] = reinterpret_cast<RawObject**>(
-            instance->ptr())[TypedDataBase::length_offset() / kWordSize];
+        RawTypedDataBase* instance = reinterpret_cast<RawTypedDataBase*>(SP[0]);
+        SP[0] = instance->ptr()->length_;
+      } break;
+      case MethodRecognizer::kByteDataViewOffsetInBytes:
+      case MethodRecognizer::kTypedDataViewOffsetInBytes: {
+        RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+        SP[0] = instance->ptr()->offset_in_bytes_;
+      } break;
+      case MethodRecognizer::kByteDataViewTypedData:
+      case MethodRecognizer::kTypedDataViewTypedData: {
+        RawTypedDataView* instance = reinterpret_cast<RawTypedDataView*>(SP[0]);
+        SP[0] = instance->ptr()->typed_data_;
       } break;
       case MethodRecognizer::kClassIDgetID: {
         SP[0] = InterpreterHelpers::GetClassIdAsSmi(SP[0]);
       } break;
       case MethodRecognizer::kGrowableArrayCapacity: {
-        RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
-        instance = reinterpret_cast<RawInstance**>(
-            instance->ptr())[GrowableObjectArray::data_offset() / kWordSize];
-        SP[0] = reinterpret_cast<RawObject**>(
-            instance->ptr())[Array::length_offset() / kWordSize];
+        RawGrowableObjectArray* instance =
+            reinterpret_cast<RawGrowableObjectArray*>(SP[0]);
+        SP[0] = instance->ptr()->data_->ptr()->length_;
       } break;
       case MethodRecognizer::kListFactory: {
         // factory List<E>([int length]) {
@@ -2161,12 +2115,10 @@
           // Change the ArgumentsDescriptor of the call with a new cached one.
           argdesc_ = ArgumentsDescriptor::New(
               0, KernelBytecode::kNativeCallToGrowableListArgc);
-          if (!thread->isolate()->is_using_old_bytecode_instructions()) {
-            // Replace PC to the return trampoline so ReturnTOS would see
-            // a call bytecode at return address and will be able to get argc
-            // via DecodeArgc.
-            pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline();
-          }
+          // Replace PC to the return trampoline so ReturnTOS would see
+          // a call bytecode at return address and will be able to get argc
+          // via DecodeArgc.
+          pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline();
           if (!Invoke(thread, SP - 1, SP + 1, &pc, &FP, &SP)) {
             HANDLE_EXCEPTION;
           }
@@ -2317,9 +2269,7 @@
     }
 
     // Look at the caller to determine how many arguments to pop.
-    const uint8_t argc = thread->isolate()->is_using_old_bytecode_instructions()
-                             ? KernelBytecode::DecodeArgc_Old(pc)
-                             : KernelBytecode::DecodeArgc(pc);
+    const uint8_t argc = KernelBytecode::DecodeArgc(pc);
 
     // Restore SP, FP and PP. Push result and dispatch.
     SP = FrameArguments(FP, argc);
@@ -2536,10 +2486,9 @@
       const intptr_t class_id = cls->ptr()->id_;
       const intptr_t instance_size = cls->ptr()->instance_size_in_words_
                                      << kWordSizeLog2;
-      const uword start = thread->top();
-      if (LIKELY((start + instance_size) < thread->end())) {
-        thread->set_top(start + instance_size);
-        RawObject* result = InitializeHeader(start, class_id, instance_size);
+      RawObject* result;
+      if (TryAllocate(thread, class_id, instance_size, &result)) {
+        uword start = RawObject::ToAddr(result);
         for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
              offset += kWordSize) {
           *reinterpret_cast<RawObject**>(start + offset) = null_value;
@@ -2567,10 +2516,9 @@
       const intptr_t class_id = cls->ptr()->id_;
       const intptr_t instance_size = cls->ptr()->instance_size_in_words_
                                      << kWordSizeLog2;
-      const uword start = thread->top();
-      if (LIKELY((start + instance_size) < thread->end())) {
-        thread->set_top(start + instance_size);
-        RawObject* result = InitializeHeader(start, class_id, instance_size);
+      RawObject* result;
+      if (TryAllocate(thread, class_id, instance_size, &result)) {
+        uword start = RawObject::ToAddr(result);
         for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
              offset += kWordSize) {
           *reinterpret_cast<RawObject**>(start + offset) = null_value;
@@ -3070,51 +3018,27 @@
   }
 
   {
-    BYTECODE(Trap, 0);
-    BYTECODE(Unused00, 0);
-    BYTECODE_NEW(Unused01, 0);
-    BYTECODE_NEW(Unused02, 0);
-    BYTECODE_NEW(Unused03, 0);
-    BYTECODE_NEW(Unused04, 0);
-    BYTECODE_NEW(Unused05, 0);
-    BYTECODE_NEW(Unused06, 0);
-    BYTECODE_NEW(Unused07, 0);
-    BYTECODE_NEW(Unused08, 0);
-    BYTECODE_NEW(Unused09, 0);
-    BYTECODE_NEW(Unused10, 0);
-    BYTECODE_NEW(Unused11, 0);
-    BYTECODE_NEW(Unused12, 0);
-    BYTECODE_NEW(Unused13, 0);
-    BYTECODE_NEW(Unused14, 0);
-    BYTECODE_NEW(Unused15, 0);
-    BYTECODE_NEW(Unused16, 0);
-    BYTECODE_NEW(Unused17, 0);
-    BYTECODE_NEW(Unused18, 0);
-    BYTECODE_NEW(Unused19, 0);
-    BYTECODE_NEW(Unused20, 0);
-    BYTECODE_NEW(Unused21, 0);
-    BYTECODE_NEW(Unused22, 0);
-    BYTECODE_NEW(Unused23, 0);
-    BYTECODE_NEW(Unused24, 0);
-    BYTECODE_NEW(Unused25, 0);
-    BYTECODE_NEW(Unused26, 0);
-    BYTECODE_NEW(Unused27, 0);
-    BYTECODE_NEW(Unused28, 0);
-    BYTECODE_NEW(Unused29, 0);
-    BYTECODE_NEW(Unused30, 0);
-    BYTECODE_NEW(Unused31, 0);
-    BYTECODE_NEW(Unused32, 0);
-    BYTECODE_NEW(Unused33, 0);
-    BYTECODE_NEW(Unused34, 0);
-    BYTECODE_NEW(Unused35, 0);
-    BYTECODE_NEW(Unused36, 0);
-    BYTECODE_NEW(Unused37, 0);
+    BYTECODE_ENTRY_LABEL(Trap);
+
+#define UNIMPLEMENTED_LABEL_ORDN(Name)
+#define UNIMPLEMENTED_LABEL_WIDE(Name)
+#define UNIMPLEMENTED_LABEL_RESV(Name) BYTECODE_ENTRY_LABEL(Name)
+#define UNIMPLEMENTED_LABEL(name, encoding, kind, op1, op2, op3)               \
+  UNIMPLEMENTED_LABEL_##kind(name)
+
+    KERNEL_BYTECODES_LIST(UNIMPLEMENTED_LABEL)
+
+#undef UNIMPLEMENTED_LABEL_ORDN
+#undef UNIMPLEMENTED_LABEL_WIDE
+#undef UNIMPLEMENTED_LABEL_RESV
+#undef UNIMPLEMENTED_LABEL
+
     UNIMPLEMENTED();
     DISPATCH();
   }
 
   {
-    BYTECODE_NEW(VMInternal_ImplicitGetter, 0);
+    BYTECODE(VMInternal_ImplicitGetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitGetter);
@@ -3163,7 +3087,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_ImplicitSetter, 0);
+    BYTECODE(VMInternal_ImplicitSetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitSetter);
@@ -3284,7 +3208,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_ImplicitStaticGetter, 0);
+    BYTECODE(VMInternal_ImplicitStaticGetter, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitStaticGetter);
@@ -3316,7 +3240,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_MethodExtractor, 0);
+    BYTECODE(VMInternal_MethodExtractor, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kMethodExtractor);
@@ -3356,7 +3280,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_InvokeClosure, 0);
+    BYTECODE(VMInternal_InvokeClosure, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3378,7 +3302,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_InvokeField, 0);
+    BYTECODE(VMInternal_InvokeField, 0);
 
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kInvokeFieldDispatcher);
@@ -3482,7 +3406,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_ForwardDynamicInvocation, 0);
+    BYTECODE(VMInternal_ForwardDynamicInvocation, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) ==
            RawFunction::kDynamicInvocationForwarder);
@@ -3584,14 +3508,14 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_NoSuchMethodDispatcher, 0);
+    BYTECODE(VMInternal_NoSuchMethodDispatcher, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kNoSuchMethodDispatcher);
     goto NoSuchMethodFromPrologue;
   }
 
   {
-    BYTECODE_NEW(VMInternal_ImplicitStaticClosure, 0);
+    BYTECODE(VMInternal_ImplicitStaticClosure, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
     UNIMPLEMENTED();
@@ -3599,7 +3523,7 @@
   }
 
   {
-    BYTECODE_NEW(VMInternal_ImplicitInstanceClosure, 0);
+    BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
     RawFunction* function = FrameFunction(FP);
     ASSERT(Function::kind(function) == RawFunction::kImplicitClosureFunction);
     UNIMPLEMENTED();
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 11e65e9..000375c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -2561,6 +2561,7 @@
       !had_isolate_reload_context ? 0 : reload_context()->start_time_micros();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
   bool resume = false;
+  bool handle_non_service_messages = false;
   while (true) {
     // Handle all available vm service messages, up to a resume
     // request.
@@ -2571,6 +2572,8 @@
     }
     if (resume) {
       break;
+    } else {
+      handle_non_service_messages = true;
     }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -2589,6 +2592,13 @@
     Monitor::WaitResult res = ml.Wait();
     ASSERT(res == Monitor::kNotified);
   }
+  // If any non-service messages came in, we need to notify the registered
+  // message notify callback to check for unhandled messages. Otherwise, events
+  // may be left unhandled until the next event comes in. See
+  // https://github.com/dart-lang/sdk/issues/37312.
+  if ((saved_notify_callback != nullptr) && handle_non_service_messages) {
+    saved_notify_callback(Api::CastIsolate(this));
+  }
   set_message_notify_callback(saved_notify_callback);
   Dart_ExitScope();
 }
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 5d76a92..6c6ee8e 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -781,23 +781,6 @@
     return !unsafe_trust_strong_mode_types();
   }
 
-  static_assert(KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-                "Cleanup support for old bytecode format versions");
-  bool is_using_old_bytecode_instructions() const {
-    return UsingOldBytecodeInstructionsBit::decode(isolate_flags_);
-  }
-  void set_is_using_old_bytecode_instructions(bool value) {
-    isolate_flags_ =
-        UsingOldBytecodeInstructionsBit::update(value, isolate_flags_);
-  }
-  bool is_using_new_bytecode_instructions() const {
-    return UsingNewBytecodeInstructionsBit::decode(isolate_flags_);
-  }
-  void set_is_using_new_bytecode_instructions(bool value) {
-    isolate_flags_ =
-        UsingNewBytecodeInstructionsBit::update(value, isolate_flags_);
-  }
-
   bool has_attempted_stepping() const {
     return HasAttemptedSteppingBit::decode(isolate_flags_);
   }
@@ -930,13 +913,7 @@
   V(Obfuscate)                                                                 \
   V(CompactionInProgress)                                                      \
   V(ShouldLoadVmService)                                                       \
-  V(UnsafeTrustStrongModeTypes)                                                \
-  V(UsingOldBytecodeInstructions)                                              \
-  V(UsingNewBytecodeInstructions)
-
-  static_assert(
-      KernelBytecode::kMinSupportedBytecodeFormatVersion < 7,
-      "Cleanup UsingOldBytecodeInstructions and UsingNewBytecodeInstructions");
+  V(UnsafeTrustStrongModeTypes)
 
   // Isolate specific flags.
   enum FlagBits {
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 75273e8..c261bba 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -4,6 +4,8 @@
 
 #include "vm/isolate_reload.h"
 
+#include <memory>
+
 #include "vm/bit_vector.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_api_impl.h"
@@ -171,10 +173,10 @@
   for (intptr_t i = 0; i < new_fields_->length(); i++) {
     // Create a function that returns the expression.
     const Field* field = new_fields_->At(i);
-    if (field->kernel_offset() > 0) {
-      eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
+    if (field->is_declared_in_bytecode()) {
+      UNIMPLEMENTED();
     } else {
-      UNREACHABLE();
+      eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
     }
 
     for (intptr_t j = 0; j < after_->length(); j++) {
@@ -526,17 +528,6 @@
   return (a_length - a_cursor);
 }
 
-template <class T>
-class ResourceHolder : ValueObject {
-  T* resource_;
-
- public:
-  ResourceHolder() : resource_(NULL) {}
-  void set(T* resource) { resource_ = resource; }
-  T* get() { return resource_; }
-  ~ResourceHolder() { delete (resource_); }
-};
-
 static void AcceptCompilation(Thread* thread) {
   TransitionVMToNative transition(thread);
   Dart_KernelCompilationResult result = KernelIsolate::AcceptCompilation();
@@ -582,7 +573,7 @@
   }
 
   Object& result = Object::Handle(thread->zone());
-  ResourceHolder<kernel::Program> kernel_program;
+  std::unique_ptr<kernel::Program> kernel_program;
   String& packages_url = String::Handle();
   if (packages_url_ != NULL) {
     packages_url = String::New(packages_url_);
@@ -609,10 +600,10 @@
     // root_script_url is a valid .dill file. If that's the case, a Program*
     // is returned. Otherwise, this is likely a source file that needs to be
     // compiled, so ReadKernelFromFile returns NULL.
-    kernel_program.set(kernel::Program::ReadFromFile(root_script_url));
-    if (kernel_program.get() != NULL) {
-      num_received_libs_ = kernel_program.get()->library_count();
-      bytes_received_libs_ = kernel_program.get()->kernel_data_size();
+    kernel_program = kernel::Program::ReadFromFile(root_script_url);
+    if (kernel_program != nullptr) {
+      num_received_libs_ = kernel_program->library_count();
+      bytes_received_libs_ = kernel_program->kernel_data_size();
       p_num_received_classes = &num_received_classes_;
       p_num_received_procedures = &num_received_procedures_;
     } else {
@@ -669,7 +660,7 @@
       // into the middle of c-allocated buffer and don't have a finalizer).
       I->RetainKernelBlob(typed_data);
 
-      kernel_program.set(kernel::Program::ReadFromTypedData(typed_data));
+      kernel_program = kernel::Program::ReadFromTypedData(typed_data);
     }
 
     kernel::KernelLoader::FindModifiedLibraries(
@@ -808,6 +799,8 @@
   // Other errors (e.g. a parse error) are captured by the reload system.
   if (result.IsError()) {
     FinalizeFailedLoad(Error::Cast(result));
+  } else {
+    ReportSuccess();
   }
 }
 
@@ -933,7 +926,11 @@
     if (frame->IsDartFrame() && !frame->is_interpreted()) {
       func = frame->LookupDartFunction();
       ASSERT(!func.IsNull());
-      func.EnsureHasCompiledUnoptimizedCode();
+      // Force-optimized functions don't need unoptimized code because their
+      // optimized code cannot deopt.
+      if (!func.ForceOptimize()) {
+        func.EnsureHasCompiledUnoptimizedCode();
+      }
     }
   }
 }
@@ -1900,7 +1897,7 @@
       bytecode.ResetICDatas(zone);
     } else {
       code = frame->LookupDartCode();
-      if (code.is_optimized()) {
+      if (code.is_optimized() && !code.is_force_optimized()) {
         // If this code is optimized, we need to reset the ICs in the
         // corresponding unoptimized code, which will be executed when the stack
         // unwinds to the optimized code.
@@ -2314,6 +2311,9 @@
   for (intptr_t i = 1; i < num_cids; i++) {
     if (class_table->HasValidClassAt(i)) {
       cls = class_table->At(i);
+      if (!cls.is_declaration_loaded()) {
+        continue;  // Can't have any subclasses or implementors yet.
+      }
       subclasses = cls.direct_subclasses();
       if (!subclasses.IsNull()) {
         cls.ClearDirectSubclasses();
@@ -2337,6 +2337,9 @@
   for (intptr_t i = 1; i < num_cids; i++) {
     if (class_table->HasValidClassAt(i)) {
       cls = class_table->At(i);
+      if (!cls.is_declaration_loaded()) {
+        continue;  // Will register itself later when loaded.
+      }
       super_type = cls.super_type();
       if (!super_type.IsNull() && !super_type.IsObjectType()) {
         super_cls = cls.SuperClass();
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 32f975f..9afdc32 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_KERNEL_H_
 #define RUNTIME_VM_KERNEL_H_
 
+#include <memory>
+
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/globals.h"
@@ -62,15 +64,16 @@
   // Read a kernel Program from the given Reader. Note the returned Program
   // can potentially contain several "sub programs", though the library count
   // etc will reference the last "sub program" only.
-  static Program* ReadFrom(Reader* reader, const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFrom(Reader* reader,
+                                           const char** error = nullptr);
 
-  static Program* ReadFromFile(const char* script_uri,
-                               const char** error = nullptr);
-  static Program* ReadFromBuffer(const uint8_t* buffer,
-                                 intptr_t buffer_length,
-                                 const char** error = nullptr);
-  static Program* ReadFromTypedData(const ExternalTypedData& typed_data,
-                                    const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromFile(const char* script_uri,
+                                               const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromBuffer(const uint8_t* buffer,
+                                                 intptr_t buffer_length,
+                                                 const char** error = nullptr);
+  static std::unique_ptr<Program> ReadFromTypedData(
+      const ExternalTypedData& typed_data, const char** error = nullptr);
 
   bool is_single_program() { return single_program_; }
   uint32_t binary_version() { return binary_version_; }
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index d974b31..eda3858 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -81,7 +81,7 @@
 const char* kKernelInvalidSizeIndicated =
     "Invalid kernel binary: Indicated size is invalid";
 
-Program* Program::ReadFrom(Reader* reader, const char** error) {
+std::unique_ptr<Program> Program::ReadFrom(Reader* reader, const char** error) {
   if (reader->size() < 60) {
     // A kernel file currently contains at least the following:
     //   * Magic number (32)
@@ -120,7 +120,7 @@
     return nullptr;
   }
 
-  Program* program = new Program();
+  std::unique_ptr<Program> program(new Program());
   program->binary_version_ = formatVersion;
   program->kernel_data_ = reader->buffer();
   program->kernel_data_size_ = reader->size();
@@ -136,7 +136,6 @@
       if (error != nullptr) {
         *error = kKernelInvalidSizeIndicated;
       }
-      delete program;
       return nullptr;
     }
     ++subprogram_count;
@@ -164,13 +163,13 @@
   return program;
 }
 
-Program* Program::ReadFromFile(const char* script_uri,
-                               const char** error /* = nullptr */) {
+std::unique_ptr<Program> Program::ReadFromFile(
+    const char* script_uri, const char** error /* = nullptr */) {
   Thread* thread = Thread::Current();
   if (script_uri == NULL) {
-    return NULL;
+    return nullptr;
   }
-  kernel::Program* kernel_program = NULL;
+  std::unique_ptr<kernel::Program> kernel_program;
 
   const String& uri = String::Handle(String::New(script_uri));
   const Object& ret = Object::Handle(thread->isolate()->CallTagHandler(
@@ -204,15 +203,15 @@
   return kernel_program;
 }
 
-Program* Program::ReadFromBuffer(const uint8_t* buffer,
-                                 intptr_t buffer_length,
-                                 const char** error) {
+std::unique_ptr<Program> Program::ReadFromBuffer(const uint8_t* buffer,
+                                                 intptr_t buffer_length,
+                                                 const char** error) {
   kernel::Reader reader(buffer, buffer_length);
   return kernel::Program::ReadFrom(&reader, error);
 }
 
-Program* Program::ReadFromTypedData(const ExternalTypedData& typed_data,
-                                    const char** error) {
+std::unique_ptr<Program> Program::ReadFromTypedData(
+    const ExternalTypedData& typed_data, const char** error) {
   kernel::Reader reader(typed_data);
   return kernel::Program::ReadFrom(&reader, error);
 }
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index d37c67d..681783d 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -6,6 +6,8 @@
 
 #include <string.h>
 
+#include <memory>
+
 #include "vm/compiler/frontend/constant_evaluator.h"
 #include "vm/compiler/frontend/kernel_translation_helper.h"
 #include "vm/dart_api_impl.h"
@@ -190,6 +192,7 @@
       zone_(thread_->zone()),
       isolate_(thread_->isolate()),
       patch_classes_(Array::ZoneHandle(zone_)),
+      active_class_(),
       library_kernel_offset_(-1),  // Set to the correct value in LoadLibrary
       correction_offset_(-1),      // Set to the correct value in LoadLibrary
       loading_native_wrappers_library_(false),
@@ -206,9 +209,9 @@
       bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
+      evaluating_(GrowableObjectArray::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
-      potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)),
@@ -292,17 +295,15 @@
     reader.set_raw_buffer(program->kernel_data() + subprogram_start);
     reader.set_size(subprogram_end - subprogram_start);
     reader.set_offset(0);
-    Program* subprogram = Program::ReadFrom(&reader);
+    std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
     ASSERT(subprogram->is_single_program());
-    KernelLoader loader(subprogram, &uri_to_source_table);
+    KernelLoader loader(subprogram.get(), &uri_to_source_table);
     Object& load_result = Object::Handle(loader.LoadProgram(false));
     if (load_result.IsError()) return load_result;
 
     if (load_result.IsLibrary()) {
       library ^= load_result.raw();
     }
-
-    delete subprogram;
   }
 
   if (process_pending_classes && !ClassFinalizer::ProcessPendingClasses()) {
@@ -455,9 +456,9 @@
       bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
+      evaluating_(GrowableObjectArray::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
       potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
-      potential_extension_libraries_(GrowableObjectArray::Handle(Z)),
       pragma_class_(Class::Handle(Z)),
       name_index_handle_(Smi::Handle(Z)),
       expression_evaluation_library_(Library::Handle(Z)),
@@ -472,32 +473,6 @@
   H.InitFromKernelProgramInfo(kernel_program_info_);
 }
 
-const Array& KernelLoader::ReadConstantTable() {
-  if (program_->library_count() == 0) {
-    return Array::empty_array();
-  }
-  // We use the very first library's toplevel class as an owner for an
-  // [ActiveClassScope]
-  //
-  // Though since constants cannot refer to types containing type parameter
-  // references, the only purpose of the class is to serve as an owner for
-  // signature functions (which get created for function types).
-  const dart::Library& owner_library =
-      Library::Handle(Z, LookupLibrary(library_canonical_name(0)));
-  const dart::Class& toplevel_class =
-      Class::Handle(Z, owner_library.toplevel_class());
-  ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
-
-  helper_.SetOffset(program_->constant_table_offset());
-  TypeTranslator type_translator_(&helper_, &active_class_,
-                                  true /* finalize */);
-  ASSERT(type_translator_.active_class_ == &active_class_);
-
-  ConstantHelper helper(Z, &helper_, &type_translator_, &active_class_,
-                        skip_vmservice_library_);
-  return helper.ReadConstantTable();
-}
-
 void KernelLoader::EvaluateDelayedPragmas() {
   potential_pragma_functions_ =
       kernel_program_info_.potential_pragma_functions();
@@ -522,66 +497,68 @@
       GrowableObjectArray::Handle(Z));
 }
 
-void KernelLoader::AnnotateNativeProcedures(const Array& constant_table_array) {
-  KernelConstantsMap constant_table(constant_table_array.raw());
+void KernelLoader::AnnotateNativeProcedures() {
   potential_natives_ = kernel_program_info_.potential_natives();
   const intptr_t length =
       !potential_natives_.IsNull() ? potential_natives_.Length() : 0;
-  if (length > 0) {
-    // Obtain `dart:_internal::ExternalName.name`.
-    EnsureExternalClassIsLookedUp();
-    Instance& constant = Instance::Handle(Z);
-    String& native_name = String::Handle(Z);
+  if (length == 0) return;
 
-    // Start scanning all candidates in [potential_natives] for the annotation
-    // constant.  If the annotation is found, flag the [Function] as native and
-    // attach the native name to it.
-    Function& function = Function::Handle(Z);
-    for (intptr_t i = 0; i < length; ++i) {
-      function ^= potential_natives_.At(i);
-      helper_.SetOffset(function.KernelDataProgramOffset() +
-                        function.kernel_offset());
-      {
-        ProcedureHelper procedure_helper(&helper_);
-        procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
-      }
+  // Prepare lazy constant reading.
+  ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                       &active_class_);
 
-      const intptr_t annotation_count = helper_.ReadListLength();
-      for (intptr_t j = 0; j < annotation_count; ++j) {
-        const intptr_t tag = helper_.PeekTag();
-        if (tag == kConstantExpression ||
-            tag == kDeprecated_ConstantExpression) {
-          helper_.ReadByte();  // Skip the tag.
+  // Obtain `dart:_internal::ExternalName.name`.
+  EnsureExternalClassIsLookedUp();
+  Instance& constant = Instance::Handle(Z);
+  String& native_name = String::Handle(Z);
 
-          // We have a candiate.  Let's look if it's an instance of the
-          // ExternalName class.
-          if (tag == kConstantExpression) {
-            helper_.ReadPosition();  // Skip fileOffset.
-            helper_.SkipDartType();  // Skip type.
-          }
-          const intptr_t constant_table_offset = helper_.ReadUInt();
-          constant ^= constant_table.GetOrDie(constant_table_offset);
-          if (constant.clazz() == external_name_class_.raw()) {
-            // We found the annotation, let's flag the function as native and
-            // set the native name!
-            native_name ^= constant.GetField(external_name_field_);
-            function.set_is_native(true);
-            function.set_native_name(native_name);
-            function.set_is_external(false);
-            break;
-          }
-        } else {
-          helper_.SkipExpression();
-        }
-      }
+  // Start scanning all candidates in [potential_natives] for the annotation
+  // constant.  If the annotation is found, flag the [Function] as native and
+  // attach the native name to it.
+  Function& function = Function::Handle(Z);
+  for (intptr_t i = 0; i < length; ++i) {
+    function ^= potential_natives_.At(i);
+    helper_.SetOffset(function.KernelDataProgramOffset() +
+                      function.kernel_offset());
+    {
+      ProcedureHelper procedure_helper(&helper_);
+      procedure_helper.ReadUntilExcluding(ProcedureHelper::kAnnotations);
     }
 
-    // Clear out the list of [Function] objects which might need their native
-    // name to be set after reading the constant table from the kernel blob.
-    potential_natives_ = GrowableObjectArray::null();
-    kernel_program_info_.set_potential_natives(potential_natives_);
+    const intptr_t annotation_count = helper_.ReadListLength();
+    for (intptr_t j = 0; j < annotation_count; ++j) {
+      const intptr_t tag = helper_.PeekTag();
+      if (tag == kConstantExpression || tag == kDeprecated_ConstantExpression) {
+        helper_.ReadByte();  // Skip the tag.
+
+        // We have a candidate.  Let's look if it's an instance of the
+        // ExternalName class.
+        if (tag == kConstantExpression) {
+          helper_.ReadPosition();  // Skip fileOffset.
+          helper_.SkipDartType();  // Skip type.
+        }
+        const intptr_t constant_table_offset = helper_.ReadUInt();
+        constant = constant_evaluator.EvaluateConstantExpression(
+            constant_table_offset);
+        if (constant.clazz() == external_name_class_.raw()) {
+          // We found the annotation, let's flag the function as native and
+          // set the native name!
+          native_name ^= constant.GetField(external_name_field_);
+          function.set_is_native(true);
+          function.set_native_name(native_name);
+          function.set_is_external(false);
+          break;
+        }
+      } else {
+        helper_.SkipExpression();
+      }
+    }
   }
-  ASSERT(constant_table.Release().raw() == constant_table_array.raw());
+
+  // Clear out the list of [Function] objects which might need their native
+  // name to be set after reading the constant table from the kernel blob.
+  potential_natives_ = GrowableObjectArray::null();
+  kernel_program_info_.set_potential_natives(potential_natives_);
 }
 
 RawString* KernelLoader::DetectExternalNameCtor() {
@@ -638,14 +615,16 @@
   return IsClassName(annotation_class, Symbols::DartCore(), Symbols::Pragma());
 }
 
-void KernelLoader::LoadNativeExtensionLibraries(
-    const Array& constant_table_array) {
-  const intptr_t length = !potential_extension_libraries_.IsNull()
-                              ? potential_extension_libraries_.Length()
-                              : 0;
-  if (length == 0) return;
+void KernelLoader::LoadNativeExtensionLibraries() {
+  const auto& potential_extension_libraries =
+      GrowableObjectArray::Handle(Z, H.GetPotentialExtensionLibraries());
+  if (potential_extension_libraries.IsNull()) {
+    return;
+  }
 
-  KernelConstantsMap constant_table(constant_table_array.raw());
+  // Prepare lazy constant reading.
+  ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                       &active_class_);
 
   // Obtain `dart:_internal::ExternalName.name`.
   EnsureExternalClassIsLookedUp();
@@ -653,70 +632,89 @@
   Instance& constant = Instance::Handle(Z);
   String& uri_path = String::Handle(Z);
   Library& library = Library::Handle(Z);
-#if !defined(DART_PRECOMPILER)
-  Object& result = Object::Handle(Z);
-#endif
 
+  const intptr_t length = potential_extension_libraries.Length();
   for (intptr_t i = 0; i < length; ++i) {
-    library ^= potential_extension_libraries_.At(i);
-    ASSERT(!library.is_declared_in_bytecode());
-    helper_.SetOffset(library.kernel_offset());
+    library ^= potential_extension_libraries.At(i);
 
-    LibraryHelper library_helper(&helper_);
-    library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
-
-    const intptr_t annotation_count = helper_.ReadListLength();
-    for (intptr_t j = 0; j < annotation_count; ++j) {
-      uri_path = String::null();
-
-      const intptr_t tag = helper_.PeekTag();
-      if (tag == kConstantExpression || tag == kDeprecated_ConstantExpression) {
-        helper_.ReadByte();  // Skip the tag.
-
-        if (tag == kConstantExpression) {
-          helper_.ReadPosition();  // Skip fileOffset.
-          helper_.SkipDartType();  // Skip type.
+    if (library.is_declared_in_bytecode()) {
+      const auto& imports = Array::Handle(Z, library.imports());
+      auto& ns = Namespace::Handle(Z);
+      auto& importee = Library::Handle(Z);
+      for (intptr_t j = 0; j < imports.Length(); ++j) {
+        ns ^= imports.At(j);
+        if (ns.IsNull()) continue;
+        importee = ns.library();
+        uri_path = importee.url();
+        if (uri_path.StartsWith(Symbols::DartExtensionScheme())) {
+          LoadNativeExtension(library, uri_path);
         }
-        const intptr_t constant_table_index = helper_.ReadUInt();
-        constant ^= constant_table.GetOrDie(constant_table_index);
-        if (constant.clazz() == external_name_class_.raw()) {
-          uri_path ^= constant.GetField(external_name_field_);
+      }
+    } else {
+      helper_.SetOffset(library.kernel_offset());
+
+      LibraryHelper library_helper(&helper_);
+      library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations);
+
+      const intptr_t annotation_count = helper_.ReadListLength();
+      for (intptr_t j = 0; j < annotation_count; ++j) {
+        uri_path = String::null();
+
+        const intptr_t tag = helper_.PeekTag();
+        if (tag == kConstantExpression ||
+            tag == kDeprecated_ConstantExpression) {
+          helper_.ReadByte();  // Skip the tag.
+
+          if (tag == kConstantExpression) {
+            helper_.ReadPosition();  // Skip fileOffset.
+            helper_.SkipDartType();  // Skip type.
+          }
+          const intptr_t constant_table_offset = helper_.ReadUInt();
+          constant = constant_evaluator.EvaluateConstantExpression(
+              constant_table_offset);
+          if (constant.clazz() == external_name_class_.raw()) {
+            uri_path ^= constant.GetField(external_name_field_);
+          }
+        } else if (tag == kConstructorInvocation ||
+                   tag == kConstConstructorInvocation) {
+          uri_path = DetectExternalNameCtor();
+        } else {
+          helper_.SkipExpression();
         }
-      } else if (tag == kConstructorInvocation ||
-                 tag == kConstConstructorInvocation) {
-        uri_path = DetectExternalNameCtor();
-      } else {
-        helper_.SkipExpression();
+
+        if (uri_path.IsNull()) continue;
+
+        LoadNativeExtension(library, uri_path);
+
+        // Create a dummy library and add it as an import to the current
+        // library. This allows later to discover and reload this native
+        // extension, e.g. when running from an app-jit snapshot.
+        // See Loader::ReloadNativeExtensions(...) which relies on
+        // Dart_GetImportsOfScheme('dart-ext').
+        const auto& native_library = Library::Handle(Library::New(uri_path));
+        library.AddImport(Namespace::Handle(Namespace::New(
+            native_library, Array::null_array(), Array::null_array())));
       }
-
-      if (uri_path.IsNull()) continue;
-
-#if !defined(DART_PRECOMPILER)
-      if (!I->HasTagHandler()) {
-        H.ReportError("no library handler registered.");
-      }
-
-      I->BlockClassFinalization();
-      result = I->CallTagHandler(Dart_kImportExtensionTag, library, uri_path);
-      I->UnblockClassFinalization();
-
-      if (result.IsError()) {
-        H.ReportError(Error::Cast(result), "library handler failed");
-      }
-#endif
-
-      // Create a dummy library and add it as an import to the current library.
-      // This allows later to discover and reload this native extension, e.g.
-      // when running from an app-jit snapshot.
-      // See Loader::ReloadNativeExtensions(...) which relies on
-      // Dart_GetImportsOfScheme('dart-ext').
-      const auto& native_library = Library::Handle(Library::New(uri_path));
-      library.AddImport(Namespace::Handle(Namespace::New(
-          native_library, Array::null_array(), Array::null_array())));
     }
   }
-  potential_extension_libraries_ = GrowableObjectArray::null();
-  ASSERT(constant_table.Release().raw() == constant_table_array.raw());
+}
+
+void KernelLoader::LoadNativeExtension(const Library& library,
+                                       const String& uri_path) {
+#if !defined(DART_PRECOMPILER)
+  if (!I->HasTagHandler()) {
+    H.ReportError("no library handler registered.");
+  }
+
+  I->BlockClassFinalization();
+  const auto& result = Object::Handle(
+      Z, I->CallTagHandler(Dart_kImportExtensionTag, library, uri_path));
+  I->UnblockClassFinalization();
+
+  if (result.IsError()) {
+    H.ReportError(Error::Cast(result), "library handler failed");
+  }
+#endif
 }
 
 RawObject* KernelLoader::LoadProgram(bool process_pending_classes) {
@@ -743,6 +741,7 @@
       }
     }
 
+    // Finalize still pending classes if requested.
     if (process_pending_classes) {
       if (!ClassFinalizer::ProcessPendingClasses()) {
         // Class finalization failed -> sticky error would be set.
@@ -750,44 +749,17 @@
       }
     }
 
-    // Set pending fields array to flag constant table loading.
-    ASSERT(I->object_store()->pending_unevaluated_const_fields() ==
-           GrowableObjectArray::null());
-    GrowableObjectArray& pending_unevaluated_const_fields =
-        GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
-    I->object_store()->set_pending_unevaluated_const_fields(
-        pending_unevaluated_const_fields);
-
-    // All classes were successfully loaded, so let's:
-    //     a) load & canonicalize the constant table
-    const Array& constants = ReadConstantTable();
-
-    //     b) set the native names for native functions which have been created
-    //        so far (the rest will be directly set during LoadProcedure)
-    AnnotateNativeProcedures(constants);
-    LoadNativeExtensionLibraries(constants);
-
-    //     c) update all scripts with the constants array
-    ASSERT(kernel_program_info_.constants() == Array::null());
-    kernel_program_info_.set_constants(constants);
-    kernel_program_info_.set_constants_table(ExternalTypedData::Handle(Z));
-
-    //     d) evaluate pending field initializers
-    Error& error = Error::Handle(Z);
-    Field& field = Field::Handle(Z);
-    for (intptr_t i = 0, n = pending_unevaluated_const_fields.Length(); i < n;
-         i++) {
-      field ^= pending_unevaluated_const_fields.At(i);
-      error = field.Initialize();
-      if (!error.IsNull()) {
-        H.ReportError(error, "postponed field initializer");
-      }
-    }
-    pending_unevaluated_const_fields = GrowableObjectArray::null();
-    I->object_store()->set_pending_unevaluated_const_fields(
-        pending_unevaluated_const_fields);
-
-    //     e) evaluate pragmas that were delayed
+    // Sets the constants array to an empty hash and leaves the constant
+    // table's raw bytes in place for lazy reading. We can fix up all
+    // "pending" processing now, and must ensure we don't create new
+    // ones from this point on.
+    ASSERT(kernel_program_info_.constants_table() != ExternalTypedData::null());
+    const Array& array =
+        Array::Handle(Z, HashTables::New<KernelConstantsMap>(16, Heap::kOld));
+    kernel_program_info_.set_constants(array);
+    H.SetConstants(array);  // for caching
+    AnnotateNativeProcedures();
+    LoadNativeExtensionLibraries();
     EvaluateDelayedPragmas();
 
     NameIndex main = program_->main_method();
@@ -920,12 +892,11 @@
       reader.set_raw_buffer(program->kernel_data() + subprogram_start);
       reader.set_size(subprogram_end - subprogram_start);
       reader.set_offset(0);
-      Program* subprogram = Program::ReadFrom(&reader);
+      std::unique_ptr<Program> subprogram = Program::ReadFrom(&reader);
       ASSERT(subprogram->is_single_program());
-      KernelLoader loader(subprogram, /*uri_to_source_table=*/nullptr);
+      KernelLoader loader(subprogram.get(), /*uri_to_source_table=*/nullptr);
       loader.walk_incremental_kernel(modified_libs, is_empty_program,
                                      p_num_classes, p_num_procedures);
-      delete subprogram;
     }
   }
 }
@@ -1067,8 +1038,9 @@
       helper_.ReaderOffset() - correction_offset_;
   intptr_t annotation_count = helper_.ReadListLength();  // read list length.
   if (annotation_count > 0) {
-    EnsurePotentialExtensionLibraries();
-    potential_extension_libraries_.Add(library);
+    // This must wait until we can evaluate constants.
+    // So put on the "pending" list.
+    H.AddPotentialExtensionLibrary(library);
   }
   for (intptr_t i = 0; i < annotation_count; ++i) {
     helper_.SkipExpression();  // read ith annotation.
@@ -1148,7 +1120,6 @@
   if (toplevel_class.is_loaded()) {
     return;
   }
-
   TIMELINE_DURATION(Thread::Current(), Isolate, "FinishTopLevelClassLoading");
 
   ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
@@ -1190,7 +1161,7 @@
     {
       String& native_name_unused = String::Handle();
       bool is_potential_native_unused;
-      ReadVMAnnotations(annotation_count, &native_name_unused,
+      ReadVMAnnotations(library, annotation_count, &native_name_unused,
                         &is_potential_native_unused, &has_pragma_annotation);
     }
     field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1436,8 +1407,9 @@
     out_class->set_script(script);
   }
   if (out_class->token_pos() == TokenPosition::kNoSource) {
-    class_helper.ReadUntilIncluding(ClassHelper::kStartPosition);
+    class_helper.ReadUntilIncluding(ClassHelper::kEndPosition);
     out_class->set_token_pos(class_helper.start_position_);
+    out_class->set_end_token_pos(class_helper.end_position_);
   }
 
   class_helper.ReadUntilIncluding(ClassHelper::kFlags);
@@ -1451,7 +1423,7 @@
   {
     String& native_name_unused = String::Handle(Z);
     bool is_potential_native_unused = false;
-    ReadVMAnnotations(annotation_count, &native_name_unused,
+    ReadVMAnnotations(library, annotation_count, &native_name_unused,
                       &is_potential_native_unused, &has_pragma_annotation);
   }
   if (has_pragma_annotation) {
@@ -1545,7 +1517,7 @@
       {
         String& native_name_unused = String::Handle();
         bool is_potential_native_unused;
-        ReadVMAnnotations(annotation_count, &native_name_unused,
+        ReadVMAnnotations(library, annotation_count, &native_name_unused,
                           &is_potential_native_unused, &has_pragma_annotation);
       }
       field_helper.SetJustRead(FieldHelper::kAnnotations);
@@ -1618,7 +1590,7 @@
     {
       String& native_name_unused = String::Handle();
       bool is_potential_native_unused;
-      ReadVMAnnotations(annotation_count, &native_name_unused,
+      ReadVMAnnotations(library, annotation_count, &native_name_unused,
                         &is_potential_native_unused, &has_pragma_annotation);
     }
     constructor_helper.SetJustRead(ConstructorHelper::kAnnotations);
@@ -1678,7 +1650,11 @@
     }
   }
 
-  ASSERT(!klass.is_loaded());
+  // Due to ReadVMAnnotations(), the klass may have been loaded at this point
+  // (loading the class while evaluating annotations).
+  if (klass.is_loaded()) {
+    return;
+  }
 
   // Everything up til the procedures are skipped implicitly, and class_helper
   // is no longer used.
@@ -1760,12 +1736,14 @@
 //   `has_pragma_annotation`: non-null if @pragma(...) was found (no information
 //   is given on the kind of pragma directive).
 //
-void KernelLoader::ReadVMAnnotations(intptr_t annotation_count,
+void KernelLoader::ReadVMAnnotations(const Library& library,
+                                     intptr_t annotation_count,
                                      String* native_name,
                                      bool* is_potential_native,
                                      bool* has_pragma_annotation) {
   *is_potential_native = false;
   *has_pragma_annotation = false;
+  Instance& constant = Instance::Handle(Z);
   String& detected_name = String::Handle(Z);
   for (intptr_t i = 0; i < annotation_count; ++i) {
     const intptr_t tag = helper_.PeekTag();
@@ -1828,7 +1806,13 @@
                           Symbols::DartCore(), Symbols::Pragma());
         }
       } else {
-        KernelConstantsMap constant_table(constant_table_array.raw());
+        // Prepare lazy constant reading.
+        const dart::Class& toplevel_class =
+            Class::Handle(Z, library.toplevel_class());
+        ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
+        ConstantEvaluator constant_evaluator(&helper_, &type_translator_,
+                                             &active_class_);
+
         helper_.ReadByte();  // Skip the tag.
 
         // Obtain `dart:_internal::ExternalName.name`.
@@ -1841,18 +1825,27 @@
           helper_.ReadPosition();  // Skip fileOffset.
           helper_.SkipDartType();  // Skip type.
         }
-        const intptr_t constant_table_index = helper_.ReadUInt();
-        const Object& constant =
-            Object::Handle(constant_table.GetOrDie(constant_table_index));
-        if (constant.clazz() == external_name_class_.raw()) {
-          const Instance& instance =
-              Instance::Handle(Instance::RawCast(constant.raw()));
-          *native_name =
-              String::RawCast(instance.GetField(external_name_field_));
-        } else if (constant.clazz() == pragma_class_.raw()) {
-          *has_pragma_annotation = true;
+        const intptr_t constant_table_offset = helper_.ReadUInt();
+        // A cycle in evaluating the same library instance occurs when we are
+        // trying to finalize a class while evaluation the constant. We break
+        // this cycle by ignoring the second evaluation, since the first
+        // evaluation will take care of inspecting the result.
+        // TODO(ajcbik): avoid cycle detection completely by peeking
+        //               into the constants and proceed only for @pragma
+        //               or @ExternalName
+        if (EnqueueLibraryForEvaluation(library)) {
+          constant = constant_evaluator.EvaluateConstantExpression(
+              constant_table_offset);
+          DequeueLibraryForEvaluation(library);
+          if (constant.clazz() == external_name_class_.raw()) {
+            const Instance& instance =
+                Instance::Handle(Instance::RawCast(constant.raw()));
+            *native_name =
+                String::RawCast(instance.GetField(external_name_field_));
+          } else if (constant.clazz() == pragma_class_.raw()) {
+            *has_pragma_annotation = true;
+          }
         }
-        ASSERT(constant_table.Release().raw() == constant_table_array.raw());
       }
     } else {
       helper_.SkipExpression();
@@ -1881,8 +1874,8 @@
   bool is_potential_native;
   bool has_pragma_annotation;
   const intptr_t annotation_count = helper_.ReadListLength();
-  ReadVMAnnotations(annotation_count, &native_name, &is_potential_native,
-                    &has_pragma_annotation);
+  ReadVMAnnotations(library, annotation_count, &native_name,
+                    &is_potential_native, &has_pragma_annotation);
   // If this is a potential native, we'll unset is_external in
   // AnnotateNativeProcedures instead.
   is_external = is_external && native_name.IsNull();
@@ -1959,6 +1952,7 @@
     function.set_native_name(native_name);
   }
   if (is_potential_native) {
+    // Cannot be processed right now, so put on "pending" list.
     EnsurePotentialNatives();
     potential_natives_.Add(function);
   }
@@ -1979,6 +1973,8 @@
 
   if (has_pragma_annotation) {
     if (kernel_program_info_.constants() == Array::null()) {
+      // Any potential pragma function before point at which
+      // constant table could be loaded goes to "pending".
       EnsurePotentialPragmaFunctions();
       potential_pragma_functions_.Add(function);
     } else {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index f6d7665..a6bd55d 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -230,8 +230,6 @@
 
   void ReadObfuscationProhibitions();
 
-  const Array& ReadConstantTable();
-
   // Check for the presence of a (possibly const) constructor for the
   // 'ExternalName' class. If found, returns the name parameter to the
   // constructor.
@@ -243,11 +241,13 @@
 
   bool IsClassName(NameIndex name, const String& library, const String& klass);
 
-  void AnnotateNativeProcedures(const Array& constant_table);
-  void LoadNativeExtensionLibraries(const Array& constant_table);
+  void AnnotateNativeProcedures();
+  void LoadNativeExtensionLibraries();
+  void LoadNativeExtension(const Library& library, const String& uri_path);
   void EvaluateDelayedPragmas();
 
-  void ReadVMAnnotations(intptr_t annotation_count,
+  void ReadVMAnnotations(const Library& library,
+                         intptr_t annotation_count,
                          String* native_name,
                          bool* is_potential_native,
                          bool* has_pragma_annotation);
@@ -390,9 +390,34 @@
         translation_helper_.EnsurePotentialPragmaFunctions();
   }
 
-  void EnsurePotentialExtensionLibraries() {
-    if (potential_extension_libraries_.IsNull()) {
-      potential_extension_libraries_ = GrowableObjectArray::New();
+  // Returns `true` if the [library] was newly enqueued or `false`
+  // if it was already enqueued. Allocates storage on first enqueue.
+  bool EnqueueLibraryForEvaluation(const Library& library) {
+    evaluating_ = kernel_program_info_.evaluating();
+    if (evaluating_.IsNull()) {
+      evaluating_ = GrowableObjectArray::New();
+      kernel_program_info_.set_evaluating(evaluating_);
+      ASSERT(!evaluating_.IsNull());
+    } else {
+      for (intptr_t i = 0, n = evaluating_.Length(); i < n; i++) {
+        if (library.raw() == evaluating_.At(i)) {
+          return false;
+        }
+      }
+    }
+    evaluating_.Add(library);
+    return true;
+  }
+
+  // Dequeues most recent libary. Releases storage when empty.
+  void DequeueLibraryForEvaluation(const Library& library) {
+    ASSERT(!evaluating_.IsNull());
+    RawObject* object = evaluating_.RemoveLast();
+    ASSERT(library.raw() == object);
+    if (evaluating_.Length() == 0) {
+      evaluating_ = GrowableObjectArray::null();
+      kernel_program_info_.set_evaluating(evaluating_);
+      ASSERT(evaluating_.IsNull());
     }
   }
 
@@ -423,9 +448,9 @@
 
   Class& external_name_class_;
   Field& external_name_field_;
+  GrowableObjectArray& evaluating_;
   GrowableObjectArray& potential_natives_;
   GrowableObjectArray& potential_pragma_functions_;
-  GrowableObjectArray& potential_extension_libraries_;
 
   Class& pragma_class_;
 
diff --git a/runtime/vm/libfuzzer/dart_libfuzzer.cc b/runtime/vm/libfuzzer/dart_libfuzzer.cc
index 5c870ab..a1cb53f 100644
--- a/runtime/vm/libfuzzer/dart_libfuzzer.cc
+++ b/runtime/vm/libfuzzer/dart_libfuzzer.cc
@@ -31,7 +31,7 @@
 }
 
 // Target function that stresses various utilities.
-// Found: http:/dartbug.com/36818
+// Found: http://dartbug.com/36818
 static int TestUtilities(const uint8_t* Data, size_t Size) {
   dart::Utils::StringHash(reinterpret_cast<const char*>(Data), Size);
   dart::bin::DartUtils::SniffForMagicNumber(Data, Size);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 19ceac8..9ad6cd4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4,6 +4,8 @@
 
 #include "vm/object.h"
 
+#include <memory>
+
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "platform/unicode.h"
@@ -2274,6 +2276,7 @@
 }
 
 RawAbstractType* Class::RareType() const {
+  ASSERT(is_declaration_loaded());
   const Type& type = Type::Handle(Type::New(
       *this, Object::null_type_arguments(), TokenPosition::kNoSource));
   return ClassFinalizer::FinalizeType(*this, type);
@@ -2292,6 +2295,7 @@
   FakeObject fake;
   result.set_handle_vtable(fake.vtable());
   result.set_token_pos(TokenPosition::kNoSource);
+  result.set_end_token_pos(TokenPosition::kNoSource);
   result.set_instance_size(FakeObject::InstanceSize());
   result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
   result.set_next_field_offset(FakeObject::NextFieldOffset());
@@ -3382,10 +3386,7 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
-  const Error& error = Error::Handle(zone, EnsureIsFinalized(thread));
-  if (!error.IsNull()) {
-    return error.raw();
-  }
+  CHECK_ERROR(EnsureIsFinalized(thread));
 
   // Check for real fields and user-defined setters.
   const Field& field = Field::Handle(zone, LookupStaticField(setter_name));
@@ -3542,6 +3543,21 @@
       arguments, type_arguments);
 }
 
+void Class::EnsureDeclarationLoaded() const {
+  if (!is_declaration_loaded()) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+    UNREACHABLE();
+#else
+    // Loading of class declaration can be postponed until needed
+    // if class comes from bytecode.
+    ASSERT(is_declared_in_bytecode());
+    kernel::BytecodeReader::LoadClassDeclaration(*this);
+    ASSERT(is_declaration_loaded());
+    ASSERT(is_type_finalized());
+#endif
+  }
+}
+
 // Ensure that top level parsing of the class has been done.
 RawError* Class::EnsureIsFinalized(Thread* thread) const {
   // Finalized classes have already been parsed.
@@ -3660,6 +3676,7 @@
   ASSERT(fake.IsInstance());
   result.set_handle_vtable(fake.vtable());
   result.set_token_pos(TokenPosition::kNoSource);
+  result.set_end_token_pos(TokenPosition::kNoSource);
   result.set_instance_size(FakeInstance::InstanceSize());
   result.set_type_arguments_field_offset_in_words(kNoTypeArguments);
   result.set_next_field_offset(FakeInstance::NextFieldOffset());
@@ -3975,69 +3992,16 @@
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
-TokenPosition Class::ComputeEndTokenPos() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  return TokenPosition::kNoSource;
-#else
-  // Return the begin token for synthetic classes.
-  if (is_synthesized_class() || IsTopLevel()) {
-    return token_pos();
-  }
-
-  Thread* thread = Thread::Current();
-  Zone* zone = thread->zone();
-  const Script& scr = Script::Handle(zone, script());
-  ASSERT(!scr.IsNull());
-
-  if (scr.kind() == RawScript::kKernelTag) {
-    if (is_declared_in_bytecode()) {
-      // TODO(alexmarkov): keep end_token_pos in Class?
-      UNIMPLEMENTED();
-      return token_pos();
-    }
-    ASSERT(kernel_offset() > 0);
-    const Library& lib = Library::Handle(zone, library());
-    const ExternalTypedData& kernel_data =
-        ExternalTypedData::Handle(zone, lib.kernel_data());
-    ASSERT(!kernel_data.IsNull());
-    const intptr_t library_kernel_offset = lib.kernel_offset();
-    ASSERT(library_kernel_offset > 0);
-    const intptr_t class_offset = kernel_offset();
-
-    kernel::TranslationHelper translation_helper(thread);
-    translation_helper.InitFromScript(scr);
-
-    kernel::KernelReaderHelper kernel_reader_helper(zone, &translation_helper,
-                                                    scr, kernel_data, 0);
-    kernel_reader_helper.SetOffset(class_offset);
-    kernel::ClassHelper class_helper(&kernel_reader_helper);
-    class_helper.ReadUntilIncluding(kernel::ClassHelper::kEndPosition);
-    if (class_helper.end_position_.IsReal()) return class_helper.end_position_;
-
-    TokenPosition largest_seen = token_pos();
-
-    // Walk through all functions and get their end_tokens to find the classes
-    // "end token".
-    // TODO(jensj): Should probably walk though all fields as well.
-    Function& function = Function::Handle(zone);
-    const Array& arr = Array::Handle(functions());
-    for (int i = 0; i < arr.Length(); i++) {
-      function ^= arr.At(i);
-      if (function.script() == script()) {
-        if (largest_seen < function.end_token_pos()) {
-          largest_seen = function.end_token_pos();
-        }
-      }
-    }
-    return TokenPosition(largest_seen);
-  }
-
-  UNREACHABLE();
-#endif
+void Class::set_end_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
+  StoreNonPointer(&raw_ptr()->end_token_pos_, token_pos);
 }
 
 int32_t Class::SourceFingerprint() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
+  if (is_declared_in_bytecode()) {
+    return 0;  // TODO(37353): Implement or remove.
+  }
   return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint(
       *this);
 #else
@@ -4186,6 +4150,7 @@
 }
 
 RawType* Class::DeclarationType() const {
+  ASSERT(is_declaration_loaded());
   if (declaration_type() != Type::null()) {
     return declaration_type();
   }
@@ -5747,6 +5712,7 @@
 }
 
 void Function::EnsureHasCompiledUnoptimizedCode() const {
+  ASSERT(!ForceOptimize());
   Thread* thread = Thread::Current();
   ASSERT(thread->IsMutatorThread());
   DEBUG_ASSERT(thread->TopErrorHandlerIsExitFrame());
@@ -6075,6 +6041,20 @@
   FfiTrampolineData::Cast(obj).set_callback_target(target);
 }
 
+RawInstance* Function::FfiCallbackExceptionalReturn() const {
+  ASSERT(IsFfiTrampoline());
+  const Object& obj = Object::Handle(raw_ptr()->data_);
+  ASSERT(!obj.IsNull());
+  return FfiTrampolineData::Cast(obj).callback_exceptional_return();
+}
+
+void Function::SetFfiCallbackExceptionalReturn(const Instance& value) const {
+  ASSERT(IsFfiTrampoline());
+  const Object& obj = Object::Handle(raw_ptr()->data_);
+  ASSERT(!obj.IsNull());
+  FfiTrampolineData::Cast(obj).set_callback_exceptional_return(value);
+}
+
 RawType* Function::SignatureType() const {
   Type& type = Type::Handle(ExistingSignatureType());
   if (type.IsNull()) {
@@ -7797,7 +7777,8 @@
 
 intptr_t Function::KernelDataProgramOffset() const {
   ASSERT(!is_declared_in_bytecode());
-  if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher()) {
+  if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher() ||
+      IsFfiTrampoline()) {
     return 0;
   }
   Object& data = Object::Handle(raw_ptr()->data_);
@@ -7942,6 +7923,9 @@
 // arguments.
 int32_t Function::SourceFingerprint() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
+  if (is_declared_in_bytecode()) {
+    return 0;  // TODO(37353): Implement or remove.
+  }
   return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
       *this);
 #else
@@ -8095,7 +8079,7 @@
   }
   // Compiling in unoptimized mode should never fail if there are no errors.
   ASSERT(HasCode());
-  ASSERT(unoptimized_code() == result.raw());
+  ASSERT(ForceOptimize() || unoptimized_code() == result.raw());
   return CurrentCode();
 }
 
@@ -8288,6 +8272,11 @@
   StoreNonPointer(&raw_ptr()->callback_id_, callback_id);
 }
 
+void FfiTrampolineData::set_callback_exceptional_return(
+    const Instance& value) const {
+  StorePointer(&raw_ptr()->callback_exceptional_return_, value.raw());
+}
+
 RawFfiTrampolineData* FfiTrampolineData::New() {
   ASSERT(Object::ffi_trampoline_data_class() != Class::null());
   RawObject* raw =
@@ -8587,6 +8576,9 @@
 
 int32_t Field::SourceFingerprint() const {
 #if !defined(DART_PRECOMPILED_RUNTIME)
+  if (is_declared_in_bytecode()) {
+    return 0;  // TODO(37353): Implement or remove.
+  }
   return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint(
       *this);
 #else
@@ -11334,7 +11326,7 @@
       String::New("Expression evaluation not available in precompiled mode."));
   return ApiError::New(error_str);
 #else
-  kernel::Program* kernel_pgm =
+  std::unique_ptr<kernel::Program> kernel_pgm =
       kernel::Program::ReadFromBuffer(kernel_bytes, kernel_length);
 
   if (kernel_pgm == NULL) {
@@ -11342,12 +11334,11 @@
         String::New("Kernel isolate returned ill-formed kernel.")));
   }
 
-  kernel::KernelLoader loader(kernel_pgm, /*uri_to_source_table=*/nullptr);
+  kernel::KernelLoader loader(kernel_pgm.get(),
+                              /*uri_to_source_table=*/nullptr);
   const Object& result = Object::Handle(
       loader.LoadExpressionEvaluationFunction(library_url, klass));
-
-  delete kernel_pgm;
-  kernel_pgm = NULL;
+  kernel_pgm.reset();
 
   if (result.IsError()) return result.raw();
 
@@ -12149,6 +12140,11 @@
   StorePointer(&raw_ptr()->constants_table_, value.raw());
 }
 
+void KernelProgramInfo::set_evaluating(
+    const GrowableObjectArray& evaluating) const {
+  StorePointer(&raw_ptr()->evaluating_, evaluating.raw());
+}
+
 void KernelProgramInfo::set_potential_natives(
     const GrowableObjectArray& candidates) const {
   StorePointer(&raw_ptr()->potential_natives_, candidates.raw());
@@ -14476,6 +14472,10 @@
   set_state_bits(OptimizedBit::update(value, raw_ptr()->state_bits_));
 }
 
+void Code::set_is_force_optimized(bool value) const {
+  set_state_bits(ForceOptimizedBit::update(value, raw_ptr()->state_bits_));
+}
+
 void Code::set_is_alive(bool value) const {
   set_state_bits(AliveBit::update(value, raw_ptr()->state_bits_));
 }
@@ -14749,6 +14749,7 @@
     result ^= raw;
     result.set_pointer_offsets_length(pointer_offsets_length);
     result.set_is_optimized(false);
+    result.set_is_force_optimized(false);
     result.set_is_alive(false);
     NOT_IN_PRODUCT(result.set_comments(Comments::New(0)));
     NOT_IN_PRODUCT(result.set_compile_timestamp(0));
@@ -14938,6 +14939,20 @@
   return code.raw();
 }
 
+void Code::NotifyCodeObservers(const Code& code, bool optimized) {
+#if !defined(PRODUCT)
+  ASSERT(!Thread::Current()->IsAtSafepoint());
+  if (CodeObservers::AreActive()) {
+    const Object& owner = Object::Handle(code.owner());
+    if (owner.IsFunction()) {
+      NotifyCodeObservers(Function::Cast(owner), code, optimized);
+    } else {
+      NotifyCodeObservers(code.Name(), code, optimized);
+    }
+  }
+#endif
+}
+
 void Code::NotifyCodeObservers(const Function& function,
                                const Code& code,
                                bool optimized) {
@@ -15296,21 +15311,21 @@
   return info.metadata_payloads();
 }
 
-TokenPosition Bytecode::GetTokenIndexOfPC(uword pc) const {
+TokenPosition Bytecode::GetTokenIndexOfPC(uword return_address) const {
 #if defined(DART_PRECOMPILED_RUNTIME)
   UNREACHABLE();
 #else
   if (!HasSourcePositions()) {
     return TokenPosition::kNoSource;
   }
-  uword pc_offset = pc - PayloadStart();
+  uword pc_offset = return_address - PayloadStart();
   // PC could equal to bytecode size if the last instruction is Throw.
   ASSERT(pc_offset <= static_cast<uword>(Size()));
   kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(),
                                                *this);
   TokenPosition token_pos = TokenPosition::kNoSource;
   while (iter.MoveNext()) {
-    if (pc_offset < iter.PcOffset()) {
+    if (pc_offset <= iter.PcOffset()) {
       break;
     }
     token_pos = iter.TokenPos();
@@ -16152,9 +16167,11 @@
 RawObject* Instance::InvokeGetter(const String& getter_name,
                                   bool respect_reflectable,
                                   bool check_is_entrypoint) const {
-  Zone* zone = Thread::Current()->zone();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
 
   Class& klass = Class::Handle(zone, clazz());
+  CHECK_ERROR(klass.EnsureIsFinalized(thread));
   TypeArguments& type_args = TypeArguments::Handle(zone);
   if (klass.NumTypeArguments() > 0) {
     type_args = GetTypeArguments();
@@ -16210,9 +16227,11 @@
                                   const Instance& value,
                                   bool respect_reflectable,
                                   bool check_is_entrypoint) const {
-  Zone* zone = Thread::Current()->zone();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
 
   const Class& klass = Class::Handle(zone, clazz());
+  CHECK_ERROR(klass.EnsureIsFinalized(thread));
   TypeArguments& type_args = TypeArguments::Handle(zone);
   if (klass.NumTypeArguments() > 0) {
     type_args = GetTypeArguments();
@@ -16255,8 +16274,10 @@
                             const Array& arg_names,
                             bool respect_reflectable,
                             bool check_is_entrypoint) const {
-  Zone* zone = Thread::Current()->zone();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   Class& klass = Class::Handle(zone, clazz());
+  CHECK_ERROR(klass.EnsureIsFinalized(thread));
   Function& function = Function::Handle(
       zone, Resolver::ResolveDynamicAnyArgs(zone, klass, function_name));
 
@@ -16382,7 +16403,7 @@
   NoSafepointScope no_safepoint;
   const intptr_t instance_size = SizeFromClass();
   ASSERT(instance_size != 0);
-  uint32_t hash = instance_size;
+  uint32_t hash = instance_size / kWordSize;
   uword this_addr = reinterpret_cast<uword>(this->raw_ptr());
   Instance& member = Instance::Handle();
   for (intptr_t offset = Instance::NextFieldOffset(); offset < instance_size;
@@ -16455,6 +16476,10 @@
   return true;
 }
 
+RawInstance* Instance::CopyShallowToOldSpace(Thread* thread) const {
+  return Instance::RawCast(Object::Clone(*this, Heap::kOld));
+}
+
 RawInstance* Instance::CheckAndCanonicalize(Thread* thread,
                                             const char** error_str) const {
   ASSERT(error_str != NULL);
@@ -16506,6 +16531,12 @@
     return Type::NullType();
   }
   const Class& cls = Class::Handle(clazz());
+  if (!cls.is_finalized()) {
+    // Various predefined classes can be instantiated by the VM or
+    // Dart_NewString/Integer/TypedData/... before the class is finalized.
+    ASSERT(cls.is_prefinalized());
+    cls.EnsureDeclarationLoaded();
+  }
   if (cls.IsClosureClass()) {
     Function& signature =
         Function::Handle(Closure::Cast(*this).GetInstantiatedSignature(
@@ -17242,6 +17273,10 @@
   return !IsFunctionType() && (type_class_id() == kClosureCid);
 }
 
+bool AbstractType::IsFfiPointerType() const {
+  return HasTypeClass() && type_class_id() == kFfiPointerCid;
+}
+
 bool AbstractType::IsSubtypeOf(const AbstractType& other,
                                Heap::Space space) const {
   ASSERT(IsFinalized());
@@ -17712,14 +17747,7 @@
         for (intptr_t i = 0; i < from_index; i++) {
           type_arg = type_args.TypeAt(i);
           other_type_arg = other_type_args.TypeAt(i);
-          // Type arguments may not match if they are TypeRefs without
-          // underlying type (which will be set later).
-          ASSERT(
-              type_arg.IsEquivalent(other_type_arg, trail) ||
-              (type_arg.IsTypeRef() &&
-               TypeRef::Cast(type_arg).type() == AbstractType::null()) ||
-              (other_type_arg.IsTypeRef() &&
-               TypeRef::Cast(other_type_arg).type() == AbstractType::null()));
+          ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
         }
       }
 #endif
@@ -18178,10 +18206,9 @@
   // TODO(regis): Try to reduce the number of nodes required to represent the
   // referenced recursive type.
   AbstractType& ref_type = AbstractType::Handle(type());
-  if (!ref_type.IsNull()) {
-    ref_type = ref_type.Canonicalize(trail);
-    set_type(ref_type);
-  }
+  ASSERT(!ref_type.IsNull());
+  ref_type = ref_type.Canonicalize(trail);
+  set_type(ref_type);
   return raw();
 }
 
@@ -18207,11 +18234,15 @@
 }
 
 intptr_t TypeRef::Hash() const {
-  // Do not calculate the hash of the referenced type to avoid divergence.
-  // TypeRef can participate in type canonicalization even before referenced
-  // type is set, so its hash should not rely on referenced type.
-  const intptr_t kTypeRefHash = 37;
-  return kTypeRefHash;
+  // Do not use hash of the referenced type because
+  //  - we could be in process of calculating it (as TypeRef is used to
+  //    represent recursive references to types).
+  //  - referenced type might be incomplete (e.g. not all its
+  //    type arguments are set).
+  const AbstractType& ref_type = AbstractType::Handle(type());
+  ASSERT(!ref_type.IsNull());
+  const uint32_t result = Class::Handle(ref_type.type_class()).id();
+  return FinalizeHash(result, kHashBits);
 }
 
 RawTypeRef* TypeRef::New() {
@@ -21366,24 +21397,24 @@
 }
 
 RawPointer* Pointer::New(const AbstractType& type_arg,
-                         const Integer& c_memory_address,
-                         intptr_t cid,
+                         size_t native_address,
                          Heap::Space space) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
+
   TypeArguments& type_args = TypeArguments::Handle(zone);
   type_args = TypeArguments::New(1);
   type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
   type_args = type_args.Canonicalize();
 
-  const Class& cls = Class::Handle(Isolate::Current()->class_table()->At(cid));
+  const Class& cls =
+      Class::Handle(Isolate::Current()->class_table()->At(kFfiPointerCid));
   cls.EnsureIsFinalized(Thread::Current());
 
   Pointer& result = Pointer::Handle(zone);
-  result ^= Object::Allocate(cid, Pointer::InstanceSize(), space);
-  NoSafepointScope no_safepoint;
+  result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
   result.SetTypeArguments(type_args);
-  result.SetCMemoryAddress(c_memory_address);
+  result.SetNativeAddress(native_address);
 
   return result.raw();
 }
@@ -21392,9 +21423,7 @@
   TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
   String& type_args_name = String::Handle(type_args.UserVisibleName());
   return OS::SCreate(Thread::Current()->zone(), "Pointer%s: address=0x%" Px,
-                     type_args_name.ToCString(),
-                     static_cast<intptr_t>(
-                         Integer::Handle(GetCMemoryAddress()).AsInt64Value()));
+                     type_args_name.ToCString(), NativeAddress());
 }
 
 RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {
@@ -21408,23 +21437,7 @@
 
 bool Pointer::IsPointer(const Instance& obj) {
   ASSERT(!obj.IsNull());
-
-  // fast path for predefined classes
-  intptr_t cid = obj.raw()->GetClassId();
-  if (RawObject::IsFfiPointerClassId(cid)) {
-    return true;
-  }
-
-  // slow check for subtyping
-  const Class& pointer_class = Class::ZoneHandle(
-      Isolate::Current()->object_store()->ffi_pointer_class());
-  AbstractType& pointer_type =
-      AbstractType::Handle(pointer_class.DeclarationType());
-  pointer_type = pointer_type.InstantiateFrom(Object::null_type_arguments(),
-                                              Object::null_type_arguments(),
-                                              kNoneFree, NULL, Heap::kNew);
-  AbstractType& type = AbstractType::Handle(obj.GetType(Heap::kNew));
-  return type.IsSubtypeOf(pointer_type, Heap::kNew);
+  return RawObject::IsFfiPointerClassId(obj.raw()->GetClassId());
 }
 
 bool Instance::IsPointer() const {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 58eacf7..2411db7 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -866,8 +866,11 @@
 
   TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   void set_token_pos(TokenPosition value) const;
-
-  TokenPosition ComputeEndTokenPos() const;
+  TokenPosition end_token_pos() const {
+    ASSERT(is_declaration_loaded());
+    return raw_ptr()->end_token_pos_;
+  }
+  void set_end_token_pos(TokenPosition value) const;
 
   int32_t SourceFingerprint() const;
 
@@ -1306,6 +1309,10 @@
       const Array& param_values,
       const TypeArguments& type_param_values) const;
 
+  // Load class declaration (super type, interfaces, type parameters and
+  // number of type arguments) if it is not loaded yet.
+  void EnsureDeclarationLoaded() const;
+
   RawError* EnsureIsFinalized(Thread* thread) const;
 
   // Allocate a class used for VM internal objects.
@@ -2118,6 +2125,13 @@
   // Can only be called on FFI trampolines.
   void SetFfiCallbackTarget(const Function& target) const;
 
+  // Can only be called on FFI trampolines.
+  // Null for Dart -> native calls.
+  RawInstance* FfiCallbackExceptionalReturn() const;
+
+  // Can only be called on FFI trampolines.
+  void SetFfiCallbackExceptionalReturn(const Instance& value) const;
+
   // Return a new function with instantiated result and parameter types.
   RawFunction* InstantiateSignatureFrom(
       const TypeArguments& instantiator_type_arguments,
@@ -3257,6 +3271,11 @@
   RawFunction* callback_target() const { return raw_ptr()->callback_target_; }
   void set_callback_target(const Function& value) const;
 
+  RawInstance* callback_exceptional_return() const {
+    return raw_ptr()->callback_exceptional_return_;
+  }
+  void set_callback_exceptional_return(const Instance& value) const;
+
   int32_t callback_id() const { return raw_ptr()->callback_id_; }
   void set_callback_id(int32_t value) const;
 
@@ -4402,6 +4421,10 @@
   RawArray* constants() const { return raw_ptr()->constants_; }
   void set_constants(const Array& constants) const;
 
+  // Records libraries under evaluation to break evaluation cycles.
+  RawGrowableObjectArray* evaluating() const { return raw_ptr()->evaluating_; }
+  void set_evaluating(const GrowableObjectArray& evaluating) const;
+
   // If we load a kernel blob with evaluated constants, then we delay setting
   // the native names of [Function] objects until we've read the constant table
   // (since native names are encoded as constants).
@@ -4555,7 +4578,8 @@
   // Returns the pool index from the offset relative to a tagged RawObjectPool*,
   // adjusting for the tag-bit.
   static intptr_t IndexFromOffset(intptr_t offset) {
-    ASSERT(Utils::IsAligned(offset + kHeapObjectTag, kWordSize));
+    ASSERT(
+        Utils::IsAligned(offset + kHeapObjectTag, compiler::target::kWordSize));
     return (offset + kHeapObjectTag - data_offset()) /
            sizeof(RawObjectPool::Entry);
   }
@@ -4712,7 +4736,9 @@
   static intptr_t HeaderSize() {
     intptr_t alignment = OS::PreferredCodeAlignment();
     intptr_t aligned_size = Utils::RoundUp(sizeof(RawInstructions), alignment);
+#if !defined(IS_SIMARM_X64)
     ASSERT(aligned_size == alignment);
+#endif  // !defined(IS_SIMARM_X64)
     return aligned_size;
   }
 
@@ -5193,6 +5219,14 @@
     return Code::OptimizedBit::decode(code->ptr()->state_bits_);
   }
 
+  bool is_force_optimized() const {
+    return ForceOptimizedBit::decode(raw_ptr()->state_bits_);
+  }
+  void set_is_force_optimized(bool value) const;
+  static bool IsForceOptimized(RawCode* code) {
+    return Code::ForceOptimizedBit::decode(code->ptr()->state_bits_);
+  }
+
   bool is_alive() const { return AliveBit::decode(raw_ptr()->state_bits_); }
   void set_is_alive(bool value) const;
 
@@ -5424,6 +5458,9 @@
     StorePointer(&raw_ptr()->exception_handlers_, handlers.raw());
   }
 
+  // WARNING: function() returns the owner which is not guaranteed to be
+  // a Function. It is up to the caller to guarantee it isn't a stub, class,
+  // or something else.
   // TODO(turnidge): Consider dropping this function and making
   // everybody use owner().  Currently this function is misused - even
   // while generating the snapshot.
@@ -5470,6 +5507,7 @@
                                CodeStatistics* stats);
 
   // Notifies all active [CodeObserver]s.
+  static void NotifyCodeObservers(const Code& code, bool optimized);
   static void NotifyCodeObservers(const Function& function,
                                   const Code& code,
                                   bool optimized);
@@ -5546,12 +5584,19 @@
   friend class RawCode;
   enum {
     kOptimizedBit = 0,
-    kAliveBit = 1,
-    kPtrOffBit = 2,
-    kPtrOffSize = 30,
+    kForceOptimizedBit = 1,
+    kAliveBit = 2,
+    kPtrOffBit = 3,
+    kPtrOffSize = 29,
   };
 
   class OptimizedBit : public BitField<int32_t, bool, kOptimizedBit, 1> {};
+
+  // Force-optimized is true if the Code was generated for a function with
+  // Function::ForceOptimize().
+  class ForceOptimizedBit
+      : public BitField<int32_t, bool, kForceOptimizedBit, 1> {};
+
   class AliveBit : public BitField<int32_t, bool, kAliveBit, 1> {};
   class PtrOffBits
       : public BitField<int32_t, intptr_t, kPtrOffBit, kPtrOffSize> {};
@@ -5681,7 +5726,7 @@
 
   RawExternalTypedData* GetBinary(Zone* zone) const;
 
-  TokenPosition GetTokenIndexOfPC(uword pc) const;
+  TokenPosition GetTokenIndexOfPC(uword return_address) const;
   intptr_t GetTryIndexAtPc(uword return_address) const;
 
   intptr_t instructions_binary_offset() const {
@@ -6225,6 +6270,8 @@
   virtual bool CheckAndCanonicalizeFields(Thread* thread,
                                           const char** error_str) const;
 
+  RawInstance* CopyShallowToOldSpace(Thread* thread) const;
+
 #if defined(DEBUG)
   // Check if instance is canonical.
   virtual bool CheckIsCanonical(Thread* thread) const;
@@ -6795,6 +6842,9 @@
   // Check if this type represents the Dart '_Closure' type.
   bool IsDartClosureType() const;
 
+  // Check if this type represents the 'Pointer' type from "dart:ffi".
+  bool IsFfiPointerType() const;
+
   // Check the subtype relationship.
   bool IsSubtypeOf(const AbstractType& other, Heap::Space space) const;
 
@@ -7282,9 +7332,7 @@
     return reinterpret_cast<intptr_t>(New(value));
   }
 
-  static bool IsValid(int64_t value) {
-    return (value >= kMinValue) && (value <= kMaxValue);
-  }
+  static bool IsValid(int64_t value) { return compiler::target::IsSmi(value); }
 
   void operator=(RawSmi* value) {
     raw_ = value;
@@ -9040,8 +9088,7 @@
 class Pointer : public Instance {
  public:
   static RawPointer* New(const AbstractType& type_arg,
-                         const Integer& c_memory_address,
-                         intptr_t class_id = kFfiPointerCid,
+                         uword native_address,
                          Heap::Space space = Heap::kNew);
 
   static intptr_t InstanceSize() {
@@ -9050,10 +9097,12 @@
 
   static bool IsPointer(const Instance& obj);
 
-  RawInteger* GetCMemoryAddress() const { return raw_ptr()->c_memory_address_; }
+  size_t NativeAddress() const {
+    return Integer::Handle(raw_ptr()->c_memory_address_).AsInt64Value();
+  }
 
-  void SetCMemoryAddress(const Integer& value) const {
-    StorePointer(&raw_ptr()->c_memory_address_, value.raw());
+  void SetNativeAddress(size_t address) const {
+    StorePointer(&raw_ptr()->c_memory_address_, Integer::New(address));
   }
 
   static intptr_t type_arguments_offset() {
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 0dba671..51d3365 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -102,9 +102,18 @@
   if (!owner.IsFunction()) {
     return;  // No switchable calls in stub code.
   }
+  const Function& function = Function::Cast(owner);
 
-  const Array& ic_data_array =
-      Array::Handle(zone, Function::Cast(owner).ic_data_array());
+  if (function.kind() == RawFunction::kIrregexpFunction) {
+    // Regex matchers do not support breakpoints or stepping, and they only call
+    // core library functions that cannot change due to reload. As a performance
+    // optimization, avoid this matching of ICData to PCs for these functions'
+    // large number of instance calls.
+    ASSERT(!function.is_debuggable());
+    return;
+  }
+
+  const Array& ic_data_array = Array::Handle(zone, function.ic_data_array());
   if (ic_data_array.IsNull()) {
     // The megamorphic miss stub and some recognized function doesn't populate
     // their ic_data_array. Check this only happens for functions without IC
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3786d8e..2ba49c8 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -116,7 +116,7 @@
   jsobj.AddProperty("library", Object::Handle(library()));
   const Script& script = Script::Handle(this->script());
   if (!script.IsNull()) {
-    jsobj.AddLocation(script, token_pos(), ComputeEndTokenPos());
+    jsobj.AddLocation(script, token_pos(), end_token_pos());
   }
   {
     JSONArray interfaces_array(&jsobj, "interfaces");
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 47c461e..8294709 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -140,7 +140,7 @@
   set_linked_hash_set_class(cls);
 
 #ifdef DART_PRECOMPILED_RUNTIME
-  // These objects are only needed for code generation.
+  // The rest of these objects are only needed for code generation.
   return;
 #else
   Isolate* isolate = thread->isolate();
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index d3277a4..f0ded97 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -143,6 +143,8 @@
   RW(GrowableObjectArray, changed_in_last_reload)                              \
   RW(Class, ffi_pointer_class)                                                 \
   RW(Class, ffi_native_type_class)                                             \
+  RW(Class, ffi_struct_class)                                                  \
+  RW(Object, ffi_as_function_internal)                                         \
 // Please remember the last entry must be referred in the 'to' function below.
 
 // The object store is a per isolate instance which stores references to
@@ -235,7 +237,7 @@
                           DECLARE_OBJECT_STORE_FIELD)
 #undef DECLARE_OBJECT_STORE_FIELD
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ffi_pointer_class_);
+    return reinterpret_cast<RawObject**>(&ffi_as_function_internal_);
   }
   RawObject** to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 0921cc8..8e66ed7 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -168,7 +168,7 @@
   EXPECT_EQ(type_arguments1.raw(), type_arguments3.raw());
 }
 
-TEST_CASE(Class_ComputeEndTokenPos) {
+TEST_CASE(Class_EndTokenPos) {
   const char* kScript =
       "\n"
       "class A {\n"
@@ -178,7 +178,6 @@
       "  foo(a) { return '''\"}'''; }\n"
       "  // }\n"
       "  var bar = '\\'}';\n"
-      "  var baz = \"${foo('}')}\";\n"
       "}\n";
   Dart_Handle lib_h = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib_h);
@@ -189,12 +188,15 @@
   const Class& cls =
       Class::Handle(lib.LookupClass(String::Handle(String::New("A"))));
   EXPECT(!cls.IsNull());
-  const TokenPosition end_token_pos = cls.ComputeEndTokenPos();
+  const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
+  EXPECT(error.IsNull());
+  const TokenPosition end_token_pos = cls.end_token_pos();
   const Script& scr = Script::Handle(cls.script());
   intptr_t line;
   intptr_t col;
   scr.GetTokenLocation(end_token_pos, &line, &col);
-  EXPECT(line == 10 && col == 1);
+  EXPECT_EQ(9, line);
+  EXPECT_EQ(1, col);
 }
 
 ISOLATE_UNIT_TEST_CASE(InstanceClass) {
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 517f3c4..efde807 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -90,7 +90,7 @@
 int OS::GetLocalTimeZoneAdjustmentInSeconds() {
   int32_t local_offset, dst_offset;
   zx_time_t now = 0;
-  zx_clock_get_new(ZX_CLOCK_UTC, &now);
+  zx_clock_get(ZX_CLOCK_UTC, &now);
   zx_status_t status = GetLocalAndDstOffsetInSeconds(
       now / ZX_SEC(1), &local_offset, &dst_offset);
   return status == ZX_OK ? local_offset : 0;
@@ -102,7 +102,7 @@
 
 int64_t OS::GetCurrentTimeMicros() {
   zx_time_t now = 0;
-  zx_clock_get_new(ZX_CLOCK_UTC, &now);
+  zx_clock_get(ZX_CLOCK_UTC, &now);
   return now / kNanosecondsPerMicrosecond;
 }
 
@@ -122,7 +122,7 @@
 
 int64_t OS::GetCurrentThreadCPUMicros() {
   zx_time_t now = 0;
-  zx_clock_get_new(ZX_CLOCK_THREAD, &now);
+  zx_clock_get(ZX_CLOCK_THREAD, &now);
   return now / kNanosecondsPerMicrosecond;
 }
 
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 4ad4340..0b580dd 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -4,6 +4,8 @@
 
 #include "vm/port.h"
 
+#include <utility>
+
 #include "platform/utils.h"
 #include "vm/dart_api_impl.h"
 #include "vm/dart_entry.h"
@@ -82,14 +84,20 @@
 }
 
 Dart_Port PortMap::AllocatePort() {
-  const Dart_Port kMASK = 0x3fffffff;
-  Dart_Port result = prng_->NextUInt32() & kMASK;
+  Dart_Port result;
 
   // Keep getting new values while we have an illegal port number or the port
   // number is already in use.
-  while ((result == 0) || (FindPort(result) >= 0)) {
-    result = prng_->NextUInt32() & kMASK;
-  }
+  do {
+    // Ensure port ids are representable in JavaScript for the benefit of
+    // vm-service clients such as Observatory.
+    const Dart_Port kMask1 = 0xFFFFFFFFFFFFF;
+    // Ensure port ids are never valid object pointers so that reinterpreting
+    // an object pointer as a port id never produces a used port id.
+    const Dart_Port kMask2 = 0x3;
+    result = (prng_->NextUInt64() & kMask1) | kMask2;
+    ASSERT(!reinterpret_cast<RawObject*>(result)->IsWellFormed());
+  } while (FindPort(result) >= 0);
 
   ASSERT(result != 0);
   ASSERT(FindPort(result) < 0);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 97153de..d3a1450 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1615,16 +1615,13 @@
     ASSERT(function != NULL);
     const intptr_t code_index = profile_code->code_table_index();
     ASSERT(profile_code != NULL);
-    Code& code = Code::ZoneHandle();
-    if (profile_code->code().IsCode()) {
-      code ^= profile_code->code().raw();
-    } else {
-      // No inlining in bytecode.
-    }
+
     GrowableArray<const Function*>* inlined_functions = NULL;
     GrowableArray<TokenPosition>* inlined_token_positions = NULL;
     TokenPosition token_position = TokenPosition::kNoSource;
-    if (!code.IsNull()) {
+    Code& code = Code::ZoneHandle();
+    if (profile_code->code().IsCode()) {
+      code ^= profile_code->code().raw();
       inlined_functions_cache_.Get(pc, code, sample, frame_index,
                                    &inlined_functions, &inlined_token_positions,
                                    &token_position);
@@ -1637,6 +1634,11 @@
                     (*inlined_token_positions)[i].ToCString());
         }
       }
+    } else if (profile_code->code().IsBytecode()) {
+      // No inlining in bytecode.
+      const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(),
+                                                   profile_code->code().raw());
+      token_position = bc.GetTokenIndexOfPC(pc);
     }
 
     if (code.IsNull() || (inlined_functions == NULL) ||
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 1cb8236..25ae272 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -280,23 +280,37 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
 
     // Inclusive code: main -> B.boo.
     walker.Reset(Profile::kInclusiveCode);
     // Move down from the root.
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
 
@@ -306,8 +320,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -321,8 +337,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -616,23 +634,37 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
 
     // Inclusive code: main -> B.boo.
     walker.Reset(Profile::kInclusiveCode);
     // Move down from the root.
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
 
@@ -642,8 +674,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
     EXPECT_STREQ("main", walker.CurrentName());
@@ -657,8 +691,10 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -744,35 +780,59 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentNodeTickCount());
-    EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentNodeTickCount());
-    EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(0, walker.CurrentExclusiveTicks());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+      EXPECT(!walker.Down());
+    }
 
     // Inclusive code: main -> B.boo.
     walker.Reset(Profile::kInclusiveCode);
     // Move down from the root.
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentNodeTickCount());
-    EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT_EQ(0, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentNodeTickCount());
-    EXPECT_EQ(3, walker.CurrentInclusiveTicks());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT(walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT_EQ(0, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentNodeTickCount());
+      EXPECT_EQ(3, walker.CurrentInclusiveTicks());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -841,9 +901,11 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
@@ -867,9 +929,11 @@
     EXPECT_EQ(3, walker.CurrentNodeTickCount());
     EXPECT_EQ(3, walker.CurrentInclusiveTicks());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(3, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(3, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -921,14 +985,21 @@
 
     walker.Reset(Profile::kExclusiveCode);
     EXPECT(walker.Down());
-    EXPECT_STREQ("Double_add", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] _Double._add", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] _Double.+", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("Double_add", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] _Double._add", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] _Double.+", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   double_class.SetTraceAllocation(false);
@@ -988,12 +1059,19 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateArray", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] new _List", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   array_class.SetTraceAllocation(false);
@@ -1078,10 +1156,15 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateContext", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   context_class.SetTraceAllocation(false);
@@ -1142,8 +1225,10 @@
     EXPECT(walker.Down());
     EXPECT_SUBSTRING("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName());
+      EXPECT(walker.Down());
+    }
     EXPECT_SUBSTRING("foo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
@@ -1212,10 +1297,17 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("TypedData_Float32Array_new", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] new Float32List", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   float32_list_class.SetTraceAllocation(false);
@@ -1293,12 +1385,17 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("String_concat", walker.CurrentName());
     EXPECT(walker.Down());
-#if 1
-    EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName());
-    EXPECT(walker.Down());
-#endif
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] _StringBase.+", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   one_byte_string_class.SetTraceAllocation(false);
@@ -1376,17 +1473,29 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("OneByteString_allocate", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] _OneByteString._allocate",
-                 walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] _OneByteString._concatAll",
-                 walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] _StringBase._interpolate",
-                 walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] _OneByteString._allocate", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] _OneByteString._concatAll",
+                   walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] _StringBase._interpolate", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Unoptimized] _OneByteString._allocate",
+                   walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] _OneByteString._concatAll",
+                   walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] _StringBase._interpolate",
+                   walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 
   one_byte_string_class.SetTraceAllocation(false);
@@ -1421,6 +1530,7 @@
   DisableNativeProfileScope dnps;
   DisableBackgroundCompilationScope dbcs;
   SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
+  SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
 
   const char* kScript =
       "class A {\n"
@@ -1706,6 +1816,7 @@
   DisableNativeProfileScope dnps;
   DisableBackgroundCompilationScope dbcs;
   SetFlagScope<int> sfs(&FLAG_optimization_counter_threshold, 30000);
+  SetFlagScope<bool> sfs2(&FLAG_enable_interpreter, false);
 
   const char* kScript =
       "class A {\n"
@@ -1890,48 +2001,91 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] init", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] go", walker.CurrentName());
-    EXPECT(walker.Down());
-    EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
-    EXPECT(!walker.Down());
+    if (FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] orange", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] napkin", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] mayo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] lemon", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] kindle", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] jeep", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] ice", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] haystack", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] granola", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] fred", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] elephant", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] dog", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] cantaloupe", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] banana", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] apple", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] secondInit", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] init", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] go", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Bytecode] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    } else {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] init", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] go", walker.CurrentName());
+      EXPECT(walker.Down());
+      EXPECT_STREQ("[Unoptimized] main", walker.CurrentName());
+      EXPECT(!walker.Down());
+    }
   }
 }
 
@@ -1988,9 +2142,11 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2013,6 +2169,7 @@
   SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
   // Optimize quickly.
   SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+  SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
   const char* kScript =
       "const AlwaysInline = 'AlwaysInline';\n"
       "const NeverInline = 'NeverInline';\n"
@@ -2159,9 +2316,11 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2202,6 +2361,7 @@
   SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
   // Optimize quickly.
   SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+  SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
 
   const char* kScript =
       "const AlwaysInline = 'AlwaysInline';\n"
@@ -2382,9 +2542,11 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
@@ -2431,6 +2593,7 @@
   SetFlagScope<bool> sfs(&FLAG_enable_inlining_annotations, true);
   // Optimize quickly.
   SetFlagScope<int> sfs2(&FLAG_optimization_counter_threshold, 5);
+  SetFlagScope<bool> sfs3(&FLAG_enable_interpreter, false);
 
   const char* kScript =
       "const AlwaysInline = 'AlwaysInline';\n"
@@ -2511,9 +2674,11 @@
     EXPECT(walker.Down());
     EXPECT_STREQ("DRT_AllocateObject", walker.CurrentName());
     EXPECT(walker.Down());
-    EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
-    EXPECT_EQ(1, walker.CurrentExclusiveTicks());
-    EXPECT(walker.Down());
+    if (!FLAG_enable_interpreter) {
+      EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName());
+      EXPECT_EQ(1, walker.CurrentExclusiveTicks());
+      EXPECT(walker.Down());
+    }
     EXPECT_STREQ("B.boo", walker.CurrentName());
     EXPECT_EQ(1, walker.CurrentNodeTickCount());
     EXPECT_EQ(1, walker.CurrentInclusiveTicks());
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index e63d22b..029f91a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -174,15 +174,11 @@
         : public BitField<uint32_t, intptr_t, kSizeTagPos, kSizeTagSize> {};
 
     static intptr_t SizeToTagValue(intptr_t size) {
-      ASSERT(Utils::IsAligned(
-          size, compiler::target::ObjectAlignment::kObjectAlignment));
-      return (size > kMaxSizeTag)
-                 ? 0
-                 : (size >>
-                    compiler::target::ObjectAlignment::kObjectAlignmentLog2);
+      ASSERT(Utils::IsAligned(size, kObjectAlignment));
+      return (size > kMaxSizeTag) ? 0 : (size >> kObjectAlignmentLog2);
     }
     static intptr_t TagValueToSize(intptr_t value) {
-      return value << compiler::target::ObjectAlignment::kObjectAlignmentLog2;
+      return value << kObjectAlignmentLog2;
     }
   };
 
@@ -490,6 +486,10 @@
 #if defined(HASH_IN_OBJECT_HEADER)
   // On 64 bit there is a hash field in the header for the identity hash.
   uint32_t hash_;
+#elif defined(IS_SIMARM_X64)
+  // On simarm_x64 the hash isn't used, but we need the padding anyway so that
+  // the object layout fits assumptions made about X64.
+  uint32_t padding_;
 #endif
 
   // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
@@ -800,6 +800,7 @@
 
   cpp_vtable handle_vtable_;
   TokenPosition token_pos_;
+  TokenPosition end_token_pos_;
   int32_t instance_size_in_words_;  // Size if fixed len or 0 if variable len.
   int32_t type_arguments_field_offset_in_words_;  // Offset of type args fld.
   int32_t next_field_offset_in_words_;  // Offset of the next instance field.
@@ -1038,7 +1039,10 @@
   // Target Dart method for callbacks, otherwise null.
   RawFunction* callback_target_;
 
-  VISIT_TO(RawObject*, callback_target_);
+  // For callbacks, value to return if Dart target throws an exception.
+  RawInstance* callback_exceptional_return_;
+
+  VISIT_TO(RawObject*, callback_exceptional_return_);
   RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
 
   // Callback id for callbacks.
@@ -1258,13 +1262,14 @@
   RawArray* bytecode_component_;
   RawGrowableObjectArray* potential_natives_;
   RawGrowableObjectArray* potential_pragma_functions_;
+  RawGrowableObjectArray* evaluating_;  // detects cycles
   RawExternalTypedData* constants_table_;
   RawArray* libraries_cache_;
   RawArray* classes_cache_;
   VISIT_TO(RawObject*, classes_cache_);
 
   RawObject** to_snapshot(Snapshot::Kind kind) {
-    return reinterpret_cast<RawObject**>(&ptr()->potential_natives_);
+    return reinterpret_cast<RawObject**>(&ptr()->constants_table_);
   }
 };
 
@@ -1457,6 +1462,7 @@
   friend class Function;
   friend class ImageReader;
   friend class ImageWriter;
+  friend class BlobImageWriter;
 };
 
 class RawPcDescriptors : public RawObject {
@@ -1518,6 +1524,7 @@
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
 
   friend class Object;
+  friend class ImageWriter;
 };
 
 // CodeSourceMap encodes a mapping from code PC ranges to source token
@@ -1536,6 +1543,7 @@
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
 
   friend class Object;
+  friend class ImageWriter;
 };
 
 // StackMap is an immutable representation of the layout of the stack at a
@@ -1559,6 +1567,8 @@
   // Variable length data follows here (bitmap of the stack layout).
   uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
   const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
+
+  friend class ImageWriter;
 };
 
 class RawLocalVarDescriptors : public RawObject {
@@ -2088,6 +2098,7 @@
   friend class OneByteStringDeserializationCluster;
   friend class TwoByteStringDeserializationCluster;
   friend class RODataSerializationCluster;
+  friend class ImageWriter;
 };
 
 class RawOneByteString : public RawString {
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 35d4fdc..e9113d9 100644
--- a/runtime/vm/raw_object_fields.cc
+++ b/runtime/vm/raw_object_fields.cc
@@ -93,6 +93,7 @@
   F(KernelProgramInfo, bytecode_component_)                                    \
   F(KernelProgramInfo, potential_natives_)                                     \
   F(KernelProgramInfo, potential_pragma_functions_)                            \
+  F(KernelProgramInfo, evaluating_)                                            \
   F(KernelProgramInfo, constants_table_)                                       \
   F(KernelProgramInfo, libraries_cache_)                                       \
   F(KernelProgramInfo, classes_cache_)                                         \
@@ -199,6 +200,7 @@
   F(FfiTrampolineData, signature_type_)                                        \
   F(FfiTrampolineData, c_signature_)                                           \
   F(FfiTrampolineData, callback_target_)                                       \
+  F(FfiTrampolineData, callback_exceptional_return_)                           \
   F(TypedDataBase, data_)                                                      \
   F(TypedDataBase, length_)                                                    \
   F(TypedDataView, typed_data_)                                                \
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index c886658..2b5d9cf2 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2132,7 +2132,7 @@
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = stack->FrameAt(i);
 #ifndef DART_PRECOMPILED_RUNTIME
-      if (!frame->IsInterpreted()) {
+      if (!frame->IsInterpreted() && !frame->function().ForceOptimize()) {
         // Ensure that we have unoptimized code.
         frame->function().EnsureHasCompiledUnoptimizedCode();
       }
@@ -2219,6 +2219,13 @@
 DEFINE_RUNTIME_ENTRY(StackOverflow, 0) {
 #if defined(USING_SIMULATOR)
   uword stack_pos = Simulator::Current()->get_sp();
+  // If simulator was never called (for example, in pure
+  // interpreted mode) it may return 0 as a value of SPREG.
+  if (stack_pos == 0) {
+    // Use any reasonable value which would not be treated
+    // as stack overflow.
+    stack_pos = thread->saved_stack_limit();
+  }
 #else
   uword stack_pos = OSThread::GetCurrentStackPointer();
 #endif
@@ -2296,7 +2303,8 @@
   // If running with interpreter, do the unoptimized compilation first.
   const bool optimizing_compilation = function.ShouldCompilerOptimize();
   ASSERT(FLAG_enable_interpreter || optimizing_compilation);
-  ASSERT((!optimizing_compilation) || function.HasCode());
+  ASSERT((!optimizing_compilation) || function.HasCode() ||
+         function.ForceOptimize());
 
 #if defined(PRODUCT)
   if (!optimizing_compilation ||
@@ -2510,6 +2518,11 @@
 
 void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
   ASSERT(optimized_code.is_optimized());
+
+  // Force-optimized code is optimized code which cannot deoptimize and doesn't
+  // have unoptimized code to fall back to.
+  ASSERT(!optimized_code.is_force_optimized());
+
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const Function& function = Function::Handle(zone, optimized_code.function());
@@ -2590,7 +2603,8 @@
   while (frame != NULL) {
     if (!frame->is_interpreted()) {
       optimized_code = frame->LookupDartCode();
-      if (optimized_code.is_optimized()) {
+      if (optimized_code.is_optimized() &&
+          !optimized_code.is_force_optimized()) {
         DeoptimizeAt(optimized_code, frame);
       }
     }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index a5f12e0..b39fa23 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3628,6 +3628,17 @@
 #endif
 }
 
+static const MethodParameter* get_vm_timeline_micros_params[] = {
+    NO_ISOLATE_PARAMETER, NULL,
+};
+
+static bool GetVMTimelineMicros(Thread* thread, JSONStream* js) {
+  JSONObject obj(js);
+  obj.AddProperty("type", "Timestamp");
+  obj.AddPropertyTimeMicros("timestamp", OS::GetCurrentMonotonicMicros());
+  return true;
+}
+
 static const MethodParameter* clear_vm_timeline_params[] = {
     NO_ISOLATE_PARAMETER, NULL,
 };
@@ -4976,6 +4987,8 @@
     get_vm_timeline_params },
   { "getVMTimelineFlags", GetVMTimelineFlags,
     get_vm_timeline_flags_params },
+  { "getVMTimelineMicros", GetVMTimelineMicros,
+    get_vm_timeline_micros_params },
   { "invoke", Invoke, invoke_params },
   { "kill", Kill, kill_params },
   { "pause", Pause,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 15d30ff..835282f 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 20
+#define SERVICE_PROTOCOL_MINOR_VERSION 21
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 2c5731c..2dfda77 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.20
+# Dart VM Service Protocol 3.21
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.20_ of the Dart VM Service Protocol. This
+This document describes of _version 3.21_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
   - [getVM](#getvm)
   - [getVMTimeline](#getvmtimeline)
   - [getVMTimelineFlags](#getvmtimelineflags)
+  - [getVMTimelineMicros](#getvmtimelinemicros)
   - [invoke](#invoke)
   - [pause](#pause)
   - [kill](#kill)
@@ -107,6 +108,7 @@
   - [Timeline](#timeline)
   - [TimelineEvent](#timelineevent)
   - [TimelineFlags](#timelineflags)
+  - [Timestamp](#timestamp)
   - [TypeArguments](#typearguments)
   - [UresolvedSourceLocation](#unresolvedsourcelocation)
   - [Version](#version)
@@ -490,7 +492,7 @@
 
 ### clearVMTimeline
 
-``` 
+```
 Success clearVMTimeline()
 ```
 
@@ -615,8 +617,8 @@
 
 ```
 AllocationProfile getAllocationProfile(string isolateId,
-                                       boolean reset [optional],
-                                       boolean gc [optional])
+                                       bool reset [optional],
+                                       bool gc [optional])
 ```
 
 The _getAllocationProfile_ RPC is used to retrieve allocation information for a
@@ -643,7 +645,8 @@
 ### getInstances
 
 ```
-InstanceSet getInstances(string objectId,
+InstanceSet getInstances(string isolateId,
+                         string objectId,
                          int limit)
 ```
 
@@ -806,8 +809,8 @@
 ### getVMTimeline
 
 ```
-Timeline getVMTimeline(int timeOriginMicros,
-                       int timeExtentMicros)
+Timeline getVMTimeline(int timeOriginMicros [optional],
+                       int timeExtentMicros [optional])
 ```
 
 The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
@@ -815,7 +818,8 @@
 
 The _timeOriginMicros_ parameter is the beginning of the time range used to filter
 timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
 
 The _timeExtentMicros_ parameter specifies how large the time range used to filter
 timeline events should be.
@@ -839,6 +843,17 @@
 
 See [TimelineFlags](#timelineflags).
 
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
 ### pause
 
 ```
@@ -2318,7 +2333,7 @@
   int totalCount;
 
   // An array of instances of the requested type.
-  @Instance[] instances;
+  @Object[] instances;
 }
 ```
 
@@ -2897,7 +2912,7 @@
 class TimelineFlags extends Response {
   // The name of the recorder currently in use. Recorder types include, but are
   // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
-  // Set to "null" if no recorder is currently set. 
+  // Set to "null" if no recorder is currently set.
   string recorderName;
 
   // The list of all available timeline streams.
@@ -2908,6 +2923,15 @@
 }
 ```
 
+### Timestamp
+
+```
+class Timestamp extends Response {
+  // A timestamp in microseconds since epoch.
+  int timestamp;
+}
+```
+
 ### TypeArguments
 
 ```
@@ -3056,5 +3080,6 @@
 3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
 3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
 3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 14293eb..04fd1e9 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.21-dev
+# Dart VM Service Protocol 3.22-dev
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.21-dev_ of the Dart VM Service Protocol. This
+This document describes of _version 3.22-dev_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -43,6 +43,7 @@
   - [getVM](#getvm)
   - [getVMTimeline](#getvmtimeline)
   - [getVMTimelineFlags](#getvmtimelineflags)
+  - [getVMTimelineMicros](#getvmtimelinemicros)
   - [invoke](#invoke)
   - [pause](#pause)
   - [kill](#kill)
@@ -107,6 +108,7 @@
   - [Timeline](#timeline)
   - [TimelineEvent](#timelineevent)
   - [TimelineFlags](#timelineflags)
+  - [Timestamp](#timestamp)
   - [TypeArguments](#typearguments)
   - [UresolvedSourceLocation](#unresolvedsourcelocation)
   - [Version](#version)
@@ -490,7 +492,7 @@
 
 ### clearVMTimeline
 
-``` 
+```
 Success clearVMTimeline()
 ```
 
@@ -615,8 +617,8 @@
 
 ```
 AllocationProfile getAllocationProfile(string isolateId,
-                                       boolean reset [optional],
-                                       boolean gc [optional])
+                                       bool reset [optional],
+                                       bool gc [optional])
 ```
 
 The _getAllocationProfile_ RPC is used to retrieve allocation information for a
@@ -643,7 +645,8 @@
 ### getInstances
 
 ```
-InstanceSet getInstances(string objectId,
+InstanceSet getInstances(string isolateId,
+                         string objectId,
                          int limit)
 ```
 
@@ -806,8 +809,8 @@
 ### getVMTimeline
 
 ```
-Timeline getVMTimeline(int timeOriginMicros,
-                       int timeExtentMicros)
+Timeline getVMTimeline(int timeOriginMicros [optional],
+                       int timeExtentMicros [optional])
 ```
 
 The _getVMTimeline_ RPC is used to retrieve an object which contains VM timeline
@@ -815,7 +818,8 @@
 
 The _timeOriginMicros_ parameter is the beginning of the time range used to filter
 timeline events. It uses the same monotonic clock as dart:developer's `Timeline.now`
-and the VM embedding API's `Dart_TimelineGetMicros`.
+and the VM embedding API's `Dart_TimelineGetMicros`. See [getVMTimelineMicros](#getvmtimelinemicros)
+for access to this clock through the service protocol.
 
 The _timeExtentMicros_ parameter specifies how large the time range used to filter
 timeline events should be.
@@ -839,6 +843,17 @@
 
 See [TimelineFlags](#timelineflags).
 
+### getVMTimelineMicros
+
+```
+Timestamp getVMTimelineMicros()
+```
+
+The _getVMTimelineMicros_ RPC returns the current time stamp from the clock used by the timeline,
+similar to `Timeline.now` in `dart:developer` and `Dart_TimelineGetMicros` in the VM embedding API.
+
+See [Timestamp](#timestamp) and [getVMTimeline](#getvmtimeline).
+
 ### pause
 
 ```
@@ -2318,7 +2333,7 @@
   int totalCount;
 
   // An array of instances of the requested type.
-  @Instance[] instances;
+  @Object[] instances;
 }
 ```
 
@@ -2897,7 +2912,7 @@
 class TimelineFlags extends Response {
   // The name of the recorder currently in use. Recorder types include, but are
   // not limited to: Callback, Endless, Fuchsia, Ring, Startup, and Systrace.
-  // Set to "null" if no recorder is currently set. 
+  // Set to "null" if no recorder is currently set.
   string recorderName;
 
   // The list of all available timeline streams.
@@ -2908,6 +2923,15 @@
 }
 ```
 
+### Timestamp
+
+```
+class Timestamp extends Response {
+  // A timestamp in microseconds since epoch.
+  int timestamp;
+}
+```
+
 ### TypeArguments
 
 ```
@@ -3056,5 +3080,6 @@
 3.18 | Add 'getAllocationProfile' RPC and 'AllocationProfile' and 'ClassHeapStats' objects.
 3.19 | Add 'clearVMTimeline', 'getVMTimeline', 'getVMTimelineFlags', 'setVMTimelineFlags', 'Timeline', and 'TimelineFlags'.
 3.20 | Add 'getInstances' RPC and 'InstanceSet' object.
+3.21 | Add 'getVMTimelineMicros' RPC and 'Timestamp' object.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 2cd0745..24197fe 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -829,10 +829,12 @@
 
 // Get the active Simulator for the current isolate.
 Simulator* Simulator::Current() {
-  Simulator* simulator = Isolate::Current()->simulator();
+  Isolate* isolate = Isolate::Current();
+  Simulator* simulator = isolate->simulator();
   if (simulator == NULL) {
+    NoSafepointScope no_safepoint;
     simulator = new Simulator();
-    Isolate::Current()->set_simulator(simulator);
+    isolate->set_simulator(simulator);
   }
   return simulator;
 }
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index c835793..8eb8dd5 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -869,10 +869,12 @@
 
 // Get the active Simulator for the current isolate.
 Simulator* Simulator::Current() {
-  Simulator* simulator = Isolate::Current()->simulator();
+  Isolate* isolate = Isolate::Current();
+  Simulator* simulator = isolate->simulator();
   if (simulator == NULL) {
+    NoSafepointScope no_safepoint;
     simulator = new Simulator();
-    Isolate::Current()->set_simulator(simulator);
+    isolate->set_simulator(simulator);
   }
   return simulator;
 }
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 99726ee..2a7176d 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -584,10 +584,12 @@
 
 // Get the active Simulator for the current isolate.
 Simulator* Simulator::Current() {
-  Simulator* simulator = Isolate::Current()->simulator();
+  Isolate* isolate = Isolate::Current();
+  Simulator* simulator = isolate->simulator();
   if (simulator == NULL) {
+    NoSafepointScope no_safepoint;
     simulator = new Simulator();
-    Isolate::Current()->set_simulator(simulator);
+    isolate->set_simulator(simulator);
   }
   return simulator;
 }
@@ -702,45 +704,12 @@
 DART_FORCE_INLINE static bool SignedMulWithOverflow(intptr_t lhs,
                                                     intptr_t rhs,
                                                     intptr_t* out) {
-  intptr_t res = 1;
-#if defined(HOST_ARCH_IA32) || defined(HOST_ARCH_X64)
-  asm volatile(
-      "imul %2, %1\n"
-      "jo 1f;\n"
-      "xor %0, %0\n"
-      "mov %1, 0(%3)\n"
-      "1: "
-      : "+r"(res), "+r"(lhs)
-      : "r"(rhs), "r"(out)
-      : "cc");
-#elif defined(HOST_ARCH_ARM)
-  asm volatile(
-      "smull %1, ip, %1, %2;\n"
-      "cmp ip, %1, ASR #31;\n"
-      "bne 1f;\n"
-      "mov %0, $0;\n"
-      "str %1, [%3, #0]\n"
-      "1:"
-      : "+r"(res), "+r"(lhs)
-      : "r"(rhs), "r"(out)
-      : "cc", "r12");
-#elif defined(HOST_ARCH_ARM64)
-  int64_t prod_lo = 0;
-  asm volatile(
-      "mul %1, %2, %3\n"
-      "smulh %2, %2, %3\n"
-      "cmp %2, %1, ASR #63;\n"
-      "bne 1f;\n"
-      "mov %0, #0;\n"
-      "str %1, [%4, #0]\n"
-      "1:"
-      : "=r"(res), "+r"(prod_lo), "+r"(lhs)
-      : "r"(rhs), "r"(out)
-      : "cc");
-#else
-#error "Unsupported platform"
-#endif
-  return (res != 0);
+  const intptr_t kMaxBits = (sizeof(intptr_t) * 8) - 2;
+  if ((Utils::HighestBit(lhs) + Utils::HighestBit(rhs)) < kMaxBits) {
+    *out = lhs * rhs;
+    return false;
+  }
+  return true;
 }
 
 DART_FORCE_INLINE static bool AreBothSmis(intptr_t a, intptr_t b) {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index febc594..0a79bd9 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -88,6 +88,9 @@
     }
   }
 
+  // These don't have unoptimized code and are only used for synthetic stubs.
+  if (func.ForceOptimize()) return true;
+
   switch (func.kind()) {
     case RawFunction::kRegularFunction:
     case RawFunction::kClosureFunction:
@@ -559,19 +562,20 @@
           script = cls.script();
           range.AddProperty("scriptIndex", GetScriptIndex(script));
           range.AddProperty("startPos", cls.token_pos());
-          range.AddProperty("endPos", cls.ComputeEndTokenPos());
+          range.AddProperty("endPos", cls.end_token_pos());
           range.AddProperty("compiled", false);
           range.AddProperty("error", err);
           continue;
         }
         ASSERT(cls.is_finalized());
       } else {
+        cls.EnsureDeclarationLoaded();
         // Emit one range for the whole uncompiled class.
         JSONObject range(jsarr);
         script = cls.script();
         range.AddProperty("scriptIndex", GetScriptIndex(script));
         range.AddProperty("startPos", cls.token_pos());
-        range.AddProperty("endPos", cls.ComputeEndTokenPos());
+        range.AddProperty("endPos", cls.end_token_pos());
         range.AddProperty("compiled", false);
         continue;
       }
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index fa77c7d..76a31f8 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -48,7 +48,7 @@
   if (!expected.OperatorEquals(actual)) {
     OS::PrintErr("expected: '%s' actual: '%s'\n", expected.ToCString(),
                  actual.ToCString());
-    FATAL("Expect_equals fails.\n");
+    EXPECT(false);
   }
 }
 
@@ -112,9 +112,7 @@
       ASSERT(!lib.IsNull());
       const char* lib_name = String::Handle(zone, lib.url()).ToCString();
       char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name);
-      if (strcmp(full_name, name) != 0) {
-        FATAL("StackFrame_validateFrame fails, incorrect frame.\n");
-      }
+      EXPECT_STREQ(full_name, name);
       return;
     }
     count += 1;  // Count the dart frames.
@@ -251,7 +249,45 @@
   // The true stack depends on which strategy we are using for noSuchMethod. The
   // stacktrace as seen by Dart is the same either way because dispatcher
   // methods are marked invisible.
-  if (FLAG_lazy_dispatchers) {
+  if (FLAG_enable_interpreter) {
+    kScriptChars =
+        "class StackFrame {"
+        "  static equals(var obj1, var obj2) native \"StackFrame_equals\";"
+        "  static int frameCount() native \"StackFrame_frameCount\";"
+        "  static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
+        "  static validateFrame(int index,"
+        "                       String name) native "
+        "\"StackFrame_validateFrame\";"
+        "} "
+        "class StackFrame2Test {"
+        "  StackFrame2Test() {}"
+        "  noSuchMethod(Invocation im) {"
+        "    /* We should have 8 general frames and 4 dart frames as follows:"
+        "     * exit frame"
+        "     * dart frame corresponding to StackFrame.frameCount"
+        "     * dart frame corresponding to StackFrame2Test.noSuchMethod"
+        "     * entry frame"
+        "     * exit frame"
+        "     * dart frame for noSuchMethod dispatcher"
+        "     * dart frame corresponding to StackFrame2Test.testMain"
+        "     * entry frame"
+        "     */"
+        "    StackFrame.equals(8, StackFrame.frameCount());"
+        "    StackFrame.equals(4, StackFrame.dartFrameCount());"
+        "    StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
+        "    StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
+        "    StackFrame.validateFrame(2, \"StackFrame2Test_foo\");"
+        "    StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");"
+        "    return 5;"
+        "  }"
+        "  static testMain() {"
+        "    /* Declare |obj| dynamic so that noSuchMethod can be"
+        "     * called in strong mode. */"
+        "    dynamic obj = new StackFrame2Test();"
+        "    StackFrame.equals(5, obj.foo(101, 202));"
+        "  }"
+        "}";
+  } else if (FLAG_lazy_dispatchers) {
     kScriptChars =
         "class StackFrame {"
         "  static equals(var obj1, var obj2) native \"StackFrame_equals\";"
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index fb281f7..559fc77 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -25,6 +25,7 @@
   V(ApiError, "ApiError")                                                      \
   V(ArgDescVar, ":arg_desc")                                                   \
   V(ArgumentError, "ArgumentError")                                            \
+  V(AsFunctionInternal, "_asFunctionInternal")                                 \
   V(AssertionError, "_AssertionError")                                         \
   V(AssignIndexToken, "[]=")                                                   \
   V(AsyncCompleter, ":async_completer")                                        \
@@ -235,6 +236,7 @@
   V(SetterPrefix, "set:")                                                      \
   V(SignatureData, "SignatureData")                                            \
   V(SingleTargetCache, "SingleTargetCache")                                    \
+  V(SizeOfStructField, "#sizeOf")                                              \
   V(SpaceExtendsSpace, " extends ")                                            \
   V(SpaceIsFromSpace, " is from ")                                             \
   V(SpaceOfSpace, " of ")                                                      \
@@ -247,6 +249,8 @@
   V(StreamIterator, "StreamIterator")                                          \
   V(StreamIteratorConstructor, "StreamIterator.")                              \
   V(StringBase, "_StringBase")                                                 \
+  V(Struct, "Struct")                                                          \
+  V(StructFromPointer, "#fromPointer")                                         \
   V(SubtypeTestCache, "SubtypeTestCache")                                      \
   V(SwitchExpr, ":switch_expr")                                                \
   V(Symbol, "Symbol")                                                          \
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 68d85c2..6582016 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -919,8 +919,7 @@
 };
 
 #if defined(HOST_OS_FUCHSIA) && !defined(FUCHSIA_SDK)
-// A recorder that sends events to Fuchsia's tracing app. See:
-// https://fuchsia.googlesource.com/garnet/+/master/docs/tracing_usage_guide.md
+// A recorder that sends events to Fuchsia's tracing app.
 class TimelineEventFuchsiaRecorder : public TimelineEventPlatformRecorder {
  public:
   TimelineEventFuchsiaRecorder() {}
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index b75e93b..d7a6e3c 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -676,7 +676,7 @@
             String::Handle(lib.url()).ToCString(), /* klass=*/nullptr,
             /* is_static= */ false);
     if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
-      return Dart_NewApiError(compilation_result.error);
+      return Api::NewError("%s", compilation_result.error);
     }
 
     const uint8_t* kernel_bytes = compilation_result.kernel;
diff --git a/runtime/vm/verified_memory_test.cc b/runtime/vm/verified_memory_test.cc
deleted file mode 100644
index a78fe5d..0000000
--- a/runtime/vm/verified_memory_test.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// 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.
-
-#include "vm/verified_memory.h"
-#include "platform/assert.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-void Init() {
-#if defined(DEBUG)
-  FLAG_verified_mem = true;
-#endif
-}
-
-void Shutdown() {
-#if defined(DEBUG)
-  // We must reset this to false to avoid checking some assumptions in
-  // VM shutdown that are left violated by these tests.
-  FLAG_verified_mem = false;
-#endif
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryReserve) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  delete vm;
-  Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryCommit) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  vm->Commit(false);
-  delete vm;
-  Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryBasic) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  vm->Commit(false);
-  double* addr = reinterpret_cast<double*>(vm->address());
-  VerifiedMemory::Write(&addr[0], 0.5);
-  EXPECT_EQ(0.5, addr[0]);
-  VerifiedMemory::Write(&addr[1], 1.5);
-  VerifiedMemory::Write(&addr[2], 2.5);
-  VerifiedMemory::Write(&addr[0], 0.25);
-  static const double kNaN = NAN;
-  VerifiedMemory::Write(&addr[0], kNaN);  // Bitwise comparison should be used.
-  VerifiedMemory::Write(&addr[0], 0.5);
-  int64_t* unverified = reinterpret_cast<int64_t*>(&addr[3]);
-  *unverified = 123;
-  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
-  delete vm;
-  Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifiedMemoryAccept) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  vm->Commit(false);
-  double* addr = reinterpret_cast<double*>(vm->address());
-  VerifiedMemory::Write(&addr[0], 0.5);
-  VerifiedMemory::Write(&addr[1], 1.5);
-  VerifiedMemory::Write(&addr[2], 2.5);
-  VerifiedMemory::Write(&addr[0], 0.25);
-  // Unverified write followed by Accept ("I know what I'm doing").
-  memset(addr, 0xf3, 2 * sizeof(double));
-  VerifiedMemory::Accept(reinterpret_cast<uword>(addr), 2 * sizeof(double));
-  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
-  delete vm;
-  Shutdown();
-}
-
-// Negative tests below.
-
-VM_UNIT_TEST_CASE(VerifyImplicit_Crash) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  vm->Commit(false);
-  double* addr = reinterpret_cast<double*>(vm->address());
-  addr[0] = 0.5;  // Forget to use Write.
-  VerifiedMemory::Write(&addr[0], 1.5);
-  Shutdown();
-}
-
-VM_UNIT_TEST_CASE(VerifyExplicit_Crash) {
-  Init();
-  const intptr_t kReservationSize = 64 * KB;
-  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
-  EXPECT_EQ(kReservationSize, vm->size());
-  vm->Commit(false);
-  double* addr = reinterpret_cast<double*>(vm->address());
-  VerifiedMemory::Write(&addr[0], 0.5);
-  VerifiedMemory::Write(&addr[1], 1.5);
-  addr[1] = 3.5;  // Forget to use Write.
-  VerifiedMemory::Write(&addr[2], 2.5);
-  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
-  Shutdown();
-}
-
-}  // namespace dart
diff --git a/samples-dev/swarm/swarm_ui_lib/util/Uri.dart b/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
index 28e05b5..d04d0c5 100644
--- a/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
+++ b/samples-dev/swarm/swarm_ui_lib/util/Uri.dart
@@ -6,7 +6,7 @@
 
 /**
  * A parsed URI, inspired by:
- * http://closure-library.googlecode.com/svn/docs/class_goog_Uri.html
+ * https://github.com/google/closure-library/blob/master/closure/goog/uri/uri.js
  */
 class SwarmUri {
   /**
diff --git a/samples/ffi/sqlite/docs/sqlite-tutorial.md b/samples/ffi/sqlite/docs/sqlite-tutorial.md
index c38170c..f9db349 100644
--- a/samples/ffi/sqlite/docs/sqlite-tutorial.md
+++ b/samples/ffi/sqlite/docs/sqlite-tutorial.md
@@ -118,7 +118,7 @@
 queryC.free();
 ```
 
-Browse the code: [CString class](../lib/src/ffi/cstring.dart), [code calling sqlite3_prepare_v2](../lib/src/database.dart#57), and [dart:ffi pointer interface](../../../../sdk/lib/ffi/ffi.dart).
+Browse the code: [CString class](../lib/src/ffi/utf8.dart), [code calling sqlite3_prepare_v2](../lib/src/database.dart#57), and [dart:ffi pointer interface](../../../../sdk/lib/ffi/ffi.dart).
 
 ## Dart API
 
@@ -152,7 +152,7 @@
           "This row is not the current row, reading data from the non-current"
           " row is not supported by sqlite.");
     }
-    // ...  
+    // ...
     }
 }
 ```
@@ -231,4 +231,4 @@
 For example we could catch C++ exceptions in a C++ layer, and rethrow them in Dart.
 The architecture diagram would change to the following in that case.
 
-![architecture2](lib/scenario-full.svg)
\ No newline at end of file
+![architecture2](lib/scenario-full.svg)
diff --git a/samples/ffi/sqlite/lib/src/bindings/bindings.dart b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
index 613dbad..a248716 100644
--- a/samples/ffi/sqlite/lib/src/bindings/bindings.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/bindings.dart
@@ -4,7 +4,7 @@
 
 import "dart:ffi";
 
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
 import "../ffi/dylib_utils.dart";
 
 import "signatures.dart";
@@ -27,10 +27,10 @@
   /// [sqlite3_errmsg] or sqlite3_errmsg16() routines can be used to obtain
   /// an English language description of the error following a failure of any
   /// of the sqlite3_open() routines.
-  int Function(CString filename, Pointer<DatabasePointer> databaseOut,
-      int flags, CString vfs) sqlite3_open_v2;
+  int Function(Pointer<Utf8> filename, Pointer<Pointer<Database>> databaseOut,
+      int flags, Pointer<Utf8> vfs) sqlite3_open_v2;
 
-  int Function(DatabasePointer database) sqlite3_close_v2;
+  int Function(Pointer<Database> database) sqlite3_close_v2;
 
   /// Compiling An SQL Statement
   ///
@@ -80,11 +80,11 @@
   /// original SQL text. This causes the [sqlite3_step] interface to
   /// behave differently in three ways:
   int Function(
-      DatabasePointer database,
-      CString query,
+      Pointer<Database> database,
+      Pointer<Utf8> query,
       int nbytes,
-      Pointer<StatementPointer> statementOut,
-      Pointer<CString> tail) sqlite3_prepare_v2;
+      Pointer<Pointer<Statement>> statementOut,
+      Pointer<Pointer<Utf8>> tail) sqlite3_prepare_v2;
 
   /// Evaluate An SQL Statement
   ///
@@ -162,7 +162,7 @@
   /// of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
   /// then the more specific [error codes] are returned directly
   /// by sqlite3_step().  The use of the "v2" interface is recommended.
-  int Function(StatementPointer statement) sqlite3_step;
+  int Function(Pointer<Statement> statement) sqlite3_step;
 
   /// CAPI3REF: Reset A Prepared Statement Object
   ///
@@ -185,7 +185,7 @@
   /// [sqlite3_reset] returns an appropriate [Errors].
   ///
   /// ^The [sqlite3_reset] interface does not change the values
-  int Function(StatementPointer statement) sqlite3_reset;
+  int Function(Pointer<Statement> statement) sqlite3_reset;
 
   /// Destroy A Prepared Statement Object
   ///
@@ -210,14 +210,14 @@
   /// a prepared statement after it has been finalized.  Any use of a prepared
   /// statement after it has been finalized can result in undefined and
   /// undesirable behavior such as segfaults and heap corruption.
-  int Function(StatementPointer statement) sqlite3_finalize;
+  int Function(Pointer<Statement> statement) sqlite3_finalize;
 
   /// Number Of Columns In A Result Set
   ///
   /// ^Return the number of columns in the result set returned by the
   /// prepared statement. ^This routine returns 0 if pStmt is an SQL
   /// statement that does not return data (for example an [UPDATE]).
-  int Function(StatementPointer statement) sqlite3_column_count;
+  int Function(Pointer<Statement> statement) sqlite3_column_count;
 
   /// Column Names In A Result Set
   ///
@@ -242,7 +242,7 @@
   /// ^The name of a result column is the value of the "AS" clause for
   /// that column, if there is an AS clause.  If there is no AS clause
   /// then the name of the column is unspecified and may change from
-  CString Function(StatementPointer statement, int columnIndex)
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_name;
 
   /// CAPI3REF: Declared Datatype Of A Query Result
@@ -272,26 +272,28 @@
   /// strongly typed, but the typing is dynamic not static.  ^Type
   /// is associated with individual values, not with the containers
   /// used to hold those values.
-  CString Function(StatementPointer statement, int columnIndex)
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_decltype;
 
-  int Function(StatementPointer statement, int columnIndex) sqlite3_column_type;
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_type;
 
-  ValuePointer Function(StatementPointer statement, int columnIndex)
+  Pointer<Value> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_value;
 
-  double Function(StatementPointer statement, int columnIndex)
+  double Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_double;
 
-  int Function(StatementPointer statement, int columnIndex) sqlite3_column_int;
+  int Function(Pointer<Statement> statement, int columnIndex)
+      sqlite3_column_int;
 
-  CString Function(StatementPointer statement, int columnIndex)
+  Pointer<Utf8> Function(Pointer<Statement> statement, int columnIndex)
       sqlite3_column_text;
 
   /// The sqlite3_errstr() interface returns the English-language text that
   /// describes the result code, as UTF-8. Memory to hold the error message
   /// string is managed internally and must not be freed by the application.
-  CString Function(int code) sqlite3_errstr;
+  Pointer<Utf8> Function(int code) sqlite3_errstr;
 
   /// Error Codes And Messages
   ///
@@ -324,7 +326,7 @@
   /// If an interface fails with SQLITE_MISUSE, that means the interface
   /// was invoked incorrectly by the application.  In that case, the
   /// error code and message may or may not be set.
-  CString Function(DatabasePointer database) sqlite3_errmsg;
+  Pointer<Utf8> Function(Pointer<Database> database) sqlite3_errmsg;
 
   _SQLiteBindings() {
     sqlite = dlopenPlatformSpecific("sqlite3");
diff --git a/samples/ffi/sqlite/lib/src/bindings/signatures.dart b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
index bb1b1e9..8994577 100644
--- a/samples/ffi/sqlite/lib/src/bindings/signatures.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/signatures.dart
@@ -4,52 +4,54 @@
 
 import "dart:ffi";
 
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
 
 import "types.dart";
 
-typedef sqlite3_open_v2_native_t = Int32 Function(
-    CString filename, Pointer<DatabasePointer> ppDb, Int32 flags, CString vfs);
+typedef sqlite3_open_v2_native_t = Int32 Function(Pointer<Utf8> filename,
+    Pointer<Pointer<Database>> ppDb, Int32 flags, Pointer<Utf8> vfs);
 
-typedef sqlite3_close_v2_native_t = Int32 Function(DatabasePointer database);
+typedef sqlite3_close_v2_native_t = Int32 Function(Pointer<Database> database);
 
 typedef sqlite3_prepare_v2_native_t = Int32 Function(
-    DatabasePointer database,
-    CString query,
+    Pointer<Database> database,
+    Pointer<Utf8> query,
     Int32 nbytes,
-    Pointer<StatementPointer> statementOut,
-    Pointer<CString> tail);
+    Pointer<Pointer<Statement>> statementOut,
+    Pointer<Pointer<Utf8>> tail);
 
-typedef sqlite3_step_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_step_native_t = Int32 Function(Pointer<Statement> statement);
 
-typedef sqlite3_reset_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_reset_native_t = Int32 Function(Pointer<Statement> statement);
 
-typedef sqlite3_finalize_native_t = Int32 Function(StatementPointer statement);
+typedef sqlite3_finalize_native_t = Int32 Function(
+    Pointer<Statement> statement);
 
-typedef sqlite3_errstr_native_t = CString Function(Int32 error);
+typedef sqlite3_errstr_native_t = Pointer<Utf8> Function(Int32 error);
 
-typedef sqlite3_errmsg_native_t = CString Function(DatabasePointer database);
+typedef sqlite3_errmsg_native_t = Pointer<Utf8> Function(
+    Pointer<Database> database);
 
 typedef sqlite3_column_count_native_t = Int32 Function(
-    StatementPointer statement);
+    Pointer<Statement> statement);
 
-typedef sqlite3_column_name_native_t = CString Function(
-    StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_name_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
 
-typedef sqlite3_column_decltype_native_t = CString Function(
-    StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_decltype_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
 
 typedef sqlite3_column_type_native_t = Int32 Function(
-    StatementPointer statement, Int32 columnIndex);
+    Pointer<Statement> statement, Int32 columnIndex);
 
-typedef sqlite3_column_value_native_t = ValuePointer Function(
-    StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_value_native_t = Pointer<Value> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
 
 typedef sqlite3_column_double_native_t = Double Function(
-    StatementPointer statement, Int32 columnIndex);
+    Pointer<Statement> statement, Int32 columnIndex);
 
 typedef sqlite3_column_int_native_t = Int32 Function(
-    StatementPointer statement, Int32 columnIndex);
+    Pointer<Statement> statement, Int32 columnIndex);
 
-typedef sqlite3_column_text_native_t = CString Function(
-    StatementPointer statement, Int32 columnIndex);
+typedef sqlite3_column_text_native_t = Pointer<Utf8> Function(
+    Pointer<Statement> statement, Int32 columnIndex);
diff --git a/samples/ffi/sqlite/lib/src/bindings/types.dart b/samples/ffi/sqlite/lib/src/bindings/types.dart
index b843d74..f536b91 100644
--- a/samples/ffi/sqlite/lib/src/bindings/types.dart
+++ b/samples/ffi/sqlite/lib/src/bindings/types.dart
@@ -4,7 +4,7 @@
 
 import "dart:ffi";
 
-import "../ffi/cstring.dart";
+import "../ffi/utf8.dart";
 
 /// Database Connection Handle
 ///
@@ -15,7 +15,7 @@
 /// is its destructor.  There are many other interfaces (such as
 /// [sqlite3_prepare_v2()], [sqlite3_create_function()], and
 /// [sqlite3_busy_timeout()] to name but three) that are methods on an
-class DatabasePointer extends Pointer<Void> {}
+class Database extends Struct<Database> {}
 
 /// SQL Statement Object
 ///
@@ -38,7 +38,7 @@
 ///
 /// Refer to documentation on individual methods above for additional
 /// information.
-class StatementPointer extends Pointer<Void> {}
+class Statement extends Struct<Statement> {}
 
 /// Dynamically Typed Value Object
 ///
@@ -74,4 +74,4 @@
 /// [sqlite3_result_value()] and [sqlite3_bind_value()].
 /// The [sqlite3_value_blob | sqlite3_value_type()] family of
 /// interfaces require protected sqlite3_value objects.
-class ValuePointer extends Pointer<Void> {}
+class Value extends Struct<Value> {}
diff --git a/samples/ffi/sqlite/lib/src/database.dart b/samples/ffi/sqlite/lib/src/database.dart
index a20b7fc..2cd4316 100644
--- a/samples/ffi/sqlite/lib/src/database.dart
+++ b/samples/ffi/sqlite/lib/src/database.dart
@@ -6,10 +6,13 @@
 import "dart:ffi";
 
 import "bindings/bindings.dart";
-import "bindings/types.dart";
+
+import "bindings/types.dart" as types;
+import "bindings/types.dart" hide Database;
+
 import "bindings/constants.dart";
 import "collections/closable_iterator.dart";
-import "ffi/cstring.dart";
+import "ffi/utf8.dart";
 
 /// [Database] represents an open connection to a SQLite database.
 ///
@@ -17,16 +20,16 @@
 ///
 /// This database interacts with SQLite synchonously.
 class Database {
-  DatabasePointer _database;
+  Pointer<types.Database> _database;
   bool _open = false;
 
   /// Open a database located at the file [path].
   Database(String path,
       [int flags = Flags.SQLITE_OPEN_READWRITE | Flags.SQLITE_OPEN_CREATE]) {
-    Pointer<DatabasePointer> dbOut = allocate();
-    CString pathC = CString.allocate(path);
+    Pointer<Pointer<types.Database>> dbOut = Pointer.allocate();
+    final pathC = Utf8.allocate(path);
     final int resultCode =
-        bindings.sqlite3_open_v2(pathC, dbOut, flags, fromAddress(0));
+        bindings.sqlite3_open_v2(pathC, dbOut, flags, Pointer.fromAddress(0));
     _database = dbOut.load();
     dbOut.free();
     pathC.free();
@@ -59,11 +62,11 @@
 
   /// Execute a query, discarding any returned rows.
   void execute(String query) {
-    Pointer<StatementPointer> statementOut = allocate();
-    CString queryC = CString.allocate(query);
+    Pointer<Pointer<Statement>> statementOut = Pointer.allocate();
+    Pointer<Utf8> queryC = Utf8.allocate(query);
     int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, fromAddress(0));
-    StatementPointer statement = statementOut.load();
+        _database, queryC, -1, statementOut, Pointer.fromAddress(0));
+    Pointer<Statement> statement = statementOut.load();
     statementOut.free();
     queryC.free();
 
@@ -78,11 +81,11 @@
 
   /// Evaluate a query and return the resulting rows as an iterable.
   Result query(String query) {
-    Pointer<StatementPointer> statementOut = allocate();
-    CString queryC = CString.allocate(query);
+    Pointer<Pointer<Statement>> statementOut = Pointer.allocate();
+    Pointer<Utf8> queryC = Utf8.allocate(query);
     int resultCode = bindings.sqlite3_prepare_v2(
-        _database, queryC, -1, statementOut, fromAddress(0));
-    StatementPointer statement = statementOut.load();
+        _database, queryC, -1, statementOut, Pointer.fromAddress(0));
+    Pointer<Statement> statement = statementOut.load();
     statementOut.free();
     queryC.free();
 
@@ -95,7 +98,7 @@
     int columnCount = bindings.sqlite3_column_count(statement);
     for (int i = 0; i < columnCount; i++) {
       String columnName =
-          CString.fromUtf8(bindings.sqlite3_column_name(statement, i));
+          bindings.sqlite3_column_name(statement, i).load<Utf8>().toString();
       columnIndices[columnName] = i;
     }
 
@@ -103,12 +106,13 @@
   }
 
   SQLiteException _loadError([int errorCode]) {
-    String errorMessage = CString.fromUtf8(bindings.sqlite3_errmsg(_database));
+    String errorMessage =
+        bindings.sqlite3_errmsg(_database).load<Utf8>().toString();
     if (errorCode == null) {
       return SQLiteException(errorMessage);
     }
     String errorCodeExplanation =
-        CString.fromUtf8(bindings.sqlite3_errstr(errorCode));
+        bindings.sqlite3_errstr(errorCode).load<Utf8>().toString();
     return SQLiteException(
         "$errorMessage (Code $errorCode: $errorCodeExplanation)");
   }
@@ -122,7 +126,7 @@
 class Result extends IterableBase<Row> implements ClosableIterable<Row> {
   final Database _database;
   final ClosableIterator<Row> _iterator;
-  final StatementPointer _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -139,7 +143,7 @@
 }
 
 class _ResultIterator implements ClosableIterator<Row> {
-  final StatementPointer _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   Row _currentRow = null;
@@ -177,7 +181,7 @@
 }
 
 class Row {
-  final StatementPointer _statement;
+  final Pointer<Statement> _statement;
   final Map<String, int> _columnIndices;
 
   bool _isCurrentRow = true;
@@ -208,8 +212,10 @@
       dynamicType =
           _typeFromCode(bindings.sqlite3_column_type(_statement, columnIndex));
     } else {
-      dynamicType = _typeFromText(CString.fromUtf8(
-          bindings.sqlite3_column_decltype(_statement, columnIndex)));
+      dynamicType = _typeFromText(bindings
+          .sqlite3_column_decltype(_statement, columnIndex)
+          .load<Utf8>()
+          .toString());
     }
 
     switch (dynamicType) {
@@ -245,8 +251,10 @@
   /// Reads column [columnIndex] and converts to [Type.Text] if not text.
   String readColumnByIndexAsText(int columnIndex) {
     _checkIsCurrentRow();
-    return CString.fromUtf8(
-        bindings.sqlite3_column_text(_statement, columnIndex));
+    return bindings
+        .sqlite3_column_text(_statement, columnIndex)
+        .load<Utf8>()
+        .toString();
   }
 
   void _checkIsCurrentRow() {
diff --git a/samples/ffi/sqlite/lib/src/ffi/cstring.dart b/samples/ffi/sqlite/lib/src/ffi/utf8.dart
similarity index 61%
rename from samples/ffi/sqlite/lib/src/ffi/cstring.dart
rename to samples/ffi/sqlite/lib/src/ffi/utf8.dart
index da095e4..b7da3c5 100644
--- a/samples/ffi/sqlite/lib/src/ffi/cstring.dart
+++ b/samples/ffi/sqlite/lib/src/ffi/utf8.dart
@@ -8,36 +8,41 @@
 import "arena.dart";
 
 /// Represents a String in C memory, managed by an [Arena].
-class CString extends Pointer<Uint8> {
+class Utf8 extends Struct<Utf8> {
+  @Int8()
+  int char;
+
   /// Allocates a [CString] in the current [Arena] and populates it with
   /// [dartStr].
-  factory CString(String dartStr) => CString.inArena(Arena.current(), dartStr);
+  static Pointer<Utf8> fromString(String dartStr) =>
+      Utf8.fromStringArena(Arena.current(), dartStr);
 
   /// Allocates a [CString] in [arena] and populates it with [dartStr].
-  factory CString.inArena(Arena arena, String dartStr) =>
-      arena.scoped(CString.allocate(dartStr));
+  static Pointer<Utf8> fromStringArena(Arena arena, String dartStr) =>
+      arena.scoped(allocate(dartStr));
 
   /// Allocate a [CString] not managed in and populates it with [dartStr].
   ///
   /// This [CString] is not managed by an [Arena]. Please ensure to [free] the
   /// memory manually!
-  factory CString.allocate(String dartStr) {
+  static Pointer<Utf8> allocate(String dartStr) {
     List<int> units = Utf8Encoder().convert(dartStr);
-    Pointer<Uint8> str = allocate(count: units.length + 1);
+    Pointer<Utf8> str = Pointer.allocate(count: units.length + 1);
     for (int i = 0; i < units.length; ++i) {
-      str.elementAt(i).store(units[i]);
+      str.elementAt(i).load<Utf8>().char = units[i];
     }
-    str.elementAt(units.length).store(0);
+    str.elementAt(units.length).load<Utf8>().char = 0;
     return str.cast();
   }
 
   /// Read the string for C memory into Dart.
-  static String fromUtf8(CString str) {
-    if (str == null) return null;
+  String toString() {
+    final str = addressOf;
+    if (str == nullptr) return null;
     int len = 0;
-    while (str.elementAt(++len).load<int>() != 0);
+    while (str.elementAt(++len).load<Utf8>().char != 0);
     List<int> units = List(len);
-    for (int i = 0; i < len; ++i) units[i] = str.elementAt(i).load();
+    for (int i = 0; i < len; ++i) units[i] = str.elementAt(i).load<Utf8>().char;
     return Utf8Decoder().convert(units);
   }
 }
diff --git a/samples/samples.status b/samples/samples.status
index f72f9e5..b5f2b33 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -8,9 +8,6 @@
 [ $builder_tag == optimization_counter_threshold ]
 sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign # This test is too slow for testing with low optimization counter threshold.
 
-[ $compiler == precompiler ]
-sample_extension/test/*: Skip # These tests attempt to spawn another script using the precompiled runtime.
-
 [ $compiler == dart2js && $runtime == none ]
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
@@ -26,7 +23,7 @@
 [ $arch != x64 || $compiler != dartk || $system != linux || $hot_reload || $hot_reload_rollback ]
 ffi/sqlite/test/sqlite_test: Skip # FFI not supported or libsqlite3.so not available.
 
-[ $compiler == app_jitk || $compiler == dartkb || $compiler == dartkp ]
+[ $compiler == app_jitk || $compiler == dartkp ]
 sample_extension/test/sample_extension_app_snapshot_test: SkipByDesign
 sample_extension/test/sample_extension_test: SkipByDesign
 
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index a759348..5d2bbb6 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -1051,7 +1051,7 @@
  *       res.close();
  *     }
  */
-abstract class HttpRequest implements Stream<List<int>> {
+abstract class HttpRequest implements Stream<Uint8List> {
   /**
    * The content length of the request body.
    *
@@ -1947,7 +1947,7 @@
  *            });
  *          });
  */
-abstract class HttpClientResponse implements Stream<List<int>> {
+abstract class HttpClientResponse implements Stream<Uint8List> {
   /**
    * Returns the status code.
    *
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 5c39ad4..c3325a4 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -125,10 +125,10 @@
 
 typedef void _BytesConsumer(List<int> bytes);
 
-class _HttpIncoming extends Stream<List<int>> {
+class _HttpIncoming extends Stream<Uint8List> {
   final int _transferLength;
   final Completer _dataCompleter = new Completer();
-  Stream<List<int>> _stream;
+  Stream<Uint8List> _stream;
 
   bool fullBodyRead = false;
 
@@ -154,7 +154,7 @@
 
   _HttpIncoming(this.headers, this._transferLength, this._stream);
 
-  StreamSubscription<List<int>> listen(void onData(List<int> event),
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
       {Function onError, void onDone(), bool cancelOnError}) {
     hasSubscriber = true;
     return _stream.handleError((error) {
@@ -173,7 +173,7 @@
   }
 }
 
-abstract class _HttpInboundMessage extends Stream<List<int>> {
+abstract class _HttpInboundMessage extends Stream<Uint8List> {
   final _HttpIncoming _incoming;
   List<Cookie> _cookies;
 
@@ -225,7 +225,7 @@
     }
   }
 
-  StreamSubscription<List<int>> listen(void onData(List<int> event),
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
       {Function onError, void onDone(), bool cancelOnError}) {
     return _incoming.listen(onData,
         onError: onError, onDone: onDone, cancelOnError: cancelOnError);
@@ -382,18 +382,21 @@
     });
   }
 
-  StreamSubscription<List<int>> listen(void onData(List<int> event),
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
       {Function onError, void onDone(), bool cancelOnError}) {
     if (_incoming.upgraded) {
       // If upgraded, the connection is already 'removed' form the client.
       // Since listening to upgraded data is 'bogus', simply close and
       // return empty stream subscription.
       _httpRequest._httpClientConnection.destroy();
-      return new Stream<List<int>>.empty().listen(null, onDone: onDone);
+      return new Stream<Uint8List>.empty().listen(null, onDone: onDone);
     }
-    Stream<List<int>> stream = _incoming;
+    Stream<Uint8List> stream = _incoming;
     if (compressionState == HttpClientResponseCompressionState.decompressed) {
-      stream = stream.transform(gzip.decoder);
+      stream = stream
+          .cast<List<int>>()
+          .transform(gzip.decoder)
+          .transform(const _ToUint8List());
     }
     return stream.listen(onData,
         onError: onError, onDone: onDone, cancelOnError: cancelOnError);
@@ -534,6 +537,30 @@
   }
 }
 
+class _ToUint8List extends Converter<List<int>, Uint8List> {
+  const _ToUint8List();
+
+  Uint8List convert(List<int> input) => Uint8List.fromList(input);
+
+  Sink<List<int>> startChunkedConversion(Sink<Uint8List> sink) {
+    return _Uint8ListConversionSink(sink);
+  }
+}
+
+class _Uint8ListConversionSink implements Sink<List<int>> {
+  const _Uint8ListConversionSink(this._target);
+
+  final Sink<Uint8List> _target;
+
+  void add(List<int> data) {
+    _target.add(Uint8List.fromList(data));
+  }
+
+  void close() {
+    _target.close();
+  }
+}
+
 class _StreamSinkImpl<T> implements StreamSink<T> {
   final StreamConsumer<T> _target;
   final Completer _doneCompleter = new Completer();
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index eb7663b..089006f 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -265,7 +265,7 @@
   bool _paused = true;
   bool _bodyPaused = false;
   StreamController<_HttpIncoming> _controller;
-  StreamController<List<int>> _bodyController;
+  StreamController<Uint8List> _bodyController;
 
   factory _HttpParser.requestParser() {
     return new _HttpParser._(true);
@@ -762,7 +762,7 @@
           // Always present the data as a view. This way we can handle all
           // cases like this, and the user will not experience different data
           // typed (which could lead to polymorphic user code).
-          List<int> data = new Uint8List.view(
+          Uint8List data = new Uint8List.view(
               _buffer.buffer, _buffer.offsetInBytes + _index, dataAvailable);
           _bodyController.add(data);
           if (_remainingContent != -1) {
@@ -993,7 +993,7 @@
     assert(_bodyController == null);
     assert(!_bodyPaused);
     var incoming;
-    _bodyController = new StreamController<List<int>>(
+    _bodyController = new StreamController<Uint8List>(
         sync: true,
         onListen: () {
           if (incoming != _incoming) return;
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
index 1525959..1c62090 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart
@@ -425,7 +425,7 @@
 cast(obj, type, @notNull bool isImplicit) {
   if (obj == null) return obj;
   var actual = getReifiedType(obj);
-  if (_isSubtypeOrLegacySubtype(actual, type) == true) {
+  if (isSubtypeOf(actual, type)) {
     return obj;
   }
   return castError(obj, type, isImplicit);
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 3c9852c..3265b7f 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -472,7 +472,7 @@
       var actual = JS('', '#[#]', obj, _runtimeType);
       // If there's no actual type, it's a JS function.
       // Allow them to subtype all Dart function types.
-      if (actual == null || _isSubtypeOrLegacySubtype(actual, this) == true) {
+      if (actual == null || isSubtypeOf(actual, this)) {
         return obj;
       }
     }
@@ -753,13 +753,7 @@
 })()''');
 
 /// Returns true if [ft1] <: [ft2].
-/// Returns false if [ft1] </: [ft2] in both spec and strong mode
-/// Returns null if [ft1] </: [ft2] in strong mode, but spec mode
-/// may differ
-/// If [isCovariant] is true, then we are checking subtyping in a covariant
-/// position, and hence the direction of the check for function types
-/// corresponds to the direction of the check according to the Dart spec.
-_isFunctionSubtype(ft1, ft2, isCovariant) => JS('', '''(() => {
+_isFunctionSubtype(ft1, ft2) => JS('', '''(() => {
   let ret1 = $ft1.returnType;
   let ret2 = $ft2.returnType;
 
@@ -767,16 +761,12 @@
   let args2 = $ft2.args;
 
   if (args1.length > args2.length) {
-    // If we're in a covariant position, then Dart's arity rules
-    // agree with strong mode, otherwise we can't be sure.
-    return ($isCovariant) ? false : null;
+    return false;
   }
 
   for (let i = 0; i < args1.length; ++i) {
-    if (!$_isSubtype(args2[i], args1[i], !$isCovariant)) {
-      // Even if isSubtypeOf returns false, assignability
-      // means that we can't be definitive
-      return null;
+    if (!$_isSubtype(args2[i], args1[i])) {
+      return false;
     }
   }
 
@@ -784,19 +774,19 @@
   let optionals2 = $ft2.optionals;
 
   if (args1.length + optionals1.length < args2.length + optionals2.length) {
-    return ($isCovariant) ? false : null;
+    return false;
   }
 
   let j = 0;
   for (let i = args1.length; i < args2.length; ++i, ++j) {
-    if (!$_isSubtype(args2[i], optionals1[j], !$isCovariant)) {
-      return null;
+    if (!$_isSubtype(args2[i], optionals1[j])) {
+      return false;
     }
   }
 
   for (let i = 0; i < optionals2.length; ++i, ++j) {
-    if (!$_isSubtype(optionals2[i], optionals1[j], !$isCovariant)) {
-      return null;
+    if (!$_isSubtype(optionals2[i], optionals1[j])) {
+      return false;
     }
   }
 
@@ -809,36 +799,21 @@
     let n1 = named1[name];
     let n2 = named2[name];
     if (n1 === void 0) {
-      return ($isCovariant) ? false : null;
+      return false;
     }
-    if (!$_isSubtype(n2, n1, !$isCovariant)) {
-      return null;
+    if (!$_isSubtype(n2, n1)) {
+      return false;
     }
   }
 
-  // Check return type last, so that arity mismatched functions can be
-  // definitively rejected.
-
-  // For `void` we will give the same answer as the VM, so don't return null.
-  if (ret1 === $void_) return $_isTop(ret2);
-
-  if (!$_isSubtype(ret1, ret2, $isCovariant)) return null;
-  return true;
+  return $_isSubtype(ret1, ret2);
 })()''');
 
-/// Whether [t1] <: [t2].
+/// Returns true if [t1] <: [t2].
 @notNull
 bool isSubtypeOf(Object t1, Object t2) {
   // TODO(jmesserly): we've optimized `is`/`as`/implicit type checks, so they're
   // dispatched on the type. Can we optimize the subtype relation too?
-  return JS('!', '!!#', _isSubtypeOrLegacySubtype(t1, t2));
-}
-
-/// Returns true if [t1] <: [t2].
-/// Returns false if [t1] </: [t2] and we should not ignore this cast failure.
-/// Returns null if [t1] </: [t2] and we should ignore this cast failure when
-/// the appropriate flags are set.
-bool _isSubtypeOrLegacySubtype(Object t1, Object t2) {
   Object map;
   if (JS('!', '!#.hasOwnProperty(#)', t1, _subtypeCache)) {
     JS('', '#[#] = # = new Map()', t1, _subtypeCache, map);
@@ -848,7 +823,7 @@
     bool result = JS('', '#.get(#)', map, t2);
     if (JS('!', '# !== void 0', result)) return result;
   }
-  var result = _isSubtype(t1, t2, true);
+  var result = _isSubtype(t1, t2);
   JS('', '#.set(#, #)', map, t2, result);
   return result;
 }
@@ -871,8 +846,10 @@
 bool _isFutureOr(type) =>
     identical(getGenericClass(type), getGenericClass(FutureOr));
 
-bool _isSubtype(t1, t2, isCovariant) => JS('', '''(() => {
-  if ($t1 === $t2) return true;
+bool _isSubtype(t1, t2) => JS('', '''(() => {
+  if ($t1 === $t2) {
+    return true;
+  }
 
   // Trivially true.
   if (${_isTop(t2)} || ${_isBottom(t1)}) {
@@ -880,9 +857,7 @@
   }
 
   // Trivially false.
-  if (${_isBottom(t2)}) return null;
-  if (${_isTop(t1)}) {
-    if ($t1 === $dynamic) return null;
+  if (${_isTop(t1)} || ${_isBottom(t2)}) {
     return false;
   }
 
@@ -892,14 +867,13 @@
     if (${_isFutureOr(t2)}) {
       let t2TypeArg = ${getGenericArgs(t2)}[0];
       // FutureOr<A> <: FutureOr<B> iff A <: B
-      return $_isSubtype(t1TypeArg, t2TypeArg, $isCovariant);
+      return $_isSubtype(t1TypeArg, t2TypeArg);
     }
 
     // given t1 is Future<A> | A, then:
     // (Future<A> | A) <: t2 iff Future<A> <: t2 and A <: t2.
     let t1Future = ${getGenericClass(Future)}(t1TypeArg);
-    return $_isSubtype(t1Future, $t2, $isCovariant) &&
-        $_isSubtype(t1TypeArg, $t2, $isCovariant);
+    return $_isSubtype(t1Future, $t2) && $_isSubtype(t1TypeArg, $t2);
   }
 
   if ($_isFutureOr($t2)) {
@@ -907,11 +881,9 @@
     // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
     let t2TypeArg = ${getGenericArgs(t2)}[0];
     let t2Future = ${getGenericClass(Future)}(t2TypeArg);
-    let s1 = $_isSubtype($t1, t2Future, $isCovariant);
-    let s2 = $_isSubtype($t1, t2TypeArg, $isCovariant);
-    if (s1 === true || s2 === true) return true;
-    if (s1 === null || s2 === null) return null;
-    return false;
+    let s1 = $_isSubtype($t1, t2Future);
+    let s2 = $_isSubtype($t1, t2TypeArg);
+    return s1 || s2;
   }
 
   // "Traditional" name-based subtype check.  Avoid passing
@@ -930,15 +902,19 @@
     if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) return true;
 
     // Compare two interface types:
-    return ${_isInterfaceSubtype(t1, t2, isCovariant)};
+    return ${_isInterfaceSubtype(t1, t2)};
   }
 
   // Function subtyping.
-  if (!($t1 instanceof $AbstractFunctionType)) return false;
+  if (!($t1 instanceof $AbstractFunctionType)) {
+    return false;
+  }
 
   // Handle generic functions.
   if ($t1 instanceof $GenericFunctionType) {
-    if (!($t2 instanceof $GenericFunctionType)) return false;
+    if (!($t2 instanceof $GenericFunctionType)) {
+      return false;
+    }
 
     // Given generic functions g1 and g2, g1 <: g2 iff:
     //
@@ -947,7 +923,9 @@
     // where TFresh is a list of fresh type variables that both g1 and g2 will
     // be instantiated with.
     let formalCount = $t1.formalCount;
-    if (formalCount !== $t2.formalCount) return false;
+    if (formalCount !== $t2.formalCount) {
+      return false;
+    }
 
     // Using either function's type formals will work as long as they're both
     // instantiated with the same ones. The instantiate operation is guaranteed
@@ -968,7 +946,7 @@
     let t2Bounds = $t2.instantiateTypeBounds(fresh);
     // TODO(jmesserly): we could optimize for the common case of no bounds.
     for (let i = 0; i < formalCount; i++) {
-      if (!$_isSubtype(t2Bounds[i], t1Bounds[i], !$isCovariant)) {
+      if (!$_isSubtype(t2Bounds[i], t1Bounds[i])) {
         return false;
       }
     }
@@ -980,29 +958,31 @@
   }
 
   // Handle non-generic functions.
-  return ${_isFunctionSubtype(t1, t2, isCovariant)};
+  return ${_isFunctionSubtype(t1, t2)};
 })()''');
 
-bool _isInterfaceSubtype(t1, t2, isCovariant) => JS('', '''(() => {
-  // We support Dart's covariant generics with the caveat that we do not
-  // substitute bottom for dynamic in subtyping rules.
-  // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
-  // - S !<: S<T1, ..., Tn>
-  // - S<dynamic, ..., dynamic> !<: S<T1, ..., Tn>
-  
+bool _isInterfaceSubtype(t1, t2) => JS('', '''(() => {
   // If we have lazy JS types, unwrap them.  This will effectively
   // reduce to a prototype check below.
   if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
   if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
 
-  if ($t1 === $t2) return true;
-  if ($t1 === $Object) return false;
+  if ($t1 === $t2) {
+    return true;
+  }
+  if ($t1 === $Object) {
+    return false;
+  }
 
   // Classes cannot subtype `Function` or vice versa.
-  if ($t1 === $Function || $t2 === $Function) return false;
+  if ($t1 === $Function || $t2 === $Function) {
+    return false;
+  }
 
   // If t1 is a JS Object, we may not hit core.Object.
-  if ($t1 == null) return $t2 == $Object || $t2 == $dynamic;
+  if ($t1 == null) {
+    return $t2 == $Object || $t2 == $dynamic;
+  }
 
   // Check if t1 and t2 have the same raw type.  If so, check covariance on
   // type parameters.
@@ -1017,13 +997,14 @@
       return true;
     } else if (length == 0) {
       // t1 is raw, but t2 is not
-      if (typeArguments2.every($_isTop)) return true;
-      return null;
+      if (typeArguments2.every($_isTop)) {
+        return true;
+      }
+      return false;
     }
     if (length != typeArguments2.length) $assertFailed();
     for (let i = 0; i < length; ++i) {
-      let result =
-          $_isSubtype(typeArguments1[i], typeArguments2[i], $isCovariant);
+      let result = $_isSubtype(typeArguments1[i], typeArguments2[i]);
       if (!result) {
         return result;
       }
@@ -1031,37 +1012,25 @@
     return true;
   }
 
-  let indefinite = false;
-  function definitive(t1, t2) {
-    let result = $_isInterfaceSubtype(t1, t2, $isCovariant);
-    if (result == null) {
-      indefinite = true;
-      return false;
-    }
-    return result;
+  if ($_isInterfaceSubtype(t1.__proto__, $t2)) {
+    return true;
   }
 
-  if (definitive($t1.__proto__, $t2)) return true;
-
   // Check mixin.
   let m1 = $getMixin($t1);
-  if (m1 != null) {
-    if (definitive(m1, $t2)) return true;
+  if (m1 != null && $_isInterfaceSubtype(m1, $t2)) {
+    return true;
   }
 
   // Check interfaces.
   let getInterfaces = $getImplements($t1);
   if (getInterfaces) {
     for (let i1 of getInterfaces()) {
-      if (definitive(i1, $t2)) return true;
+      if ($_isInterfaceSubtype(i1, $t2)) {
+        return true;
+      }
     }
   }
-
-  // We found no definite supertypes, and at least one indefinite supertype
-  // so the answer is indefinite.
-  if (indefinite) return null;
-  // We found no definite supertypes and no indefinite supertypes, so we
-  // can return false.
   return false;
 })()''');
 
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 87fab54..4b63f9e 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -58,7 +58,6 @@
         storedCallback = callback;
         // Because of a broken shadow-dom polyfill we have to change the
         // children instead a cheap property.
-        // See https://github.com/Polymer/ShadowDOM/issues/468
         JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', div, div,
             span, div, span);
       };
diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
index 5377630..0cecf96 100644
--- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -207,6 +207,11 @@
 /// Calls are replaced with the [HInterceptor] SSA instruction.
 external getInterceptor(object);
 
+/// Returns the Rti object for the type for JavaScript arrays via JS-interop.
+///
+/// Calls are replaced with a [HLoadType] SSA instruction.
+external Object getJSArrayInteropRti();
+
 /// Returns the object corresponding to Namer.staticStateHolder.
 external JS_GET_STATIC_STATE();
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index beee35b..654019c 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -59,7 +59,7 @@
         unmangleGlobalNameIfPreservedAnyways,
         unmangleAllIdentifiersIfPreservedAnyways;
 
-import 'dart:_rti' as newRti show getRuntimeType;
+import 'dart:_rti' as newRti show createRuntimeType, getRuntimeType;
 
 part 'annotations.dart';
 part 'constant_map.dart';
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index b53dcc8..d0bd80f 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -6,10 +6,18 @@
 library rti;
 
 import 'dart:_foreign_helper'
-    show JS, JS_EMBEDDED_GLOBAL, RAW_DART_FUNCTION_REF;
+    show
+        getInterceptor,
+        getJSArrayInteropRti,
+        JS,
+        JS_BUILTIN,
+        JS_EMBEDDED_GLOBAL,
+        JS_GET_NAME,
+        RAW_DART_FUNCTION_REF;
 import 'dart:_interceptors' show JSArray, JSUnmodifiableArray;
 
-import 'dart:_js_embedded_names' show RtiUniverseFieldNames, RTI_UNIVERSE;
+import 'dart:_js_embedded_names'
+    show JsBuiltin, JsGetName, RtiUniverseFieldNames, RTI_UNIVERSE;
 
 import 'dart:_recipe_syntax';
 
@@ -56,15 +64,15 @@
 
   /// Method called from generated code to evaluate a type environment recipe in
   /// `this` type environment.
-  Rti _eval(String recipe) {
+  Rti _eval(recipe) {
     // TODO(sra): Clone the fast-path of _Universe.evalInEnvironment to here.
-    return _rtiEval(this, recipe);
+    return _rtiEval(this, _Utils.asString(recipe));
   }
 
   /// Method called from generated code to extend `this` type environment (an
   /// interface or binding Rti) with function type arguments (a singleton
   /// argument or tuple of arguments).
-  Rti _bind(Rti typeOrTuple) => _rtiBind(this, typeOrTuple);
+  Rti _bind(typeOrTuple) => _rtiBind(this, _castToRti(typeOrTuple));
 
   /// Method called from generated code to extend `this` type (as a singleton
   /// type environment) with function type arguments (a singleton argument or
@@ -80,7 +88,12 @@
   dynamic _precomputed4;
 
   // The Type object corresponding to this Rti.
-  Type _typeCache;
+  Object _cachedRuntimeType;
+  static _Type _getCachedRuntimeType(Rti rti) =>
+      JS('_Type|Null', '#', rti._cachedRuntimeType);
+  static void _setCachedRuntimeType(Rti rti, _Type type) {
+    rti._cachedRuntimeType = type;
+  }
 
   /// The kind of Rti `this` is, one of the kindXXX constants below.
   ///
@@ -88,9 +101,9 @@
   ///
   /// The zero initializer ensures dart2js type analysis considers [_kind] is
   /// non-nullable.
-  int _kind = 0;
+  Object /*int*/ _kind = 0;
 
-  static int _getKind(Rti rti) => rti._kind;
+  static int _getKind(Rti rti) => _Utils.asInt(rti._kind);
   static void _setKind(Rti rti, int kind) {
     rti._kind = kind;
   }
@@ -143,7 +156,7 @@
     return _Utils.asString(_getPrimary(rti));
   }
 
-  static JSArray _getInterfaceTypeArguments(rti) {
+  static JSArray _getInterfaceTypeArguments(Rti rti) {
     // The array is a plain JavaScript Array, otherwise we would need the type
     // `JSArray<Rti>` to exist before we could create the type `JSArray<Rti>`.
     assert(_getKind(rti) == kindInterface);
@@ -155,7 +168,7 @@
     return _castToRti(_getPrimary(rti));
   }
 
-  static JSArray _getBindingArguments(rti) {
+  static JSArray _getBindingArguments(Rti rti) {
     assert(_getKind(rti) == kindBinding);
     return JS('JSUnmodifiableArray', '#', _getRest(rti));
   }
@@ -192,16 +205,16 @@
   /// (2)using `env._eval("@<0>")._bind(args)` in place of `env._bind1(args)`).
   Object _bindCache;
 
-  static Object _getBindCache(Rti rti) => rti._evalCache;
+  static Object _getBindCache(Rti rti) => rti._bindCache;
   static void _setBindCache(Rti rti, value) {
-    rti._evalCache = value;
+    rti._bindCache = value;
   }
 
   static Rti allocate() {
     return new Rti();
   }
 
-  String _canonicalRecipe;
+  Object _canonicalRecipe;
 
   static String _getCanonicalRecipe(Rti rti) {
     var s = rti._canonicalRecipe;
@@ -231,11 +244,84 @@
 /// Evaluate a ground-term type.
 /// Called from generated code.
 Rti findType(String recipe) {
-  _Universe.eval(_theUniverse(), recipe);
+  return _Universe.eval(_theUniverse(), recipe);
+}
+
+/// Returns the Rti type of [object].
+/// Called from generated code.
+Rti instanceType(object) {
+  // TODO(sra): Add specializations of this method. One possible way is to
+  // arrange that the interceptor has a _getType method that is injected into
+  // DartObject, Interceptor and JSArray. Then this method can be replaced-by
+  // `getInterceptor(o)._getType(o)`, allowing interceptor optimizations to
+  // select the specialization.
+
+  if (_Utils.instanceOf(
+      object,
+      JS_BUILTIN(
+          'depends:none;effects:none;', JsBuiltin.dartObjectConstructor))) {
+    var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+    if (rti != null) return _castToRti(rti);
+    return _instanceTypeFromConstructor(JS('', '#.constructor', object));
+  }
+
+  if (_Utils.isArray(object)) {
+    var rti = JS('', r'#[#]', object, JS_GET_NAME(JsGetName.RTI_NAME));
+    // TODO(sra): Do we need to protect against an Array passed between two Dart
+    // programs loaded into the same JavaScript isolate (e.g. via JS-interop).
+    // FWIW, the legacy rti has this problem too. Perhaps JSArrays should use a
+    // program-local `symbol` for the type field.
+    if (rti != null) return _castToRti(rti);
+    return _castToRti(getJSArrayInteropRti());
+  }
+
+  var interceptor = getInterceptor(object);
+  return _instanceTypeFromConstructor(JS('', '#.constructor', interceptor));
+}
+
+Rti _instanceTypeFromConstructor(constructor) {
+  // TODO(sra): Cache Rti on constructor.
+  return findType(JS('String', '#.name', constructor));
 }
 
 Type getRuntimeType(object) {
-  throw UnimplementedError('getRuntimeType');
+  Rti rti = instanceType(object);
+  return _createRuntimeType(rti);
+}
+
+/// Called from generated code.
+Type _createRuntimeType(Rti rti) {
+  _Type type = Rti._getCachedRuntimeType(rti);
+  if (type != null) return type;
+  // TODO(https://github.com/dart-lang/language/issues/428) For NNBD transition,
+  // canonicalization may be needed. It might be possible to generate a
+  // star-free recipe from the canonical recipe and evaluate that.
+  type = _Type(rti);
+  Rti._setCachedRuntimeType(rti, type);
+  return type;
+}
+
+/// Called from generated code in the constant pool.
+Type typeLiteral(String recipe) {
+  return _createRuntimeType(findType(recipe));
+}
+
+/// Implementation of [Type] based on Rti.
+class _Type implements Type {
+  final Rti _rti;
+  int _hashCode;
+
+  _Type(this._rti);
+
+  int get hashCode => _hashCode ??= Rti._getCanonicalRecipe(_rti).hashCode;
+
+  @pragma('dart2js:noInline')
+  bool operator ==(other) {
+    return (other is _Type) && identical(_rti, other._rti);
+  }
+
+  @override
+  String toString() => _rtiToString(_rti, null);
 }
 
 /// Called from generated code.
@@ -243,27 +329,61 @@
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
   Rti testRti = _castToRti(JS('', 'this'));
-  throw UnimplementedError(
-      '${Error.safeToString(object)} is ${_rtiToString(testRti, null)}');
+  Rti objectRti = instanceType(object);
+  return isSubtype(_theUniverse(), objectRti, testRti);
 }
 
 /// Called from generated code.
 _generalAsCheckImplementation(object) {
+  if (object == null) return object;
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
   Rti testRti = _castToRti(JS('', 'this'));
-  throw UnimplementedError(
-      '${Error.safeToString(object)} as ${_rtiToString(testRti, null)}');
+  Rti objectRti = instanceType(object);
+  if (isSubtype(_theUniverse(), objectRti, testRti)) return object;
+  var message = "${Error.safeToString(object)}:"
+      " type '${_rtiToString(objectRti, null)}'"
+      " is not a subtype of type '${_rtiToString(testRti, null)}'";
+  throw new _CastError.fromMessage('CastError: $message');
 }
 
 /// Called from generated code.
 _generalTypeCheckImplementation(object) {
+  if (object == null) return object;
   // This static method is installed on an Rti object as a JavaScript instance
   // method. The Rti object is 'this'.
   Rti testRti = _castToRti(JS('', 'this'));
-  throw UnimplementedError(
-      '${Error.safeToString(object)} as ${_rtiToString(testRti, null)}'
-      ' (TypeError)');
+  Rti objectRti = instanceType(object);
+  if (isSubtype(_theUniverse(), objectRti, testRti)) return object;
+  var message = "${Error.safeToString(object)}:"
+      " type '${_rtiToString(objectRti, null)}'"
+      " is not a subtype of type '${_rtiToString(testRti, null)}'";
+  throw new _TypeError.fromMessage('TypeError: $message');
+}
+
+/// Called from generated code.
+checkTypeBound(Rti type, Rti bound, variable) {
+  if (isSubtype(_theUniverse(), type, bound)) return type;
+  var message = "Type '${_rtiToString(type, null)}'"
+      " is not a subtype of type '${_rtiToString(bound, null)}'"
+      " of '${_Utils.asString(variable)}'";
+  throw _TypeError.fromMessage('TypeError: $message');
+}
+
+class _CastError extends Error implements CastError {
+  final String message;
+  _CastError.fromMessage(this.message);
+
+  @override
+  String toString() => message;
+}
+
+class _TypeError extends Error implements TypeError {
+  final String message;
+  _TypeError.fromMessage(this.message);
+
+  @override
+  String toString() => message;
 }
 
 String _rtiToString(Rti rti, List<String> genericContext) {
@@ -359,12 +479,14 @@
   static evalCache(universe) =>
       JS('', '#.#', universe, RtiUniverseFieldNames.evalCache);
 
-  static findRule(universe, String targetType) =>
-      JS('', '#.#.#', universe, RtiUniverseFieldNames.typeRules, targetType);
+  static Object typeRules(universe) =>
+      JS('', '#.#', universe, RtiUniverseFieldNames.typeRules);
 
-  static void addRule(universe, String targetType, rule) {
-    JS('', '#.#.# = #', universe, RtiUniverseFieldNames.typeRules, targetType,
-        rule);
+  static Object findRule(universe, String targetType) =>
+      JS('', '#.#', typeRules(universe), targetType);
+
+  static void addRules(universe, rules) {
+    JS('', 'Object.assign(#, #)', typeRules(universe), rules);
   }
 
   static Object sharedEmptyArray(universe) =>
@@ -407,8 +529,7 @@
     if (Rti._getKind(argumentsRti) == Rti.kindBinding) {
       argumentsArray = Rti._getBindingArguments(argumentsRti);
     } else {
-      argumentsArray = JS('', '[]');
-      _Utils.arrayPush(argumentsArray, argumentsRti);
+      argumentsArray = JS('', '[#]', argumentsRti);
     }
     var rti = _lookupBindingRti(universe, environment, argumentsArray);
     _cacheSet(cache, argumentsRecipe, rti);
@@ -460,10 +581,15 @@
   //   for the proposed type.
   // * `createXXX` to create the type if it does not exist.
 
-  static String _canonicalRecipeOfDynamic() => '@';
-  static String _canonicalRecipeOfVoid() => '~';
-  static String _canonicalRecipeOfNever() => '0&';
-  static String _canonicalRecipeOfAny() => '1&';
+  static String _canonicalRecipeOfDynamic() => Recipe.pushDynamicString;
+  static String _canonicalRecipeOfVoid() => Recipe.pushVoidString;
+  static String _canonicalRecipeOfNever() =>
+      Recipe.pushNeverExtensionString + Recipe.extensionOpString;
+  static String _canonicalRecipeOfAny() =>
+      Recipe.pushAnyExtensionString + Recipe.extensionOpString;
+
+  static String _canonicalRecipeOfFutureOr(Rti baseType) =>
+      Rti._getCanonicalRecipe(baseType) + Recipe.wrapFutureOrString;
 
   static Rti _lookupDynamicRti(universe) {
     return _lookupTerminalRti(
@@ -497,6 +623,23 @@
     return _finishRti(universe, rti);
   }
 
+  static Rti _lookupFutureOrRti(universe, Rti baseType) {
+    String canonicalRecipe = _canonicalRecipeOfFutureOr(baseType);
+    var cache = evalCache(universe);
+    var probe = _cacheGet(cache, canonicalRecipe);
+    if (probe != null) return _castToRti(probe);
+    return _createFutureOrRti(universe, baseType, canonicalRecipe);
+  }
+
+  static Rti _createFutureOrRti(
+      universe, Rti baseType, String canonicalRecipe) {
+    var rti = Rti.allocate();
+    Rti._setKind(rti, Rti.kindFutureOr);
+    Rti._setPrimary(rti, baseType);
+    Rti._setCanonicalRecipe(rti, canonicalRecipe);
+    return _finishRti(universe, rti);
+  }
+
   static String _canonicalRecipeJoin(Object arguments) {
     String s = '', sep = '';
     int length = _Utils.arrayLength(arguments);
@@ -504,7 +647,7 @@
       Rti argument = _castToRti(_Utils.arrayAt(arguments, i));
       String subrecipe = Rti._getCanonicalRecipe(argument);
       s += sep + subrecipe;
-      sep = ',';
+      sep = Recipe.separatorString;
     }
     return s;
   }
@@ -514,7 +657,9 @@
     String s = _Utils.asString(name);
     int length = _Utils.arrayLength(arguments);
     if (length != 0) {
-      s += '<' + _canonicalRecipeJoin(arguments) + '>';
+      s += Recipe.startTypeArgumentsString +
+          _canonicalRecipeJoin(arguments) +
+          Recipe.endTypeArgumentsString;
     }
     return s;
   }
@@ -540,14 +685,17 @@
 
   static String _canonicalRecipeOfBinding(Rti base, Object arguments) {
     String s = Rti._getCanonicalRecipe(base);
-    s += ';'; // TODO(sra): Omit when base encoding is Rti without ToType.
-    s += '<' + _canonicalRecipeJoin(arguments) + '>';
+    s += Recipe
+        .toTypeString; // TODO(sra): Omit when base encoding is Rti without ToType.
+    s += Recipe.startTypeArgumentsString +
+        _canonicalRecipeJoin(arguments) +
+        Recipe.endTypeArgumentsString;
     return s;
   }
 
   /// [arguments] becomes owned by the created Rti.
   static Rti _lookupBindingRti(Object universe, Rti base, Object arguments) {
-    var newBase = base;
+    Rti newBase = base;
     var newArguments = arguments;
     if (Rti._getKind(base) == Rti.kindBinding) {
       newBase = Rti._getBindingBase(base);
@@ -708,11 +856,11 @@
   }
 
   // Field accessors for the parser.
-  static Object universe(Object parser) => JS('String', '#.u', parser);
+  static Object universe(Object parser) => JS('', '#.u', parser);
   static Rti environment(Object parser) => JS('Rti', '#.e', parser);
   static String recipe(Object parser) => JS('String', '#.r', parser);
   static Object stack(Object parser) => JS('', '#.s', parser);
-  static Object position(Object parser) => JS('int', '#.p', parser);
+  static int position(Object parser) => JS('int', '#.p', parser);
   static void setPosition(Object parser, int p) {
     JS('', '#.p = #', parser, p);
   }
@@ -739,7 +887,7 @@
       } else {
         i++;
         switch (ch) {
-          case Recipe.noOp:
+          case Recipe.separator:
             break;
 
           case Recipe.toType:
@@ -768,6 +916,14 @@
             handleExtendedOperations(parser, stack);
             break;
 
+          case Recipe.wrapFutureOr:
+            var u = universe(parser);
+            push(
+                stack,
+                _Universe._lookupFutureOrRti(
+                    u, toType(u, environment(parser), pop(stack))));
+            break;
+
           default:
             JS('', 'throw "Bad character " + #', ch);
         }
@@ -909,37 +1065,33 @@
     throw UnimplementedError("TypeRule is static methods only.");
   }
 
-  // TODO(fishythefish): Create whole rule at once rather than adding individual
-  // supertypes/type variables.
-
-  @pragma('dart2js:noInline')
-  static Object create() {
-    return JS('=Object', '{}');
-  }
-
-  static void addTypeVariable(rule, String typeVariable, String binding) {
-    JS('', '#.# = #', rule, typeVariable, binding);
-  }
-
   static String lookupTypeVariable(rule, String typeVariable) =>
-      JS('String|Null', '#.#', rule, typeVariable);
-
-  static void addSupertype(rule, String supertype, Object supertypeArgs) {
-    JS('', '#.# = #', rule, supertype, supertypeArgs);
-  }
+      JS('', '#.#', rule, typeVariable);
 
   static JSArray lookupSupertype(rule, String supertype) =>
-      JS('JSArray|Null', '#.#', rule, supertype);
+      JS('', '#.#', rule, supertype);
 }
 
 // -------- Subtype tests ------------------------------------------------------
 
 // Future entry point from compiled code.
 bool isSubtype(universe, Rti s, Rti t) {
+  // TODO(sra): When more tests are working, remove this rediculous hack.
+  // Temporary 'metering' of isSubtype calls to force tests that endlessly loop
+  // to fail.
+  int next = JS('int', '(#||0) + 1', _ticks);
+  _ticks = next;
+  if (next > 10 * 1000 * 1000) {
+    throw StateError('Too many isSubtype calls'
+        '  ${_rtiToString(s, null)}  <:  ${_rtiToString(t, null)}');
+  }
+
   return _isSubtype(universe, s, null, t, null);
 }
 
-bool _isSubtype(universe, Rti s, var sEnv, Rti t, var tEnv) {
+int _ticks = 0;
+
+bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
   // TODO(fishythefish): Update for NNBD. See
   // https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules
 
@@ -969,14 +1121,13 @@
 
   if (isNullType(s)) return true;
 
-  if (isFunctionType(t)) {
+  if (isFunctionKind(t)) {
     // TODO(fishythefish): Check if s is a function subtype of t.
-    throw UnimplementedError("isFunctionType(t)");
+    throw UnimplementedError("isFunctionKind(t)");
   }
 
-  if (isFunctionType(s)) {
-    // TODO(fishythefish): Check if t is Function.
-    throw UnimplementedError("isFunctionType(s)");
+  if (isFunctionKind(s)) {
+    return isFunctionType(t);
   }
 
   if (isFutureOrType(t)) {
@@ -990,28 +1141,50 @@
       // `true` because [s] <: T.
       return true;
     } else {
-      // TODO(fishythefish): Check [s] <: Future<T>.
+      // Check [s] <: Future<T>.
+      String futureClass = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+      var argumentsArray = JS('', '[#]', tTypeArgument);
+      return _isSubtypeOfInterface(
+          universe, s, sEnv, futureClass, argumentsArray, tEnv);
     }
   }
 
-  assert(Rti._getKind(s) == Rti.kindInterface);
   assert(Rti._getKind(t) == Rti.kindInterface);
-  String sName = Rti._getInterfaceName(s);
   String tName = Rti._getInterfaceName(t);
-  // TODO(fishythefish): Handle identical names.
+  var tArgs = Rti._getInterfaceTypeArguments(t);
 
+  return _isSubtypeOfInterface(universe, s, sEnv, tName, tArgs, tEnv);
+}
+
+bool _isSubtypeOfInterface(
+    universe, Rti s, sEnv, String tName, Object tArgs, tEnv) {
+  assert(Rti._getKind(s) == Rti.kindInterface);
+  String sName = Rti._getInterfaceName(s);
+
+  if (sName == tName) {
+    var sArgs = Rti._getInterfaceTypeArguments(s);
+    int length = _Utils.arrayLength(sArgs);
+    assert(length == _Utils.arrayLength(tArgs));
+    for (int i = 0; i < length; i++) {
+      Rti sArg = _castToRti(_Utils.arrayAt(sArgs, i));
+      Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
+      if (!_isSubtype(universe, sArg, sEnv, tArg, tEnv)) return false;
+    }
+    return true;
+  }
+
+  // TODO(fishythefish): Should we recursively attempt to find supertypes?
   var rule = _Universe.findRule(universe, sName);
   if (rule == null) return false;
   var supertypeArgs = TypeRule.lookupSupertype(rule, tName);
   if (supertypeArgs == null) return false;
-  var tArgs = Rti._getInterfaceTypeArguments(t);
   int length = _Utils.arrayLength(supertypeArgs);
   assert(length == _Utils.arrayLength(tArgs));
   for (int i = 0; i < length; i++) {
     String recipe = _Utils.arrayAt(supertypeArgs, i);
     Rti supertypeArg = _Universe.evalInEnvironment(universe, s, recipe);
     Rti tArg = _castToRti(_Utils.arrayAt(tArgs, i));
-    if (!isSubtype(universe, supertypeArg, tArg)) return false;
+    if (!_isSubtype(universe, supertypeArg, sEnv, tArg, tEnv)) return false;
   }
 
   return true;
@@ -1024,19 +1197,23 @@
 bool isVoidType(Rti t) => Rti._getKind(t) == Rti.kindVoid;
 bool isJsInteropType(Rti t) => Rti._getKind(t) == Rti.kindAny;
 bool isFutureOrType(Rti t) => Rti._getKind(t) == Rti.kindFutureOr;
-bool isFunctionType(Rti t) => Rti._getKind(t) == Rti.kindFunction;
+bool isFunctionKind(Rti t) => Rti._getKind(t) == Rti.kindFunction;
 bool isGenericFunctionTypeParameter(Rti t) =>
     Rti._getKind(t) == Rti.kindGenericFunctionParameter;
 
-bool isObjectType(Rti t) {
-  // TODO(fishythefish): Look up Object in universe and compare.
-  return false;
-}
+bool isObjectType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
 
-bool isNullType(Rti t) {
-  // TODO(fishythefish): Look up Null in universe and compare.
-  return false;
-}
+// TODO(fishythefish): Which representation should we use for NNBD?
+// Do we also need to check for `Never?`, etc.?
+bool isNullType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+bool isFunctionType(Rti t) =>
+    Rti._getKind(t) == Rti.kindInterface &&
+    Rti._getInterfaceName(t) == JS_GET_NAME(JsGetName.FUNCTION_CLASS_TYPE_NAME);
 
 /// Unchecked cast to Rti.
 Rti _castToRti(s) => JS('Rti', '#', s);
@@ -1049,8 +1226,13 @@
   static bool isString(Object o) => JS('bool', 'typeof # == "string"', o);
   static bool isNum(Object o) => JS('bool', 'typeof # == "number"', o);
 
+  static bool instanceOf(Object o, Object constructor) =>
+      JS('bool', '# instanceof #', o, constructor);
+
   static bool isIdentical(s, t) => JS('bool', '# === #', s, t);
 
+  static bool isArray(Object o) => JS('bool', 'Array.isArray(#)', o);
+
   static int arrayLength(Object array) => JS('int', '#.length', array);
 
   static Object arrayAt(Object array, int i) => JS('', '#[#]', array, i);
@@ -1080,6 +1262,10 @@
 }
 // -------- Entry points for testing -------------------------------------------
 
+String testingCanonicalRecipe(rti) {
+  return Rti._getCanonicalRecipe(rti);
+}
+
 String testingRtiToString(rti) {
   return _rtiToString(_castToRti(rti), null);
 }
@@ -1092,20 +1278,8 @@
   return _Universe.create();
 }
 
-Object testingCreateRule() {
-  return TypeRule.create();
-}
-
-void testingAddTypeVariable(rule, String typeVariable, String binding) {
-  TypeRule.addTypeVariable(rule, typeVariable, binding);
-}
-
-void testingAddSupertype(rule, String supertype, Object supertypeArgs) {
-  TypeRule.addSupertype(rule, supertype, supertypeArgs);
-}
-
-void testingAddRule(universe, String targetType, rule) {
-  _Universe.addRule(universe, targetType, rule);
+void testingAddRules(universe, rules) {
+  _Universe.addRules(universe, rules);
 }
 
 bool testingIsSubtype(universe, rti1, rti2) {
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
index 78d0975..7666379 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
@@ -12,18 +12,54 @@
 
   // Operators.
 
-  static const int noOp = _comma;
+  static const int separator = _comma;
+  static const String separatorString = _commaString;
 
   static const int toType = _semicolon;
+  static const String toTypeString = _semicolonString;
 
   static const int pushDynamic = _at;
+  static const String pushDynamicString = _atString;
   static const int pushVoid = _tilde;
-  static const int wrapFutureOr = _formfeed;
+  static const String pushVoidString = _tildeString;
+
+  static const int wrapStar = _asterisk;
+  static const String wrapStarString = _asteriskString;
+  static const int wrapQuestion = _question;
+  static const String wrapQuestionString = _questionString;
+  static const int wrapFutureOr = _slash;
+  static const String wrapFutureOrString = _slashString;
 
   static const int startTypeArguments = _lessThan;
+  static const String startTypeArgumentsString = _lessThanString;
   static const int endTypeArguments = _greaterThan;
+  static const String endTypeArgumentsString = _greaterThanString;
+
+  static const int startFunctionArguments = _leftParen;
+  static const String startFunctionArgumentsString = _leftParenString;
+  static const int endFunctionArguments = _rightParen;
+  static const String endFunctionArgumentsString = _rightParenString;
+  static const int startOptionalGroup = _leftBracket;
+  static const String startOptionalGroupString = _leftBracketString;
+  static const int endOptionalGroup = _rightBracket;
+  static const String endOptionalGroupString = _rightBracketString;
+  static const int startNamedGroup = _leftBrace;
+  static const String startNamedGroupString = _leftBraceString;
+  static const int endNamedGroup = _rightBrace;
+  static const String endNamedGroupString = _rightBraceString;
+  static const int nameSeparator = _colon;
+  static const String nameSeparatorString = _colonString;
+
+  static const int genericFunctionTypeParameterIndex = _circumflex;
+  static const String genericFunctionTypeParameterIndexString =
+      _circumflexString;
 
   static const int extensionOp = _ampersand;
+  static const String extensionOpString = _ampersandString;
+  static const int pushNeverExtension = 0;
+  static const String pushNeverExtensionString = '$pushNeverExtension';
+  static const int pushAnyExtension = 1;
+  static const String pushAnyExtensionString = '$pushAnyExtension';
 
   // Number and name components.
 
@@ -39,29 +75,156 @@
 
   // Private names.
 
-  static const int _formfeed = 0x0C; // '\f' in string literal.
+  static const int _formfeed = 0x0C;
+  static const String _formfeedString = '\f';
 
+  static const int _space = 0x20;
+  static const String _spaceString = ' ';
+  static const int _exclamation = 0x21;
+  static const String _exclamationString = '!';
+  static const int _hash = 0x23;
+  static const String _hashString = '#';
   static const int _dollar = 0x24;
+  static const String _dollarString = r'$';
+  static const int _percent = 0x25;
+  static const String _percentString = '%';
   static const int _ampersand = 0x26;
+  static const String _ampersandString = '&';
+  static const int _apostrophe = 0x27;
+  static const String _apostropheString = "'";
+  static const int _leftParen = 0x28;
+  static const String _leftParenString = '(';
+  static const int _rightParen = 0x29;
+  static const String _rightParenString = ')';
+  static const int _asterisk = 0x2A;
+  static const String _asteriskString = '*';
   static const int _plus = 0x2B;
+  static const String _plusString = '+';
   static const int _comma = 0x2C;
+  static const String _commaString = ',';
+  static const int _minus = 0x2D;
+  static const String _minusString = '-';
   static const int _period = 0x2E;
+  static const String _periodString = '.';
+  static const int _slash = 0x2F;
+  static const String _slashString = '/';
+
   static const int _digit0 = 0x30;
   static const int _digit9 = 0x39;
+
+  static const int _colon = 0x3A;
+  static const String _colonString = ':';
   static const int _semicolon = 0x3B;
+  static const String _semicolonString = ';';
   static const int _lessThan = 0x3C;
+  static const String _lessThanString = '<';
+  static const int _equals = 0x3D;
+  static const String _equalsString = '=';
   static const int _greaterThan = 0x3E;
-  static const int _question = 0x3f;
+  static const String _greaterThanString = '>';
+  static const int _question = 0x3F;
+  static const String _questionString = '?';
   static const int _at = 0x40;
+  static const String _atString = '@';
 
-  static const int _underscore = 0x5F;
-  static const int _lowercaseA = 0x61;
-  static const int _tilde = 0x7E;
+  static const int _uppercaseA = 0x41;
+  static const int _uppercaseZ = 0x5A;
 
-  static const int _leftParen = 0x28;
-  static const int _rightParen = 0x29;
   static const int _leftBracket = 0x5B;
+  static const String _leftBracketString = '[';
+  static const int _backslash = 0x5C;
+  static const String _backslashString = r'\';
   static const int _rightBracket = 0x5D;
+  static const String _rightBracketString = ']';
+  static const int _circumflex = 0x5E;
+  static const String _circumflexString = '^';
+  static const int _underscore = 0x5F;
+  static const String _underscoreString = '_';
+  static const int _backtick = 0x60;
+  static const String _backtickString = '`';
+
+  static const int _lowercaseA = 0x61;
+  static const int _lowercaseZ = 0x7A;
+
   static const int _leftBrace = 0x7B;
+  static const String _leftBraceString = '{';
+  static const int _vertical = 0x7C;
+  static const String _verticalString = '|';
   static const int _rightBrace = 0x7D;
+  static const String _rightBraceString = '}';
+  static const int _tilde = 0x7E;
+  static const String _tildeString = '~';
+
+  static void testEquivalence() {
+    void test(String label, int charCode, String str) {
+      if (String.fromCharCode(charCode) != str) {
+        throw StateError("$label: String.fromCharCode($charCode) != $str");
+      }
+    }
+
+    void testExtension(String label, int op, String str) {
+      if ('$op' != str) {
+        throw StateError("$label: $op.toString() != $str");
+      }
+    }
+
+    test("separator", separator, separatorString);
+    test("toType", toType, toTypeString);
+    test("pushDynamic", pushDynamic, pushDynamicString);
+    test("pushVoid", pushVoid, pushVoidString);
+    test("wrapStar", wrapStar, wrapStarString);
+    test("wrapQuestion", wrapQuestion, wrapQuestionString);
+    test("wrapFutureOr", wrapFutureOr, wrapFutureOrString);
+    test("startTypeArguments", startTypeArguments, startTypeArgumentsString);
+    test("endTypeArguments", endTypeArguments, endTypeArgumentsString);
+    test("startFunctionArguments", startFunctionArguments,
+        startFunctionArgumentsString);
+    test("endFunctionArguments", endFunctionArguments,
+        endFunctionArgumentsString);
+    test("startOptionalGroup", startOptionalGroup, startOptionalGroupString);
+    test("endOptionalGroup", endOptionalGroup, endOptionalGroupString);
+    test("startNamedGroup", startNamedGroup, startNamedGroupString);
+    test("endNamedGroup", endNamedGroup, endNamedGroupString);
+    test("nameSeparator", nameSeparator, nameSeparatorString);
+    test("genericFunctionTypeParameterIndex", genericFunctionTypeParameterIndex,
+        genericFunctionTypeParameterIndexString);
+    test("extensionOp", extensionOp, extensionOpString);
+    testExtension(
+        "pushNeverExtension", pushNeverExtension, pushNeverExtensionString);
+    testExtension("pushAnyExtension", pushAnyExtension, pushAnyExtensionString);
+
+    test("_formfeed", _formfeed, _formfeedString);
+    test("_space", _space, _spaceString);
+    test("_exclamation", _exclamation, _exclamationString);
+    test("_hash", _hash, _hashString);
+    test("_dollar", _dollar, _dollarString);
+    test("_percent", _percent, _percentString);
+    test("_ampersand", _ampersand, _ampersandString);
+    test("_apostrophe", _apostrophe, _apostropheString);
+    test("_leftParen", _leftParen, _leftParenString);
+    test("_rightParen", _rightParen, _rightParenString);
+    test("_asterisk", _asterisk, _asteriskString);
+    test("_plus", _plus, _plusString);
+    test("_comma", _comma, _commaString);
+    test("_minus", _minus, _minusString);
+    test("_period", _period, _periodString);
+    test("_slash", _slash, _slashString);
+    test("_colon", _colon, _colonString);
+    test("_semicolon", _semicolon, _semicolonString);
+    test("_lessThan", _lessThan, _lessThanString);
+    test("_equals", _equals, _equalsString);
+    test("_greaterThan", _greaterThan, _greaterThanString);
+    test("_question", _question, _questionString);
+    test("_at", _at, _atString);
+    test("_leftBracket", _leftBracket, _leftBracketString);
+    test("_backslash", _backslash, _backslashString);
+    test("_rightBracket", _rightBracket, _rightBracketString);
+    test("_circumflex", _circumflex, _circumflexString);
+    test("_underscore", _underscore, _underscoreString);
+    test("_backtick", _backtick, _backtickString);
+    test("_leftBrace", _leftBrace, _leftBraceString);
+    test("_vertical", _vertical, _verticalString);
+    test("_rightBrace", _rightBrace, _rightBraceString);
+    test("_tilde", _tilde, _tildeString);
+  }
 }
diff --git a/sdk/lib/convert/encoding.dart b/sdk/lib/convert/encoding.dart
index 7441e0a..7ce8ec3 100644
--- a/sdk/lib/convert/encoding.dart
+++ b/sdk/lib/convert/encoding.dart
@@ -19,8 +19,8 @@
   Converter<List<int>, String> get decoder;
 
   Future<String> decodeStream(Stream<List<int>> byteStream) {
-    return byteStream
-        .transform<String>(decoder)
+    return decoder
+        .bind(byteStream)
         .fold(StringBuffer(),
             (StringBuffer buffer, String string) => buffer..write(string))
         .then((StringBuffer buffer) => buffer.toString());
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index fff3d7a..a0f67ac 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -464,8 +464,8 @@
    * This increases the length of the list by one and shifts all objects
    * at or after the index towards the end of the list.
    *
-   * An error occurs if the [index] is less than 0 or greater than length.
-   * An [UnsupportedError] occurs if the list is fixed-length.
+   * The list must be growable.
+   * The [index] value must be non-negative and no greater than [length].
    */
   void insert(int index, E element);
 
@@ -475,8 +475,8 @@
    * This increases the length of the list by the length of [iterable] and
    * shifts all later objects towards the end of the list.
    *
-   * An error occurs if the [index] is less than 0 or greater than length.
-   * An [UnsupportedError] occurs if the list is fixed-length.
+   * The list must be growable.
+   * The [index] value must be non-negative and no greater than [length].
    */
   void insertAll(int index, Iterable<E> iterable);
 
@@ -537,6 +537,8 @@
   /**
    * Pops and returns the last object in this list.
    *
+   * The list must not be empty.
+   *
    * Throws an [UnsupportedError] if this is a fixed-length list.
    */
   E removeLast();
@@ -674,6 +676,14 @@
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
    * `len` is this list's `length`. The range starts at `start` and has length
    * `end - start`. An empty range (with `end == start`) is valid.
+   *
+   * Example:
+   * ```dart
+   *  List<int> list = new List(3);
+   *     list.fillRange(0, 2, 1);
+   *     print(list); //  [1, 1, null]
+   * ```
+   *
    */
   void fillRange(int start, int end, [E fillValue]);
 
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 748933d..b3046cc 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -12,7 +12,7 @@
  *
  * Dart regular expressions have the same syntax and semantics as
  * JavaScript regular expressions. See
- * <http://ecma-international.org/ecma-262/5.1/#sec-15.10>
+ * <https://ecma-international.org/ecma-262/9.0/#sec-regexp-regular-expression-objects>
  * for the specification of JavaScript regular expressions.
  *
  * [firstMatch] is the main implementation method that applies a regular
diff --git a/sdk/lib/ffi/annotations.dart b/sdk/lib/ffi/annotations.dart
index 24401e6..d246b56 100644
--- a/sdk/lib/ffi/annotations.dart
+++ b/sdk/lib/ffi/annotations.dart
@@ -4,19 +4,6 @@
 
 part of dart.ffi;
 
-class Struct {
-  const Struct();
-}
-
-/// This Dart class represents a C struct.
-///
-/// Fields in this struct, annotated with a subtype of [NativeType], are
-/// automatically transformed into wrappers to access the fields of the struct
-/// in C memory.
-///
-/// Fields without a [NativeType] annotation are not supported.
-const struct = const Struct();
-
 class DartRepresentationOf {
   /// Represents the Dart type corresponding to a [NativeType].
   ///
@@ -32,9 +19,9 @@
   /// [Double]                             -> [double]
   /// [Float]                              -> [double]
   /// [Pointer]<T>                         -> [Pointer]<T>
-  /// T extends [Pointer]                  -> T
   /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
   ///    where DartRepresentationOf(Tn) -> Sn
+  /// T extends Struct<T>                  -> T
   const DartRepresentationOf(String nativeType);
 }
 
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index 98aa64a..46d660e 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -20,13 +20,15 @@
   external Pointer<T> lookup<T extends NativeType>(String symbolName);
 
   /// Helper that combines lookup and cast to a Dart function.
-  F lookupFunction<T extends Function, F extends Function>(String symbolName) {
-    return lookup<NativeFunction<T>>(symbolName)?.asFunction<F>();
-  }
+  external F lookupFunction<T extends Function, F extends Function>(
+      String symbolName);
 
   /// Dynamic libraries are equal if they load the same library.
   external bool operator ==(other);
 
   /// The hash code for a DynamicLibrary only depends on the loaded library
   external int get hashCode;
+
+  /// The handle to the dynamic library.
+  external Pointer<Void> get handle;
 }
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
index 5176ebb..4b9a50f 100644
--- a/sdk/lib/ffi/ffi.dart
+++ b/sdk/lib/ffi/ffi.dart
@@ -9,81 +9,83 @@
 part "native_type.dart";
 part "annotations.dart";
 part "dynamic_library.dart";
+part "struct.dart";
 
-/// Allocate [count] elements of type [T] on the C heap with malloc() and return
-/// a pointer to the newly allocated memory.
+/// Number of bytes used by native type T.
 ///
-/// Note that the memory are uninitialized.
-///
-/// TODO(dacoharkes): change signature to T allocate<T extends Pointer>() ?
-/// This would enable us to allocate structs. However how do we know the size of
-/// structs? https://github.com/dart-lang/sdk/issues/35782
-external Pointer<T> allocate<T extends NativeType>({int count: 1});
-
-/// Construction from raw value
-external T fromAddress<T extends Pointer>(int ptr);
-
-/// number of bytes used by native type T
+/// Includes padding and alignment of structs.
 external int sizeOf<T extends NativeType>();
 
-/// Convert Dart function to a C function pointer, automatically marshalling
-/// the arguments and return value
-///
-/// Note: this is not implemented, always returns Pointer with address 0.
-///
-/// TODO(dacoharkes): Implement this feature.
-/// https://github.com/dart-lang/sdk/issues/35761
-external Pointer<NativeFunction<T>> fromFunction<T extends Function>(
-    @DartRepresentationOf("T") Function f);
-
-/*
-/// TODO(dacoharkes): Implement this feature.
-/// https://github.com/dart-lang/sdk/issues/35770
-/// Return a pointer object that has a finalizer attached to it. When this
-/// pointer object is collected by GC the given finalizer is invoked.
-///
-/// Note: the pointer object passed to the finalizer is not the same as
-/// the pointer object that is returned from [finalizable] - it points
-/// to the same memory region but has different identity.
-external Pointer<T> finalizable<T extends NativeType>(
-    Pointer<T> p, void finalizer(Pointer<T> ptr));
-*/
-
 /// Represents a pointer into the native C memory.
+final Pointer<Void> nullptr = Pointer.fromAddress(0);
+
+/// Represents a pointer into the native C memory. Cannot be extended.
+@pragma("vm:entry-point")
 class Pointer<T extends NativeType> extends NativeType {
   const Pointer();
 
+  /// Allocate [count] elements of type [T] on the native heap via malloc() and
+  /// return a pointer to the newly allocated memory.
+  ///
+  /// Note that the memory is uninitialized.
+  external factory Pointer.allocate({int count: 1});
+
+  /// Construction from raw integer.
+  external factory Pointer.fromAddress(int ptr);
+
+  /// Convert Dart function to a C function pointer, automatically marshalling
+  /// the arguments and return value
+  ///
+  /// If an exception is thrown while calling `f()`, the native function will
+  /// return `exceptionalReturn`, which must be assignable to return type of `f`.
+  ///
+  /// The returned function address can only be invoked on the mutator (main)
+  /// thread of the current isolate. It will abort the process if invoked on any
+  /// other thread.
+  ///
+  /// The pointer returned will remain alive for the duration of the current
+  /// isolate's lifetime. After the isolate it was created in is terminated,
+  /// invoking it from native code will cause undefined behavior.
+  ///
+  /// Does not accept dynamic invocations -- where the type of the receiver is
+  /// [dynamic].
+  external static Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+      @DartRepresentationOf("T") Function f, Object exceptionalReturn);
+
   /// Store a Dart value into this location.
   ///
-  /// The [value] is automatically marshalled into its C representation.
+  /// The [value] is automatically marshalled into its native representation.
   /// Note that ints which do not fit in [T] are truncated and sign extended,
   /// and doubles stored into Pointer<[Float]> lose precision.
   external void store(@DartRepresentationOf("T") Object value);
 
   /// Load a Dart value from this location.
   ///
-  /// The value is automatically unmarshalled from its C representation.
+  /// The value is automatically unmarshalled from its native representation.
+  /// Loading a [Struct] reference returns a reference backed by native memory
+  /// (the same pointer as it's loaded from).
   external R load<@DartRepresentationOf("T") R>();
 
   /// Access to the raw pointer value.
+  /// On 32-bit systems, the upper 32-bits of the result are 0.
   external int get address;
 
   /// Pointer arithmetic (takes element size into account).
   external Pointer<T> elementAt(int index);
 
   /// Pointer arithmetic (byte offset).
-  ///
-  /// TODO(dacoharkes): remove this?
-  /// https://github.com/dart-lang/sdk/issues/35883
+  // TODO(dacoharkes): remove this?
+  // https://github.com/dart-lang/sdk/issues/35883
   external Pointer<T> offsetBy(int offsetInBytes);
 
-  /// Cast Pointer<T> to a (subtype of) Pointer<V>.
-  external U cast<U extends Pointer>();
+  /// Cast Pointer<T> to a Pointer<V>.
+  external Pointer<U> cast<U extends NativeType>();
 
   /// Convert to Dart function, automatically marshalling the arguments
   /// and return value.
   ///
-  /// Can only be called on [Pointer]<[NativeFunction]>.
+  /// Can only be called on [Pointer]<[NativeFunction]>. Does not accept dynamic
+  /// invocations -- where the type of the receiver is [dynamic].
   external R asFunction<@DartRepresentationOf("T") R extends Function>();
 
   /// Free memory on the C heap pointed to by this pointer with free().
diff --git a/sdk/lib/ffi/ffi_sources.gni b/sdk/lib/ffi/ffi_sources.gni
index d67b267..d2bb279 100644
--- a/sdk/lib/ffi/ffi_sources.gni
+++ b/sdk/lib/ffi/ffi_sources.gni
@@ -8,5 +8,6 @@
   # The above file needs to be first as it lists the parts below.
   "annotations.dart",
   "dynamic_library.dart",
-  "native_type.dart"
+  "native_type.dart",
+  "struct.dart"
 ]
diff --git a/sdk/lib/ffi/struct.dart b/sdk/lib/ffi/struct.dart
new file mode 100644
index 0000000..23124eb
--- /dev/null
+++ b/sdk/lib/ffi/struct.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2019, 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.
+
+part of dart.ffi;
+
+/// This class is extended to define structs.
+///
+/// Fields in a struct, annotated with a subtype of [NativeType], are
+/// automatically transformed into wrappers to access the fields of the struct
+/// in native memory.
+///
+/// All fields in a struct must either have a type which extends [NativeType] or
+/// else have an annotation indicating the corresponding native type (e.g.
+/// "@Int32()" for "int").
+///
+/// Instances of a subclass of [Struct] have reference semantics and are backed
+/// by native memory. The may allocated via [Pointer.allocate] or loaded from a
+/// [Pointer], but not by a generative constructor.
+abstract class Struct<S extends NativeType> extends NativeType {
+  /// Returns the address backing the reference.
+  final Pointer<S> addressOf;
+
+  Struct() : addressOf = null;
+  Struct.fromPointer(this.addressOf);
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index eb75be5..e9c8707 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -18416,7 +18416,7 @@
 
 // Interfaces representing the InputElement APIs which are supported
 // for the various types of InputElement. From:
-// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.
+// https://w3c.github.io/html/sec-forms.html#the-input-element.
 
 /**
  * Exposes the functionality common between all InputElement types.
@@ -36425,7 +36425,7 @@
 abstract class KeyCode {
   // These constant names were borrowed from Closure's Keycode enumeration
   // class.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
   static const int WIN_KEY_FF_LINUX = 0;
   static const int MAC_ENTER = 3;
   static const int BACKSPACE = 8;
@@ -37285,7 +37285,7 @@
  */
 class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
   // This code inspired by Closure's KeyHandling library.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js
 
   /**
    * The set of keys that have been pressed down without seeing their
@@ -37310,7 +37310,7 @@
   /**
    * An enumeration of key identifiers currently part of the W3C draft for DOM3
    * and their mappings to keyCodes.
-   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+   * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/keyset.html#KeySet-Set
    */
   static const Map<String, int> _keyIdentifier = const {
     'Up': KeyCode.UP,
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 861ce47..768ba51 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -483,7 +483,7 @@
    * must be read to completion or the subscription on the stream must
    * be cancelled.
    */
-  Stream<List<int>> openRead([int start, int end]);
+  Stream<Uint8List> openRead([int start, int end]);
 
   /**
    * Creates a new independent [IOSink] for the file. The
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 68d8b1b..66a4134 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -7,9 +7,9 @@
 // Read the file in blocks of size 64k.
 const int _blockSize = 64 * 1024;
 
-class _FileStream extends Stream<List<int>> {
+class _FileStream extends Stream<Uint8List> {
   // Stream controller.
-  StreamController<List<int>> _controller;
+  StreamController<Uint8List> _controller;
 
   // Information about the underlying file.
   String _path;
@@ -33,7 +33,7 @@
 
   _FileStream.forStdin() : _position = 0;
 
-  StreamSubscription<List<int>> listen(void onData(List<int> event),
+  StreamSubscription<Uint8List> listen(void onData(Uint8List event),
       {Function onError, void onDone(), bool cancelOnError}) {
     _setupController();
     return _controller.stream.listen(onData,
@@ -41,7 +41,7 @@
   }
 
   void _setupController() {
-    _controller = new StreamController<List<int>>(
+    _controller = new StreamController<Uint8List>(
         sync: true,
         onListen: _start,
         onResume: _readBlock,
@@ -498,7 +498,7 @@
     return new _RandomAccessFile(id, "");
   }
 
-  Stream<List<int>> openRead([int start, int end]) {
+  Stream<Uint8List> openRead([int start, int end]) {
     return new _FileStream(path, start, end);
   }
 
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 63b32b3..8d76549 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -825,12 +825,12 @@
 }
 
 /**
- * Datagram package. Data send to and received from datagram sockets
+ * Datagram package. Data sent to and received from datagram sockets
  * contains the internet address and port of the destination or source
  * togeter with the data.
  */
 class Datagram {
-  List<int> data;
+  Uint8List data;
   InternetAddress address;
   int port;
 
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index 5321ddf..b51c141 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -10,6 +10,16 @@
 LibTest/html/*: SkipByDesign # d8 is not a browser
 WebPlatformTest/*: SkipByDesign # d8 is not a browser
 
+[ $compiler == dart2js && $runtime == d8 && $host_checked ]
+LibTest/collection/ListBase/ListBase_class_A01_t04: Slow
+LibTest/collection/ListBase/ListBase_class_A01_t05: Slow
+LibTest/collection/ListBase/ListBase_class_A01_t06: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t04: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t05: Slow
+LibTest/collection/ListMixin/ListMixin_class_A01_t06: Slow
+LibTest/core/List/List_class_A01_t05: Slow
+LibTest/core/List/List_class_A01_t06: Slow
+
 [ $compiler == dart2js && $runtime == ie11 ]
 LibTest/collection/ListBase/ListBase_class_A01_t04: SkipSlow # slow babeljs transformation
 LibTest/collection/ListBase/ListBase_class_A01_t05: SkipSlow # slow babeljs transformation
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 48b24cc..e74c130 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -50,8 +50,6 @@
 LibTest/io/exit/exit_A01_t01: RuntimeError
 LibTest/io/exit/exit_A02_t01: RuntimeError
 LibTest/io/exitCode/exitCode_A01_t01: RuntimeError
-LibTest/isolate/Isolate/spawnUri_A01_t02: RuntimeError
-LibTest/isolate/Isolate/spawnUri_A05_t05: RuntimeError
 LibTest/isolate/ReceivePort/lastWhere_A01_t01: RuntimeError
 
 [ $compiler == fasta ]
@@ -1432,3 +1430,10 @@
 LibTest/math/MutableRectangle/width_A03_t02: RuntimeError
 LibTest/math/Rectangle/Rectangle_A03_t04: RuntimeError
 Utils/tests/Expect/throws_A01_t04: RuntimeError
+
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+LibTest/isolate/Isolate/spawnUri*: Skip
diff --git a/tests/compiler/dart2js/closure/data/captured_variable.dart b/tests/compiler/dart2js/closure/data/captured_variable.dart
index e5dc4b2..409184d 100644
--- a/tests/compiler/dart2js/closure/data/captured_variable.dart
+++ b/tests/compiler/dart2js/closure/data/captured_variable.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: boxedLoopVariableExample:*/
+/*member: boxedLoopVariableExample:*/
 boxedLoopVariableExample() {
   var input = [1, 2, 3];
   var fs = [];
@@ -15,25 +15,25 @@
   return fs;
 }
 
-/*element: readParameterInAnonymousClosure:*/
+/*member: readParameterInAnonymousClosure:*/
 readParameterInAnonymousClosure(/**/ parameter) {
   return /*fields=[parameter],free=[parameter]*/ () => parameter;
 }
 
-/*element: readParameterInClosure:*/
+/*member: readParameterInClosure:*/
 readParameterInClosure(/**/ parameter) {
   /*fields=[parameter],free=[parameter]*/ func() => parameter;
   return func;
 }
 
-/*element: writeParameterInAnonymousClosure:box=(box0 which holds [parameter])*/
+/*member: writeParameterInAnonymousClosure:box=(box0 which holds [parameter])*/
 writeParameterInAnonymousClosure(/*boxed*/ parameter) {
   return /*fields=[box0],free=[box0,parameter]*/ () {
     parameter = 42;
   };
 }
 
-/*element: writeParameterInClosure:box=(box0 which holds [parameter])*/
+/*member: writeParameterInClosure:box=(box0 which holds [parameter])*/
 writeParameterInClosure(/*boxed*/ parameter) {
   /*fields=[box0],free=[box0,parameter]*/ func() {
     parameter = 43;
@@ -42,20 +42,20 @@
   return func;
 }
 
-/*element: readLocalInAnonymousClosure:*/
+/*member: readLocalInAnonymousClosure:*/
 readLocalInAnonymousClosure(/**/ parameter) {
   var /**/ local = parameter;
   return /*fields=[local],free=[local]*/ () => local;
 }
 
-/*element: readLocalInClosure:*/
+/*member: readLocalInClosure:*/
 readLocalInClosure(/**/ parameter) {
   var /**/ local = parameter;
   /*fields=[local],free=[local]*/ func() => local;
   return func;
 }
 
-/*element: writeLocalInAnonymousClosure:box=(box0 which holds [local])*/
+/*member: writeLocalInAnonymousClosure:box=(box0 which holds [local])*/
 writeLocalInAnonymousClosure(/**/ parameter) {
   // ignore: UNUSED_LOCAL_VARIABLE
   var /*boxed*/ local = parameter;
@@ -64,7 +64,7 @@
   };
 }
 
-/*element: writeLocalInClosure:box=(box0 which holds [local])*/
+/*member: writeLocalInClosure:box=(box0 which holds [local])*/
 writeLocalInClosure(/**/ parameter) {
   // ignore: UNUSED_LOCAL_VARIABLE
   var /*boxed*/ local = parameter;
@@ -75,25 +75,25 @@
   return func;
 }
 
-/*element: Foo.:hasThis*/
+/*member: Foo.:hasThis*/
 class Foo {
-  int /*element: Foo.bar:hasThis*/ bar = 4;
+  int /*member: Foo.bar:hasThis*/ bar = 4;
 
-  /*element: Foo.baz:hasThis*/ baz() {
+  /*member: Foo.baz:hasThis*/ baz() {
     /*fields=[this],free=[this],hasThis*/ func() => bar;
     return func;
   }
 }
 
-/*element: Repro.:hasThis*/
+/*member: Repro.:hasThis*/
 class Repro {
-  /*element: Repro.qux:hasThis*/ qux() {
+  /*member: Repro.qux:hasThis*/ qux() {
     /*fields=[this],free=[this],hasThis*/ threeNested(foo) =>
         /*fields=[this],free=[this],hasThis*/ (bar) => someFunction();
     return threeNested;
   }
 
-  /*element: Repro.someFunction:hasThis*/ someFunction() => 3;
+  /*member: Repro.someFunction:hasThis*/ someFunction() => 3;
 }
 
 main() {
diff --git a/tests/compiler/dart2js/closure/data/generic.dart b/tests/compiler/dart2js/closure/data/generic.dart
index 8823cb6..c1a3f5d 100644
--- a/tests/compiler/dart2js/closure/data/generic.dart
+++ b/tests/compiler/dart2js/closure/data/generic.dart
@@ -3,44 +3,44 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class1<T> {
-  /*element: Class1.field:hasThis*/
+  /*member: Class1.field:hasThis*/
   var field = /*fields=[T],free=[T],hasThis*/ () => T;
 
-  /*element: Class1.funcField:hasThis*/
+  /*member: Class1.funcField:hasThis*/
   Function funcField;
 
-  /*element: Class1.:hasThis*/
+  /*member: Class1.:hasThis*/
   Class1() {
     field = /*fields=[T],free=[T],hasThis*/ () => T;
   }
 
-  /*element: Class1.setFunc:hasThis*/
+  /*member: Class1.setFunc:hasThis*/
   Class1.setFunc(this.funcField);
 
-  /*element: Class1.fact:*/
+  /*member: Class1.fact:*/
   factory Class1.fact() => new Class1<T>();
 
-  /*element: Class1.fact2:*/
+  /*member: Class1.fact2:*/
   factory Class1.fact2() =>
       new Class1.setFunc(/*fields=[T],free=[T]*/ () => new Set<T>());
 
-  /*element: Class1.method1:hasThis*/
+  /*member: Class1.method1:hasThis*/
   method1() => T;
 
-  /*element: Class1.method2:hasThis*/
+  /*member: Class1.method2:hasThis*/
   method2() {
     return /*fields=[this],free=[this],hasThis*/ () => T;
   }
 
-  /*element: Class1.method3:hasThis*/
+  /*member: Class1.method3:hasThis*/
   method3<S>() => S;
 
-  /*element: Class1.method4:hasThis*/
+  /*member: Class1.method4:hasThis*/
   method4<S>() {
     return /*fields=[S],free=[S],hasThis*/ () => S;
   }
 
-  /*element: Class1.method5:hasThis*/
+  /*member: Class1.method5:hasThis*/
   method5() {
     /*hasThis*/ local<S>() {
       return /*fields=[S],free=[S],hasThis*/ () => S;
@@ -49,7 +49,7 @@
     return local<double>();
   }
 
-  /*element: Class1.method6:hasThis*/
+  /*member: Class1.method6:hasThis*/
   method6<S>() {
     /*fields=[S],free=[S],hasThis*/ local<U>() {
       return /*fields=[S,U],free=[S,U],hasThis*/ () => '$S$U';
@@ -67,15 +67,15 @@
     return local2(local<double>());
   }
 
-  /*element: Class1.staticMethod1:*/
+  /*member: Class1.staticMethod1:*/
   static staticMethod1<S>() => S;
 
-  /*element: Class1.staticMethod2:*/
+  /*member: Class1.staticMethod2:*/
   static staticMethod2<S>() {
     return /*fields=[S],free=[S]*/ () => S;
   }
 
-  /*element: Class1.staticMethod3:*/
+  /*member: Class1.staticMethod3:*/
   static staticMethod3() {
     local<S>() {
       return /*fields=[S],free=[S]*/ () => S;
@@ -84,7 +84,7 @@
     return local<double>();
   }
 
-  /*element: Class1.staticMethod4:*/
+  /*member: Class1.staticMethod4:*/
   static staticMethod4<S>() {
     /*fields=[S],free=[S]*/ local<U>() {
       return /*fields=[S,U],free=[S,U]*/ () => '$S$U';
@@ -97,15 +97,15 @@
   }
 }
 
-/*element: topLevelMethod1:*/
+/*member: topLevelMethod1:*/
 topLevelMethod1<S>() => S;
 
-/*element: topLevelMethod2:*/
+/*member: topLevelMethod2:*/
 topLevelMethod2<S>() {
   return /*fields=[S],free=[S]*/ () => S;
 }
 
-/*element: topLevelMethod3:*/
+/*member: topLevelMethod3:*/
 topLevelMethod3() {
   local<S>() {
     return /*fields=[S],free=[S]*/ () => S;
@@ -114,7 +114,7 @@
   return local<double>();
 }
 
-/*element: topLevelMethod4:*/
+/*member: topLevelMethod4:*/
 topLevelMethod4<S>() {
   /*fields=[S],free=[S]*/ local<U>() {
     return /*fields=[S,U],free=[S,U]*/ () => '$S$U';
@@ -126,7 +126,7 @@
   return local2(local<double>());
 }
 
-/*element: main:*/
+/*member: main:*/
 main() {
   new Class1<int>().method1();
   new Class1<int>.fact().method2();
diff --git a/tests/compiler/dart2js/closure/data/instantiation1.dart b/tests/compiler/dart2js/closure/data/instantiation1.dart
index 22e5276..e8ba217 100644
--- a/tests/compiler/dart2js/closure/data/instantiation1.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation1.dart
@@ -6,9 +6,9 @@
 
 typedef int F<R>(R a);
 
-/*element: B.:hasThis*/
+/*member: B.:hasThis*/
 class B<S> {
-  /*element: B.method:hasThis*/
+  /*member: B.method:hasThis*/
   method() {
     return
         /*strong.fields=[this],free=[this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/instantiation2.dart b/tests/compiler/dart2js/closure/data/instantiation2.dart
index c1f6335..d3a616f 100644
--- a/tests/compiler/dart2js/closure/data/instantiation2.dart
+++ b/tests/compiler/dart2js/closure/data/instantiation2.dart
@@ -6,9 +6,9 @@
 
 typedef bool F<R>(R a);
 
-/*element: B.:hasThis*/
+/*member: B.:hasThis*/
 class B<S> {
-  /*element: B.method:hasThis*/
+  /*member: B.method:hasThis*/
   method() {
     return
         /*strong.fields=[this],free=[this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/list_literal_class.dart b/tests/compiler/dart2js/closure/data/list_literal_class.dart
index 4384e6b..080bb77 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_class.dart
@@ -4,9 +4,9 @@
 
 import 'package:expect/expect.dart';
 
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
 class A<T> {
-  /*element: A.method:hasThis*/
+  /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
     /*fields=[this],free=[this],hasThis*/ dynamic local() => <T>[];
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
index 997fd78..a20f0b8 100644
--- a/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_class.dart
@@ -4,9 +4,9 @@
 
 import 'package:expect/expect.dart';
 
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
 class A<T> {
-  /*element: A.method:hasThis*/
+  /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
     /*omit.hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/map_literal_class.dart b/tests/compiler/dart2js/closure/data/map_literal_class.dart
index 975b5ee..f6f1f0c 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_class.dart
@@ -4,9 +4,9 @@
 
 import 'package:expect/expect.dart';
 
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
 class A<T> {
-  /*element: A.method:hasThis*/
+  /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
     /*fields=[this],free=[this],hasThis*/ dynamic local() => <T, int>{};
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
index 7161fd6..da671a3 100644
--- a/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_class.dart
@@ -4,9 +4,9 @@
 
 import 'package:expect/expect.dart';
 
-/*element: A.:hasThis*/
+/*member: A.:hasThis*/
 class A<T> {
-  /*element: A.method:hasThis*/
+  /*member: A.method:hasThis*/
   @pragma('dart2js:noInline')
   method() {
     /*omit.hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/mixed.dart b/tests/compiler/dart2js/closure/data/mixed.dart
index 2cec1c4..20fdcbe 100644
--- a/tests/compiler/dart2js/closure/data/mixed.dart
+++ b/tests/compiler/dart2js/closure/data/mixed.dart
@@ -5,7 +5,7 @@
 // Test that free variables aren't mixed between capturing and non-capturing
 // closures.
 
-/*element: mutateInClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInClosure:box=(box0 which holds [localVar])*/
 mutateInClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -17,7 +17,7 @@
   return localVar;
 }
 
-/*element: mutateOutsideClosure:box=(box0 which holds [localVar])*/
+/*member: mutateOutsideClosure:box=(box0 which holds [localVar])*/
 mutateOutsideClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -30,7 +30,7 @@
   return localVar;
 }
 
-/*element: mutateInOtherClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInOtherClosure:box=(box0 which holds [localVar])*/
 mutateInOtherClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -45,7 +45,7 @@
   return localVar;
 }
 
-/*element: mutateInNestedClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInNestedClosure:box=(box0 which holds [localVar])*/
 mutateInNestedClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
diff --git a/tests/compiler/dart2js/closure/data/mutations.dart b/tests/compiler/dart2js/closure/data/mutations.dart
index e0524d2..8516ba3 100644
--- a/tests/compiler/dart2js/closure/data/mutations.dart
+++ b/tests/compiler/dart2js/closure/data/mutations.dart
@@ -4,7 +4,7 @@
 
 // Test that captured variables are boxed regardless of where they are mutated.
 
-/*element: mutateUnused:*/
+/*member: mutateUnused:*/
 mutateUnused() {
   var localVar;
   /**/ () {
@@ -14,7 +14,7 @@
   return localVar;
 }
 
-/*element: mutateInClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInClosure:box=(box0 which holds [localVar])*/
 mutateInClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -23,7 +23,7 @@
   return localVar;
 }
 
-/*element: mutateOutsideClosure:box=(box0 which holds [localVar])*/
+/*member: mutateOutsideClosure:box=(box0 which holds [localVar])*/
 mutateOutsideClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -33,7 +33,7 @@
   return localVar;
 }
 
-/*element: mutateInOtherClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInOtherClosure:box=(box0 which holds [localVar])*/
 mutateInOtherClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
@@ -45,7 +45,7 @@
   return localVar;
 }
 
-/*element: mutateInNestedClosure:box=(box0 which holds [localVar])*/
+/*member: mutateInNestedClosure:box=(box0 which holds [localVar])*/
 mutateInNestedClosure() {
   var /*boxed*/ localVar;
   /*fields=[box0],free=[box0,localVar]*/ () {
diff --git a/tests/compiler/dart2js/closure/data/nested_closures.dart b/tests/compiler/dart2js/closure/data/nested_closures.dart
index 1dad607..2f2cb12 100644
--- a/tests/compiler/dart2js/closure/data/nested_closures.dart
+++ b/tests/compiler/dart2js/closure/data/nested_closures.dart
@@ -4,7 +4,7 @@
 
 /// Test boxing/captures for nested closures.
 
-/*element: useOne:box=(box0 which holds [b1])*/ useOne(/*boxed*/ b1) {
+/*member: useOne:box=(box0 which holds [b1])*/ useOne(/*boxed*/ b1) {
   /*box=(box1 which holds [b2]),fields=[box0],free=[b1,box0]*/ () {
     var /*boxed*/ b2 = (b1 = 1);
 
@@ -17,7 +17,7 @@
   return b1;
 }
 
-/*element: useBoth:box=(box0 which holds [b1])*/ useBoth(/*boxed*/ b1) {
+/*member: useBoth:box=(box0 which holds [b1])*/ useBoth(/*boxed*/ b1) {
   /*box=(box1 which holds [b2]),fields=[box0],free=[b1,box0]*/ () {
     var /*boxed*/ b2 = (b1 = 1);
 
@@ -30,7 +30,7 @@
   return b1;
 }
 
-/*element: useMany:box=(box0 which holds [b1,b2,b3])*/
+/*member: useMany:box=(box0 which holds [b1,b2,b3])*/
 useMany(c1, /*boxed*/ b1) {
   var /*boxed*/ b2 = 2;
   var /*boxed*/ b3 = 3;
diff --git a/tests/compiler/dart2js/closure/data/test_type_class.dart b/tests/compiler/dart2js/closure/data/test_type_class.dart
index afa2f5b..222ca14 100644
--- a/tests/compiler/dart2js/closure/data/test_type_class.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_class.dart
@@ -6,9 +6,9 @@
 /// Explicit is-test is always required.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:hasThis*/
+/*member: Class1.:hasThis*/
 class Class1<T> {
-  /*element: Class1.method1:hasThis*/
+  /*member: Class1.method1:hasThis*/
   method1(dynamic o) {
     /*fields=[o,this],free=[o,this],hasThis*/
     dynamic local() => o is T;
@@ -20,9 +20,9 @@
 /// Explicit as-cast is always required.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:hasThis*/
+/*member: Class2.:hasThis*/
 class Class2<T> {
-  /*element: Class2.method2:hasThis*/
+  /*member: Class2.method2:hasThis*/
   method2(dynamic o) {
     /*fields=[o,this],free=[o,this],hasThis*/
     dynamic local() => o as T;
@@ -34,9 +34,9 @@
 /// Implicit as-cast is only required in strong mode.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:hasThis*/
+/*member: Class3.:hasThis*/
 class Class3<T> {
-  /*element: Class3.method3:hasThis*/
+  /*member: Class3.method3:hasThis*/
   method3(dynamic o) {
     /*omit.fields=[o],free=[o],hasThis*/
     /*strong.fields=[o,this],free=[o,this],hasThis*/
diff --git a/tests/compiler/dart2js/closure/data/test_type_method.dart b/tests/compiler/dart2js/closure/data/test_type_method.dart
index cb8f88d..bab82c3 100644
--- a/tests/compiler/dart2js/closure/data/test_type_method.dart
+++ b/tests/compiler/dart2js/closure/data/test_type_method.dart
@@ -6,7 +6,7 @@
 /// Explicit is-test is always required.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: method1:*/
+/*member: method1:*/
 method1<T>(dynamic o) {
   /*fields=[T,o],free=[T,o]*/
   dynamic local() => o is T;
@@ -17,7 +17,7 @@
 /// Explicit as-cast is always required.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: method2:*/
+/*member: method2:*/
 method2<T>(dynamic o) {
   /*fields=[T,o],free=[T,o]*/
   dynamic local() => o as T;
@@ -28,7 +28,7 @@
 /// Implicit as-cast is only required in strong mode.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: method3:*/
+/*member: method3:*/
 method3<T>(dynamic o) {
   /*strong.fields=[T,o],free=[T,o]*/
   /*omit.fields=[o],free=[o]*/
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_class.dart b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
index 84a8a53..853ffd6 100644
--- a/tests/compiler/dart2js/closure/data/type_annotations_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_annotations_class.dart
@@ -7,9 +7,9 @@
 /// variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:hasThis*/
+/*member: Class1.:hasThis*/
 class Class1<T> {
-  /*element: Class1.method1:hasThis*/
+  /*member: Class1.method1:hasThis*/
   method1(T o) {
     /*fields=[o],free=[o],hasThis*/
     dynamic local() {
@@ -25,9 +25,9 @@
 /// A sound assignment to a local variable doesn't capture the type variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
 class Class1b<T> {
-  /*element: Class1b.method1b:hasThis*/
+  /*member: Class1b.method1b:hasThis*/
   method1b(T o) {
     /*fields=[o],free=[o],hasThis*/
     dynamic local() {
@@ -44,9 +44,9 @@
 /// A local function parameter type is only captured in strong mode.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:hasThis*/
+/*member: Class2.:hasThis*/
 class Class2<T> {
-  /*element: Class2.method2:hasThis*/
+  /*member: Class2.method2:hasThis*/
   method2() {
     /*omit.hasThis*/
     /*strong.fields=[this],free=[this],hasThis*/
@@ -59,9 +59,9 @@
 /// A local function return type is only captured in strong mode.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:hasThis*/
+/*member: Class3.:hasThis*/
 class Class3<T> {
-  /*element: Class3.method3:hasThis*/
+  /*member: Class3.method3:hasThis*/
   method3(dynamic o) {
     /*omit.fields=[o],free=[o],hasThis*/
     /*strong.fields=[o,this],free=[o,this],hasThis*/
@@ -74,9 +74,9 @@
 /// A member parameter type is not captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:hasThis*/
+/*member: Class4.:hasThis*/
 class Class4<T> {
-  /*element: Class4.method4:hasThis*/
+  /*member: Class4.method4:hasThis*/
   method4(T o) {
     /*fields=[o],free=[o],hasThis*/
     dynamic local() => o;
@@ -88,9 +88,9 @@
 /// A member return type is not captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:hasThis*/
+/*member: Class5.:hasThis*/
 class Class5<T> {
-  /*element: Class5.method5:hasThis*/
+  /*member: Class5.method5:hasThis*/
   T method5(dynamic o) {
     /*fields=[o],free=[o],hasThis*/
     dynamic local() => o;
@@ -102,9 +102,9 @@
 /// A local function parameter type is not captured by an inner local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class6.:hasThis*/
+/*member: Class6.:hasThis*/
 class Class6<T> {
-  /*element: Class6.method6:hasThis*/
+  /*member: Class6.method6:hasThis*/
   method6() {
     /*omit.hasThis*/
     /*strong.fields=[this],free=[this],hasThis*/
@@ -122,9 +122,9 @@
 /// A local function return type is not captured by an inner local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class7.:hasThis*/
+/*member: Class7.:hasThis*/
 class Class7<T> {
-  /*element: Class7.method7:hasThis*/
+  /*member: Class7.method7:hasThis*/
   method7(dynamic o) {
     /*omit.fields=[o],free=[o],hasThis*/
     /*strong.fields=[o,this],free=[o,this],hasThis*/
@@ -142,9 +142,9 @@
 /// A field type is not captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class8.:hasThis*/
+/*member: Class8.:hasThis*/
 class Class8<T> {
-  /*element: Class8.field8:hasThis*/
+  /*member: Class8.field8:hasThis*/
   T field8 = /*hasThis*/ () {
     return null;
   }();
diff --git a/tests/compiler/dart2js/closure/data/type_arguments_class.dart b/tests/compiler/dart2js/closure/data/type_arguments_class.dart
index 8061663..2340013 100644
--- a/tests/compiler/dart2js/closure/data/type_arguments_class.dart
+++ b/tests/compiler/dart2js/closure/data/type_arguments_class.dart
@@ -7,12 +7,12 @@
 /// type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1a.:hasThis*/
+/*member: Class1a.:hasThis*/
 class Class1a<T> {}
 
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
 class Class1b<T> {
-  /*element: Class1b.method1:hasThis*/
+  /*member: Class1b.method1:hasThis*/
   method1() {
     /*fields=[this],free=[this],hasThis*/
     dynamic local() => new Class1a<T>();
@@ -25,12 +25,12 @@
 /// _not_ capture the type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2a.:hasThis*/
+/*member: Class2a.:hasThis*/
 class Class2a<T> {}
 
-/*element: Class2b.:hasThis*/
+/*member: Class2b.:hasThis*/
 class Class2b<T> {
-  /*element: Class2b.method2:hasThis*/
+  /*member: Class2b.method2:hasThis*/
   method2() {
     /*hasThis*/
     dynamic local() => new Class2a<T>();
diff --git a/tests/compiler/dart2js/closure/data/type_arguments_method.dart b/tests/compiler/dart2js/closure/data/type_arguments_method.dart
index 99733a8..ad35ada 100644
--- a/tests/compiler/dart2js/closure/data/type_arguments_method.dart
+++ b/tests/compiler/dart2js/closure/data/type_arguments_method.dart
@@ -7,12 +7,12 @@
 /// type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1a.:hasThis*/
+/*member: Class1a.:hasThis*/
 class Class1a<T> {}
 
-/*element: Class1b.:hasThis*/
+/*member: Class1b.:hasThis*/
 class Class1b<T> {
-  /*element: Class1b.method1:hasThis*/
+  /*member: Class1b.method1:hasThis*/
   method1() {
     /*fields=[this],free=[this],hasThis*/
     dynamic local() => new Class1a<T>();
@@ -25,12 +25,12 @@
 /// does _not_ capture the type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2a.:hasThis*/
+/*member: Class2a.:hasThis*/
 class Class2a<T> {}
 
-/*element: Class2b.:hasThis*/
+/*member: Class2b.:hasThis*/
 class Class2b<T> {
-  /*element: Class2b.method2:hasThis*/
+  /*member: Class2b.method2:hasThis*/
   method2() {
     /*hasThis*/
     dynamic local() => new Class2a<T>();
@@ -69,9 +69,9 @@
 /// the type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5a.:hasThis*/
+/*member: Class5a.:hasThis*/
 class Class5a {
-  /*element: Class5a.method5a:hasThis*/
+  /*member: Class5a.method5a:hasThis*/
   method5a<T>(o) => o is T;
 }
 
@@ -86,9 +86,9 @@
 /// arguments does _not_ capture the type variables.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class6a.:hasThis*/
+/*member: Class6a.:hasThis*/
 class Class6a {
-  /*element: Class6a.method6a:hasThis*/
+  /*member: Class6a.method6a:hasThis*/
   method6a<T>(o) => o;
 }
 
diff --git a/tests/compiler/dart2js/closure/data/type_variables.dart b/tests/compiler/dart2js/closure/data/type_variables.dart
index 7180c2b..1521b3a 100644
--- a/tests/compiler/dart2js/closure/data/type_variables.dart
+++ b/tests/compiler/dart2js/closure/data/type_variables.dart
@@ -3,37 +3,37 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class1<T> {
-  /*element: Class1.field:hasThis*/
+  /*member: Class1.field:hasThis*/
   var field = /*fields=[T],free=[T],hasThis*/ () => T;
 
-  /*element: Class1.funcField:hasThis*/
+  /*member: Class1.funcField:hasThis*/
   Function funcField;
 
-  /*element: Class1.:hasThis*/
+  /*member: Class1.:hasThis*/
   Class1() {
     field = /*fields=[T],free=[T],hasThis*/ () => T;
   }
 
-  /*element: Class1.setFunc:hasThis*/
+  /*member: Class1.setFunc:hasThis*/
   Class1.setFunc(this.funcField);
 
-  /*element: Class1.fact:*/
+  /*member: Class1.fact:*/
   factory Class1.fact() => new Class1<T>();
 
-  /*element: Class1.fact2:*/
+  /*member: Class1.fact2:*/
   factory Class1.fact2() =>
       new Class1.setFunc(/*fields=[T],free=[T]*/ () => new Set<T>());
 
-  /*element: Class1.method1:hasThis*/
+  /*member: Class1.method1:hasThis*/
   method1() => T;
 
-  /*element: Class1.method2:hasThis*/
+  /*member: Class1.method2:hasThis*/
   method2() {
     return /*fields=[this],free=[this],hasThis*/ () => T;
   }
 }
 
-/*element: main:*/
+/*member: main:*/
 main() {
   new Class1<int>().method1();
   new Class1<int>.fact().method2();
diff --git a/tests/compiler/dart2js/codegen/model_data/capture.dart b/tests/compiler/dart2js/codegen/model_data/capture.dart
index 5e44fb0..251c751 100644
--- a/tests/compiler/dart2js/codegen/model_data/capture.dart
+++ b/tests/compiler/dart2js/codegen/model_data/capture.dart
@@ -2,22 +2,22 @@
 // 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.
 
-/*element: method1:params=0*/
+/*member: method1:params=0*/
 @pragma('dart2js:noInline')
 method1([a]) => /*access=[a],params=0*/ () => a;
 
 class Class {
-  /*element: Class.f:emitted*/
+  /*member: Class.f:emitted*/
   @pragma('dart2js:noElision')
   var f;
 
-  /*element: Class.capture:params=0*/
+  /*member: Class.capture:params=0*/
   @pragma('dart2js:noInline')
   Class.capture([a]) : f = (/*access=[a],params=0*/ () => a);
 
   // TODO(johnniwinther): Remove the redundant assignment of elided boxed
   // parameters.
-  /*element: Class.box:assign=[a,a],params=0*/
+  /*member: Class.box:assign=[a,a],params=0*/
   @pragma('dart2js:noInline')
   Class.box([a])
       : f = (/*access=[_box_0],assign=[a],params=0*/ () {
@@ -28,11 +28,11 @@
 }
 
 class Subclass extends Class {
-  /*element: Subclass.capture:params=0*/
+  /*member: Subclass.capture:params=0*/
   @pragma('dart2js:noInline')
   Subclass.capture([a]) : super.internal(/*access=[a],params=0*/ () => a);
 
-  /*element: Subclass.box:assign=[a,a],params=0*/
+  /*member: Subclass.box:assign=[a,a],params=0*/
   @pragma('dart2js:noInline')
   Subclass.box([a])
       : super.internal(/*access=[_box_0],assign=[a],params=0*/ () {
@@ -40,7 +40,7 @@
         });
 }
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   method1();
   new Class.capture();
diff --git a/tests/compiler/dart2js/codegen/model_data/constant_folding.dart b/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
index 6ca83c8..ce74ab7 100644
--- a/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
+++ b/tests/compiler/dart2js/codegen/model_data/constant_folding.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-/*element: main:calls=[checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1)],params=0*/
+/*member: main:calls=[checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1),checkAll$1(1)],params=0*/
 void main() {
   const BitNot(42, 4294967253).check();
   const BitNot(4294967253, 42).check();
@@ -17,7 +17,7 @@
   const BitNot(0x12121212121212, 0xEDEDEDED).check();
 }
 
-/*element: jsEquals:calls=[Expect_equals(3),Expect_equals(3),get$isNegative(1),get$isNegative(1),toString$0(1),toString$0(1)],params=3*/
+/*member: jsEquals:calls=[Expect_equals(3),Expect_equals(3),get$isNegative(1),get$isNegative(1),toString$0(1),toString$0(1)],params=3*/
 void jsEquals(expected, actual, [String reason = null]) {
   if (expected is num && actual is num) {
     if (expected.isNaN && actual.isNaN) return;
@@ -42,7 +42,7 @@
 
   const TestOp(this.expected, this.result);
 
-  /*element: TestOp.checkAll:access=[arg,expected,result],calls=[jsEquals(3),jsEquals(3),jsEquals(3)],params=1*/
+  /*member: TestOp.checkAll:access=[arg,expected,result],calls=[jsEquals(3),jsEquals(3),jsEquals(3)],params=1*/
   @pragma('dart2js:noInline')
   checkAll(evalResult) {
     jsEquals(expected, result,
@@ -56,7 +56,7 @@
 }
 
 class BitNot extends TestOp {
-  /*element: BitNot.arg:emitted*/
+  /*member: BitNot.arg:emitted*/
   final arg;
 
   const BitNot(this.arg, expected) : super(expected, ~arg);
diff --git a/tests/compiler/dart2js/codegen/model_data/constructors.dart b/tests/compiler/dart2js/codegen/model_data/constructors.dart
index e7c0d8c..6d25ce6 100644
--- a/tests/compiler/dart2js/codegen/model_data/constructors.dart
+++ b/tests/compiler/dart2js/codegen/model_data/constructors.dart
@@ -3,94 +3,94 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class {
-  /*element: Class.constructor1:params=0*/
+  /*member: Class.constructor1:params=0*/
   @pragma('dart2js:noInline')
   Class.constructor1() {}
 
-  /*element: Class.constructor2a:params=0*/
+  /*member: Class.constructor2a:params=0*/
   @pragma('dart2js:noInline')
   Class.constructor2a([a]) {}
 
-  /*element: Class.constructor2b:params=1*/
+  /*member: Class.constructor2b:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor2b([a]) {}
 
-  /*element: Class.constructor2c:params=1*/
+  /*member: Class.constructor2c:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor2c([a]) {}
 
-  /*element: Class.constructor3a:params=0*/
+  /*member: Class.constructor3a:params=0*/
   @pragma('dart2js:noInline')
   Class.constructor3a([a, b]) {}
 
-  /*element: Class.constructor3b:params=1*/
+  /*member: Class.constructor3b:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor3b([a, b]) {}
 
-  /*element: Class.constructor3c:params=2*/
+  /*member: Class.constructor3c:params=2*/
   @pragma('dart2js:noInline')
   Class.constructor3c([a, b]) {}
 
-  /*element: Class.constructor4a:params=0*/
+  /*member: Class.constructor4a:params=0*/
   @pragma('dart2js:noInline')
   Class.constructor4a({a}) {}
 
-  /*element: Class.constructor4b:params=1*/
+  /*member: Class.constructor4b:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor4b({a}) {}
 
-  /*element: Class.constructor4c:params=1*/
+  /*member: Class.constructor4c:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor4c({a}) {}
 
-  /*element: Class.constructor5a:params=0*/
+  /*member: Class.constructor5a:params=0*/
   @pragma('dart2js:noInline')
   Class.constructor5a({a, b}) {}
 
-  /*element: Class.constructor5b:params=1*/
+  /*member: Class.constructor5b:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor5b({a, b}) {}
 
-  /*element: Class.constructor5c:params=1*/
+  /*member: Class.constructor5c:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor5c({a, b}) {}
 
-  /*element: Class.constructor6a:params=1*/
+  /*member: Class.constructor6a:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor6a(a, [b, c]) {}
 
-  /*element: Class.constructor6b:params=2*/
+  /*member: Class.constructor6b:params=2*/
   @pragma('dart2js:noInline')
   Class.constructor6b(a, [b, c]) {}
 
-  /*element: Class.constructor6c:params=3*/
+  /*member: Class.constructor6c:params=3*/
   @pragma('dart2js:noInline')
   Class.constructor6c(a, [b, c]) {}
 
-  /*element: Class.constructor7a:params=1*/
+  /*member: Class.constructor7a:params=1*/
   @pragma('dart2js:noInline')
   Class.constructor7a(a, {b, c}) {}
 
-  /*element: Class.constructor7b:params=2*/
+  /*member: Class.constructor7b:params=2*/
   @pragma('dart2js:noInline')
   Class.constructor7b(a, {b, c}) {}
 
-  /*element: Class.constructor7c:params=2*/
+  /*member: Class.constructor7c:params=2*/
   @pragma('dart2js:noInline')
   Class.constructor7c(a, {b, c}) {}
 
-  /*element: Class.constructor8a:params=2*/
+  /*member: Class.constructor8a:params=2*/
   @pragma('dart2js:noInline')
   @pragma('dart2js:noElision')
   Class.constructor8a([a, b]) {}
 
-  /*element: Class.constructor8b:params=2*/
+  /*member: Class.constructor8b:params=2*/
   @pragma('dart2js:noInline')
   @pragma('dart2js:noElision')
   Class.constructor8b({a, b}) {}
 }
 
-/*element: main:
+/*member: main:
  calls=[
   Class$constructor1(0),
   Class$constructor2a(0),
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
index e7f67fb..427eb7a 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   method1(new Class1a());
   method2(new Class2a<int>());
@@ -13,61 +13,61 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:emitted*/
+  /*member: Class1a.field1:emitted*/
   @pragma('dart2js:noElision')
   int field1;
 }
 
-/*element: method1:access=[field1],params=1*/
+/*member: method1:access=[field1],params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   return c.field1;
 }
 
 class Class2a<T> {
-  /*element: Class2a.field2:emitted*/
+  /*member: Class2a.field2:emitted*/
   @pragma('dart2js:noElision')
   T field2;
 }
 
-/*element: method2:access=[field2],params=1*/
+/*member: method2:access=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   return c.field2;
 }
 
 class Class3a {
-  /*element: Class3a.field3:emitted,get=simple*/
+  /*member: Class3a.field3:emitted,get=simple*/
   @pragma('dart2js:noElision')
   int field3;
 }
 
 class Class3b {
-  /*element: Class3b.field3:emitted,get=simple*/
+  /*member: Class3b.field3:emitted,get=simple*/
   @pragma('dart2js:noElision')
   int field3;
 }
 
-/*element: method3:calls=[get$field3(0)],params=1*/
+/*member: method3:calls=[get$field3(0)],params=1*/
 @pragma('dart2js:noInline')
 method3(dynamic c) {
   return c.field3;
 }
 
 class Class4a {
-  /*element: Class4a.field4:emitted,get=simple*/
+  /*member: Class4a.field4:emitted,get=simple*/
   @pragma('dart2js:noElision')
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*element: Class4b.field4:emitted,get=simple*/
+  /*member: Class4b.field4:emitted,get=simple*/
   @pragma('dart2js:noElision')
   @override
   int field4;
 }
 
-/*element: method4:calls=[get$field4(0)],params=1*/
+/*member: method4:calls=[get$field4(0)],params=1*/
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   return c.field4;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index 7694ba4..ed3aa49 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   method1(new Class1a()..field1);
   method2(new Class2a<int>()..field2);
@@ -13,73 +13,73 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:emitted*/
+  /*member: Class1a.field1:emitted*/
   int field1;
 }
 
-/*element: method1:assign=[field1],params=1*/
+/*member: method1:assign=[field1],params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   c.field1 = 42;
 }
 
 class Class2a<T> {
-  /*strong.element: Class2a.field2:checked,emitted*/
-  /*omit.element: Class2a.field2:emitted*/
-  /*strongConst.element: Class2a.field2:checked,emitted*/
-  /*omitConst.element: Class2a.field2:emitted*/
+  /*strong.member: Class2a.field2:checked,emitted*/
+  /*omit.member: Class2a.field2:emitted*/
+  /*strongConst.member: Class2a.field2:checked,emitted*/
+  /*omitConst.member: Class2a.field2:emitted*/
   T field2;
 }
 
-/*strong.element: method2:calls=[set$field2(1)],params=1*/
-/*omit.element: method2:assign=[field2],params=1*/
-/*strongConst.element: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.element: method2:assign=[field2],params=1*/
+/*strong.member: method2:calls=[set$field2(1)],params=1*/
+/*omit.member: method2:assign=[field2],params=1*/
+/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
+/*omitConst.member: method2:assign=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.element: Class3a.field3:checked,emitted*/
-  /*omit.element: Class3a.field3:emitted,set=simple*/
-  /*strongConst.element: Class3a.field3:checked,emitted*/
-  /*omitConst.element: Class3a.field3:emitted,set=simple*/
+  /*strong.member: Class3a.field3:checked,emitted*/
+  /*omit.member: Class3a.field3:emitted,set=simple*/
+  /*strongConst.member: Class3a.field3:checked,emitted*/
+  /*omitConst.member: Class3a.field3:emitted,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.element: Class3b.field3:checked,emitted*/
-  /*omit.element: Class3b.field3:emitted,set=simple*/
-  /*strongConst.element: Class3b.field3:checked,emitted*/
-  /*omitConst.element: Class3b.field3:emitted,set=simple*/
+  /*strong.member: Class3b.field3:checked,emitted*/
+  /*omit.member: Class3b.field3:emitted,set=simple*/
+  /*strongConst.member: Class3b.field3:checked,emitted*/
+  /*omitConst.member: Class3b.field3:emitted,set=simple*/
   int field3;
 }
 
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
 @pragma('dart2js:noInline')
 method3(dynamic c) {
   c.field3 = 42;
 }
 
 class Class4a {
-  /*strong.element: Class4a.field4:checked,emitted*/
-  /*omit.element: Class4a.field4:emitted,set=simple*/
-  /*strongConst.element: Class4a.field4:checked,emitted*/
-  /*omitConst.element: Class4a.field4:emitted,set=simple*/
+  /*strong.member: Class4a.field4:checked,emitted*/
+  /*omit.member: Class4a.field4:emitted,set=simple*/
+  /*strongConst.member: Class4a.field4:checked,emitted*/
+  /*omitConst.member: Class4a.field4:emitted,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.element: Class4b.field4:checked,emitted*/
-  /*omit.element: Class4b.field4:emitted,set=simple*/
-  /*strongConst.element: Class4b.field4:checked,emitted*/
-  /*omitConst.element: Class4b.field4:emitted,set=simple*/
+  /*strong.member: Class4b.field4:checked,emitted*/
+  /*omit.member: Class4b.field4:emitted,set=simple*/
+  /*strongConst.member: Class4b.field4:checked,emitted*/
+  /*omitConst.member: Class4b.field4:emitted,set=simple*/
   @override
   int field4;
 }
 
-/*element: method4:calls=[set$field4(1)],params=1*/
+/*member: method4:calls=[set$field4(1)],params=1*/
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   c.field4 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
index 84e646c..fcaa994 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   method1(new Class1a());
   method2(new Class2a<int>());
@@ -13,73 +13,73 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:elided*/
+  /*member: Class1a.field1:elided*/
   int field1;
 }
 
-/*element: method1:params=1*/
+/*member: method1:params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   c.field1 = 42;
 }
 
 class Class2a<T> {
-  /*strong.element: Class2a.field2:checked,elided*/
-  /*omit.element: Class2a.field2:elided*/
-  /*strongConst.element: Class2a.field2:checked,elided*/
-  /*omitConst.element: Class2a.field2:elided*/
+  /*strong.member: Class2a.field2:checked,elided*/
+  /*omit.member: Class2a.field2:elided*/
+  /*strongConst.member: Class2a.field2:checked,elided*/
+  /*omitConst.member: Class2a.field2:elided*/
   T field2;
 }
 
-/*strong.element: method2:calls=[set$field2(1)],params=1*/
-/*omit.element: method2:params=1*/
-/*strongConst.element: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.element: method2:params=1*/
+/*strong.member: method2:calls=[set$field2(1)],params=1*/
+/*omit.member: method2:params=1*/
+/*strongConst.member: method2:calls=[set$field2(1)],params=1*/
+/*omitConst.member: method2:params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.element: Class3a.field3:checked,elided*/
-  /*omit.element: Class3a.field3:elided,set=simple*/
-  /*strongConst.element: Class3a.field3:checked,elided*/
-  /*omitConst.element: Class3a.field3:elided,set=simple*/
+  /*strong.member: Class3a.field3:checked,elided*/
+  /*omit.member: Class3a.field3:elided,set=simple*/
+  /*strongConst.member: Class3a.field3:checked,elided*/
+  /*omitConst.member: Class3a.field3:elided,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.element: Class3b.field3:checked,elided*/
-  /*omit.element: Class3b.field3:elided,set=simple*/
-  /*strongConst.element: Class3b.field3:checked,elided*/
-  /*omitConst.element: Class3b.field3:elided,set=simple*/
+  /*strong.member: Class3b.field3:checked,elided*/
+  /*omit.member: Class3b.field3:elided,set=simple*/
+  /*strongConst.member: Class3b.field3:checked,elided*/
+  /*omitConst.member: Class3b.field3:elided,set=simple*/
   int field3;
 }
 
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
 @pragma('dart2js:noInline')
 method3(dynamic c) {
   c.field3 = 42;
 }
 
 class Class4a {
-  /*strong.element: Class4a.field4:checked,elided*/
-  /*omit.element: Class4a.field4:elided,set=simple*/
-  /*strongConst.element: Class4a.field4:checked,elided*/
-  /*omitConst.element: Class4a.field4:elided,set=simple*/
+  /*strong.member: Class4a.field4:checked,elided*/
+  /*omit.member: Class4a.field4:elided,set=simple*/
+  /*strongConst.member: Class4a.field4:checked,elided*/
+  /*omitConst.member: Class4a.field4:elided,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.element: Class4b.field4:checked,elided*/
-  /*omit.element: Class4b.field4:elided,set=simple*/
-  /*strongConst.element: Class4b.field4:checked,elided*/
-  /*omitConst.element: Class4b.field4:elided,set=simple*/
+  /*strong.member: Class4b.field4:checked,elided*/
+  /*omit.member: Class4b.field4:elided,set=simple*/
+  /*strongConst.member: Class4b.field4:checked,elided*/
+  /*omitConst.member: Class4b.field4:elided,set=simple*/
   @override
   int field4;
 }
 
-/*element: method4:calls=[set$field4(1)],params=1*/
+/*member: method4:calls=[set$field4(1)],params=1*/
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   c.field4 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart b/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
index f1e788e..39e6f1e 100644
--- a/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
+++ b/tests/compiler/dart2js/codegen/model_data/effectively_constant_fields.dart
@@ -4,49 +4,49 @@
 
 import 'package:expect/expect.dart';
 
-/*element: _field4:params=0*/
+/*member: _field4:params=0*/
 _field4() => 4;
 
 class Class1 {
-  /*element: Class1.field1:elided*/
+  /*member: Class1.field1:elided*/
   var field1 = 0;
 
-  /*element: Class1.field2:emitted*/
+  /*member: Class1.field2:emitted*/
   @pragma('dart2js:noElision')
   var field2 = 1;
 
-  /*element: Class1.field3:elided,get=simple*/
+  /*member: Class1.field3:elided,get=simple*/
   var field3 = 2;
 
-  /*element: Class1.field4:elided*/
+  /*member: Class1.field4:elided*/
   var field4 = _field4;
 }
 
-/*element: method1:params=1*/
+/*member: method1:params=1*/
 @pragma('dart2js:noInline')
 method1(Class1 c) {
   return c.field1;
 }
 
-/*element: method2:access=[field2],params=1*/
+/*member: method2:access=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(Class1 c) {
   return c.field2;
 }
 
 class Class2 {
-  /*element: Class2.field3:elided,get=simple*/
+  /*member: Class2.field3:elided,get=simple*/
   final field3 = 3;
 }
 
-/*element: method3:calls=[get$field3(0)],params=1*/
+/*member: method3:calls=[get$field3(0)],params=1*/
 @pragma('dart2js:noInline')
 method3(c) {
   return c.field3;
 }
 
 class Class3 extends Class1 {
-  /*element: Class3.method4:params=0*/
+  /*member: Class3.method4:params=0*/
   @pragma('dart2js:noInline')
   method4() {
     return super.field1;
@@ -54,20 +54,20 @@
 }
 
 class Class4 extends Class1 {
-  /*element: Class4.method5:calls=[_field4(0)],params=0*/
+  /*member: Class4.method5:calls=[_field4(0)],params=0*/
   @pragma('dart2js:noInline')
   method5() {
     return super.field4();
   }
 }
 
-/*element: method6:access=[toString],params=1*/
+/*member: method6:access=[toString],params=1*/
 @pragma('dart2js:noInline')
 method6(Class1 c) {
   return c.field1;
 }
 
-/*element: method7:access=[toString],calls=[_field4(0)],params=1*/
+/*member: method7:access=[toString],calls=[_field4(0)],params=1*/
 @pragma('dart2js:noInline')
 method7(Class1 c) {
   return c.field4();
@@ -75,24 +75,24 @@
 
 var field8;
 
-/*element: method8:!access,params=0*/
+/*member: method8:!access,params=0*/
 @pragma('dart2js:noInline')
 method8() => field8;
 
 var field9 = 10;
 
-/*element: method9:!access,params=0*/
+/*member: method9:!access,params=0*/
 @pragma('dart2js:noInline')
 method9() => field9;
 
-/*element: field10:emitted,lazy*/
+/*member: field10:emitted,lazy*/
 var field10 = method9() + 10;
 
-/*element: method10:calls=[$get$field10(0)],params=0*/
+/*member: method10:calls=[$get$field10(0)],params=0*/
 @pragma('dart2js:noInline')
 method10() => field10;
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   Expect.equals(0, method1(new Class1()));
   Expect.equals(1, method2(new Class1()));
diff --git a/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart b/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
index fc33c4b..ec053ae 100644
--- a/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/codegen/model_data/effectively_constant_state.dart
@@ -8,28 +8,28 @@
   c,
 }
 
-/*element: tester1:params=0*/
+/*member: tester1:params=0*/
 @pragma('dart2js:noInline')
 tester1() {}
 
-/*element: tester2:params=0*/
+/*member: tester2:params=0*/
 @pragma('dart2js:noInline')
 tester2() {}
 
-/*element: tester3:params=0*/
+/*member: tester3:params=0*/
 @pragma('dart2js:noInline')
 tester3() {}
 
 class Class {
-  /*element: Class.state1:elided*/
+  /*member: Class.state1:elided*/
   final int state1;
 
-  /*element: Class.state2:elided*/
+  /*member: Class.state2:elided*/
   final Enum state2;
 
   Class({this.state1: 1, this.state2: Enum.c});
 
-  /*element: Class.method1a:calls=[tester2(0)],params=0*/
+  /*member: Class.method1a:calls=[tester2(0)],params=0*/
   @pragma('dart2js:noInline')
   method1a() {
     if (state1 == 0) {
@@ -42,7 +42,7 @@
   }
 
   // TODO(johnniwinther): Inline switch cases with constant expressions.
-  /*element: Class.method1b:calls=[tester2(0)],params=0,switch*/
+  /*member: Class.method1b:calls=[tester2(0)],params=0,switch*/
   @pragma('dart2js:noInline')
   method1b() {
     switch (state1) {
@@ -55,7 +55,7 @@
     }
   }
 
-  /*element: Class.method2a:calls=[tester3(0)],params=0*/
+  /*member: Class.method2a:calls=[tester3(0)],params=0*/
   @pragma('dart2js:noInline')
   method2a() {
     if (state2 == Enum.a) {
@@ -67,7 +67,7 @@
     }
   }
 
-  /*element: Class.method2b:calls=[tester1(0),tester2(0),tester3(0)],params=0,switch*/
+  /*member: Class.method2b:calls=[tester1(0),tester2(0),tester3(0)],params=0,switch*/
   @pragma('dart2js:noInline')
   method2b() {
     // TODO(johnniwinther): Eliminate dead code in enum switch.
@@ -82,7 +82,7 @@
   }
 }
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   var c = new Class();
   c.method1a();
diff --git a/tests/compiler/dart2js/codegen/model_data/field_set.dart b/tests/compiler/dart2js/codegen/model_data/field_set.dart
index 2c68409..1bc4366 100644
--- a/tests/compiler/dart2js/codegen/model_data/field_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/field_set.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:access=*,calls=*,params=0*/
+/*member: main:access=*,calls=*,params=0*/
 main() {
   method1(new Class1a());
   method2(new Class2a());
@@ -23,58 +23,58 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:emitted*/
+  /*member: Class1a.field1:emitted*/
   @pragma('dart2js:noElision')
   int field1;
 }
 
-/*element: method1:assign=[field1],params=1*/
+/*member: method1:assign=[field1],params=1*/
 @pragma('dart2js:noInline')
 method1(Class1a c) {
   c.field1 = 42;
 }
 
 class Class2a {
-  /*element: Class2a.field2:emitted*/
+  /*member: Class2a.field2:emitted*/
   @pragma('dart2js:noElision')
   int field2 = 42;
 }
 
 class Class2b extends Class2a {}
 
-/*element: method2:assign=[field2],params=1*/
+/*member: method2:assign=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(Class2a c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*element: Class3a.field3:elided,set=simple*/
+  /*member: Class3a.field3:elided,set=simple*/
   var field3;
 }
 
 class Class3b implements Class3a {
-  /*element: Class3b.field3:emitted,set=simple*/
+  /*member: Class3b.field3:emitted,set=simple*/
   var field3;
 }
 
-/*element: method3:calls=[set$field3(1)],params=1*/
+/*member: method3:calls=[set$field3(1)],params=1*/
 @pragma('dart2js:noInline')
 method3(Class3a a) => a.field3 = 42;
 
 class Class5a {
-  /*element: Class5a.field5:elided*/
+  /*member: Class5a.field5:elided*/
   int field5;
 }
 
-/*element: method5:params=1*/
+/*member: method5:params=1*/
 @pragma('dart2js:noInline')
 method5(Class5a c) {
   c.field5 = 42;
 }
 
 class Class6a {
-  /*element: Class6a.field6:elided*/
+  /*member: Class6a.field6:elided*/
   int field6 = 42;
 }
 
@@ -82,15 +82,15 @@
 
 @pragma('dart2js:noInline')
 method6(Class6a c) {
-  /*element: method6:params=1*/
+  /*member: method6:params=1*/
   c.field6 = 42;
 }
 
-/*element: field7:emitted*/
+/*member: field7:emitted*/
 @pragma('dart2js:noElision')
 int field7;
 
-/*element: method7:assign=[field7],params=0*/
+/*member: method7:assign=[field7],params=0*/
 @pragma('dart2js:noInline')
 method7() {
   field7 = 42;
@@ -98,17 +98,17 @@
 
 int field8;
 
-/*element: method8:params=0*/
+/*member: method8:params=0*/
 @pragma('dart2js:noInline')
 method8() {
   field8 = 42;
 }
 
-/*element: field9:emitted,lazy*/
+/*member: field9:emitted,lazy*/
 @pragma('dart2js:noElision')
 int field9 = throw 'field9';
 
-/*element: method9:assign=[field9],params=0*/
+/*member: method9:assign=[field9],params=0*/
 @pragma('dart2js:noInline')
 method9() {
   field9 = 42;
@@ -116,7 +116,7 @@
 
 int field10 = throw 'field9';
 
-/*element: method10:params=0*/
+/*member: method10:params=0*/
 @pragma('dart2js:noInline')
 method10() {
   field10 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/fields.dart b/tests/compiler/dart2js/codegen/model_data/fields.dart
index 7815fbe..5f08845 100644
--- a/tests/compiler/dart2js/codegen/model_data/fields.dart
+++ b/tests/compiler/dart2js/codegen/model_data/fields.dart
@@ -8,7 +8,7 @@
 
 var field1c;
 
-/*element: field2a:params=0*/
+/*member: field2a:params=0*/
 @pragma('dart2js:noInline')
 get field2a => 42;
 
@@ -18,30 +18,30 @@
 @pragma('dart2js:noInline')
 get field2b => 42;
 
-/*element: field2b=:params=1*/
+/*member: field2b=:params=1*/
 @pragma('dart2js:noInline')
 set field2b(_) {}
 
-/*element: field2c:params=0*/
+/*member: field2c:params=0*/
 @pragma('dart2js:noInline')
 get field2c => 42;
 
-/*element: field2c=:params=1*/
+/*member: field2c=:params=1*/
 @pragma('dart2js:noInline')
 set field2c(_) {}
 
 class Class {
-  /*element: Class.field1a:emitted*/
+  /*member: Class.field1a:emitted*/
   @pragma('dart2js:noElision')
   var field1a;
 
-  /*element: Class.field1b:elided*/
+  /*member: Class.field1b:elided*/
   var field1b;
 
-  /*element: Class.field1c:emitted*/
+  /*member: Class.field1c:emitted*/
   var field1c;
 
-  /*element: Class.field2a:params=0*/
+  /*member: Class.field2a:params=0*/
   @pragma('dart2js:noInline')
   get field2a => 42;
 
@@ -51,27 +51,27 @@
   @pragma('dart2js:noInline')
   get field2b => 42;
 
-  /*element: Class.field2b=:params=1*/
+  /*member: Class.field2b=:params=1*/
   @pragma('dart2js:noInline')
   set field2b(_) {}
 
-  /*element: Class.field2c:params=0*/
+  /*member: Class.field2c:params=0*/
   @pragma('dart2js:noInline')
   get field2c => 42;
 
   set field2c(_) {}
 
-  /*element: Class.field3a:elided*/
+  /*member: Class.field3a:elided*/
   var field3a = 0;
 
-  /*element: Class.field3b:elided*/
+  /*member: Class.field3b:elided*/
   var field3b;
 
-  /*element: Class.:params=0*/
+  /*member: Class.:params=0*/
   @pragma('dart2js:noInline')
   Class([this.field3b]);
 
-  /*element: Class.test:calls=[get$field2a(0),get$field2c(0),set$field2b(1)],params=0*/
+  /*member: Class.test:calls=[get$field2a(0),get$field2c(0),set$field2b(1)],params=0*/
   @pragma('dart2js:noInline')
   test() {
     field1a;
@@ -84,7 +84,7 @@
   }
 }
 
-/*element: main:calls=[Class$(0),field2a(0),field2b(1),field2c(0),field2c0(1),test$0(0)],params=0*/
+/*member: main:calls=[Class$(0),field2a(0),field2b(1),field2c(0),field2c0(1),test$0(0)],params=0*/
 main() {
   field1a;
   field1b = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
index aced524..4834159 100644
--- a/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
@@ -3,97 +3,97 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class {
-  /*element: Class.method1:params=0*/
+  /*member: Class.method1:params=0*/
   @pragma('dart2js:noInline')
   method1() {}
 
-  /*element: Class.method2a:params=0*/
+  /*member: Class.method2a:params=0*/
   @pragma('dart2js:noInline')
   method2a([a]) {}
 
-  /*element: Class.method2b:params=1*/
+  /*member: Class.method2b:params=1*/
   @pragma('dart2js:noInline')
   method2b([a]) {}
 
-  /*element: Class.method2c:params=1,stubs=[method2c$0:method2c$1(1)]*/
+  /*member: Class.method2c:params=1,stubs=[method2c$0:method2c$1(1)]*/
   @pragma('dart2js:noInline')
   method2c([a]) {}
 
-  /*element: Class.method3a:params=0*/
+  /*member: Class.method3a:params=0*/
   @pragma('dart2js:noInline')
   method3a([a, b]) {}
 
-  /*element: Class.method3b:params=1,stubs=[method3b$0:method3b$1(1)]*/
+  /*member: Class.method3b:params=1,stubs=[method3b$0:method3b$1(1)]*/
   @pragma('dart2js:noInline')
   method3b([a, b]) {}
 
-  /*element: Class.method3c:params=2*/
+  /*member: Class.method3c:params=2*/
   @pragma('dart2js:noInline')
   method3c([a, b]) {}
 
-  /*element: Class.method4a:params=0*/
+  /*member: Class.method4a:params=0*/
   @pragma('dart2js:noInline')
   method4a({a}) {}
 
-  /*element: Class.method4b:params=1*/
+  /*member: Class.method4b:params=1*/
   @pragma('dart2js:noInline')
   method4b({a}) {}
 
-  /*element: Class.method4c:params=1,stubs=[method4c$0:method4c$1$a(1)]*/
+  /*member: Class.method4c:params=1,stubs=[method4c$0:method4c$1$a(1)]*/
   @pragma('dart2js:noInline')
   method4c({a}) {}
 
-  /*element: Class.method5a:params=0*/
+  /*member: Class.method5a:params=0*/
   @pragma('dart2js:noInline')
   method5a({a, b}) {}
 
-  /*element: Class.method5b:params=1*/
+  /*member: Class.method5b:params=1*/
   @pragma('dart2js:noInline')
   method5b({a, b}) {}
 
-  /*element: Class.method5c:params=1*/
+  /*member: Class.method5c:params=1*/
   @pragma('dart2js:noInline')
   method5c({a, b}) {}
 
-  /*element: Class.method6a:params=0,stubs=[method6a$0:method6a$1$0(1)]*/
+  /*member: Class.method6a:params=0,stubs=[method6a$0:method6a$1$0(1)]*/
   @pragma('dart2js:noInline')
   method6a<T>() {}
 
-  /*element: Class.method7a:params=1*/
+  /*member: Class.method7a:params=1*/
   @pragma('dart2js:noInline')
   method7a(a, [b, c]) {}
 
-  /*element: Class.method7b:params=2,stubs=[method7b$1:method7b$2(2)]*/
+  /*member: Class.method7b:params=2,stubs=[method7b$1:method7b$2(2)]*/
   @pragma('dart2js:noInline')
   method7b(a, [b, c]) {}
 
-  /*element: Class.method7c:params=3*/
+  /*member: Class.method7c:params=3*/
   @pragma('dart2js:noInline')
   method7c(a, [b, c]) {}
 
-  /*element: Class.method8a:params=1*/
+  /*member: Class.method8a:params=1*/
   @pragma('dart2js:noInline')
   method8a(a, {b, c}) {}
 
-  /*element: Class.method8b:params=2*/
+  /*member: Class.method8b:params=2*/
   @pragma('dart2js:noInline')
   method8b(a, {b, c}) {}
 
-  /*element: Class.method8c:params=2*/
+  /*member: Class.method8c:params=2*/
   @pragma('dart2js:noInline')
   method8c(a, {b, c}) {}
 
-  /*element: Class.method9a:params=2,stubs=[method9a$0:method9a$2(2)]*/
+  /*member: Class.method9a:params=2,stubs=[method9a$0:method9a$2(2)]*/
   @pragma('dart2js:noInline')
   @pragma('dart2js:noElision')
   method9a([a, b]) {}
 
-  /*element: Class.method9b:params=2,stubs=[method9b$0:method9b$2$a$b(2)]*/
+  /*member: Class.method9b:params=2,stubs=[method9b$0:method9b$2$a$b(2)]*/
   @pragma('dart2js:noInline')
   @pragma('dart2js:noElision')
   method9b({a, b}) {}
 
-  /*element: Class.test:calls=*,params=0*/
+  /*member: Class.test:calls=*,params=0*/
   @pragma('dart2js:noInline')
   test() {
     method1();
@@ -133,7 +133,7 @@
   }
 }
 
-/*element: main:calls=[test$0(0)],params=0*/
+/*member: main:calls=[test$0(0)],params=0*/
 main() {
   new Class().test();
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/native.dart b/tests/compiler/dart2js/codegen/model_data/native.dart
index 23dcd6e..02cae6f 100644
--- a/tests/compiler/dart2js/codegen/model_data/native.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native.dart
@@ -16,7 +16,7 @@
 
   int field2;
 
-  /*element: Class.method1:
+  /*member: Class.method1:
    calls=[method1(a,b,c)],
    params=4,
    stubs=[
@@ -28,7 +28,7 @@
       // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
       native;
 
-  /*element: Class.method2:
+  /*member: Class.method2:
    calls=[method2(a,b,c)],
    params=4,
    stubs=[
@@ -44,7 +44,7 @@
   // TODO(johnniwinther): Control the order of the named arguments. Currently
   // we sort them lexicographically but that doesn't match the target
   // expectations.
-  /*element: Class.method3:
+  /*member: Class.method3:
    calls=[method3(a,c,b)],
    params=4,
    stubs=[
@@ -60,7 +60,7 @@
   // TODO(johnniwinther): Control the order of the named arguments. Currently
   // we sort them lexicographically but that doesn't match the target
   // expectations.
-  /*element: Class.method4:
+  /*member: Class.method4:
    calls=[method4(a,c,d,b)],
    params=5,
    stubs=[
@@ -77,18 +77,18 @@
       native;
 }
 
-/*element: makeClass:params=0*/
+/*member: makeClass:params=0*/
 @Creates('Class')
 makeClass()
     // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
     native;
 
-/*element: main:calls=[test(1),*],params=0*/
+/*member: main:calls=[test(1),*],params=0*/
 main() {
   test(makeClass());
 }
 
-/*element: test:
+/*member: test:
  assign=[field1,field2],
  calls=[
   method1$1(2),
diff --git a/tests/compiler/dart2js/codegen/model_data/native_inlined.dart b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
index 7e99271..63d5cd6 100644
--- a/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
@@ -15,7 +15,7 @@
       // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
       native;
 
-  /*element: Class.method2:
+  /*member: Class.method2:
    calls=[method2(a,b,c)],
    params=4,
    stubs=[
@@ -30,7 +30,7 @@
   // TODO(johnniwinther): Control the order of the named arguments. Currently
   // we sort them lexicographically but that doesn't match the target
   // expectations.
-  /*element: Class.method3:
+  /*member: Class.method3:
    calls=[method3(a,c,b)],
    params=4,
    stubs=[
@@ -45,7 +45,7 @@
   // TODO(johnniwinther): Control the order of the named arguments. Currently
   // we sort them lexicographically but that doesn't match the target
   // expectations.
-  /*element: Class.method4:
+  /*member: Class.method4:
    calls=[method4(a,c,d,b)],
    params=5,
    stubs=[
@@ -61,18 +61,18 @@
       native;
 }
 
-/*element: makeClass:params=0*/
+/*member: makeClass:params=0*/
 @Creates('Class')
 makeClass()
     // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
     native;
 
-/*element: main:calls=[test(1),*],params=0*/
+/*member: main:calls=[test(1),*],params=0*/
 main() {
   test(makeClass());
 }
 
-/*element: test:
+/*member: test:
  calls=[
   method1(0),
   method1(0,1),
diff --git a/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
index 9317686..33e8453 100644
--- a/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
@@ -5,28 +5,28 @@
 // ignore: import_internal_library
 import 'dart:_js_helper';
 
-/*element: Class.:access=[toString],params=1*/
+/*member: Class.:access=[toString],params=1*/
 @Native('Class')
 class Class {
-  /*element: Class.method1:calls=[method1()],params=1*/
+  /*member: Class.method1:calls=[method1()],params=1*/
   @pragma('dart2js:noInline')
   method1([a, b])
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method2:calls=[method2(a)],params=2*/
+  /*member: Class.method2:calls=[method2(a)],params=2*/
   @pragma('dart2js:noInline')
   method2([a, b])
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method3:calls=[method3(a,b)],params=3*/
+  /*member: Class.method3:calls=[method3(a,b)],params=3*/
   @pragma('dart2js:noInline')
   method3([a, b])
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method4:
+  /*member: Class.method4:
    calls=[method4(a,b)],
    params=3,
    stubs=[method4$0:method4()]
@@ -36,7 +36,7 @@
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method5:
+  /*member: Class.method5:
    calls=[method5(a,b)],
    params=3,
    stubs=[method5$1:method5(a)]
@@ -46,7 +46,7 @@
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method6:
+  /*member: Class.method6:
    calls=[method6(a,b,c)],
    params=4,
    stubs=[method6$1:method6(a)]
@@ -56,7 +56,7 @@
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method7:
+  /*member: Class.method7:
    calls=[method7(a,b,c)],
    params=4,
    stubs=[method7$2$b:method7(a,b)]
@@ -66,7 +66,7 @@
       // ignore: native_function_body_in_non_sdk_code
       native;
 
-  /*element: Class.method8:
+  /*member: Class.method8:
    calls=[method8(a,b,c)],
    params=4,
    stubs=[
@@ -79,7 +79,7 @@
       native;
 }
 
-/*element: test:
+/*member: test:
  calls=[
   method1$0(1),
   method2$1(2),
@@ -113,7 +113,7 @@
   c.method8(null, c: null);
 }
 
-/*element: main:calls=*,params=0*/
+/*member: main:calls=*,params=0*/
 main() {
   test(new Class());
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/regress_36222.dart b/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
index 8ab6ea3..6b2143d 100644
--- a/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
+++ b/tests/compiler/dart2js/codegen/model_data/regress_36222.dart
@@ -7,21 +7,21 @@
 class A {
   const A({this.foo = A.defaultFoo});
 
-  /*element: A.defaultFoo:params=2*/
+  /*member: A.defaultFoo:params=2*/
   static int defaultFoo(int x, int y) {
     return x + y;
   }
 
-  /*element: A.foo:elided,stubCalls=[foo$2:call$2(arg0,arg1),foo$2:main_A_defaultFoo$closure(0)]*/
+  /*member: A.foo:elided,stubCalls=[foo$2:call$2(arg0,arg1),foo$2:main_A_defaultFoo$closure(0)]*/
   final BinaryFunc foo;
 }
 
-/*element: test:calls=[foo$2(2)],params=1*/
+/*member: test:calls=[foo$2(2)],params=1*/
 @pragma('dart2js:assumeDynamic')
 @pragma('dart2js:noInline')
 test(dynamic a) => a.foo(1, 2);
 
-/*element: main:calls=[test(1)],params=0*/
+/*member: main:calls=[test(1)],params=0*/
 main() {
   test(new A());
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
index b95aa11..31b2433 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
@@ -2,97 +2,97 @@
 // 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.
 
-/*element: method1:params=0*/
+/*member: method1:params=0*/
 @pragma('dart2js:noInline')
 method1() {}
 
-/*element: method2a:params=0*/
+/*member: method2a:params=0*/
 @pragma('dart2js:noInline')
 method2a([a]) {}
 
-/*element: method2b:params=1*/
+/*member: method2b:params=1*/
 @pragma('dart2js:noInline')
 method2b([a]) {}
 
-/*element: method2c:params=1*/
+/*member: method2c:params=1*/
 @pragma('dart2js:noInline')
 method2c([a]) {}
 
-/*element: method3a:params=0*/
+/*member: method3a:params=0*/
 @pragma('dart2js:noInline')
 method3a([a, b]) {}
 
-/*element: method3b:params=1*/
+/*member: method3b:params=1*/
 @pragma('dart2js:noInline')
 method3b([a, b]) {}
 
-/*element: method3c:params=2*/
+/*member: method3c:params=2*/
 @pragma('dart2js:noInline')
 method3c([a, b]) {}
 
-/*element: method4a:params=0*/
+/*member: method4a:params=0*/
 @pragma('dart2js:noInline')
 method4a({a}) {}
 
-/*element: method4b:params=1*/
+/*member: method4b:params=1*/
 @pragma('dart2js:noInline')
 method4b({a}) {}
 
-/*element: method4c:params=1*/
+/*member: method4c:params=1*/
 @pragma('dart2js:noInline')
 method4c({a}) {}
 
-/*element: method5a:params=0*/
+/*member: method5a:params=0*/
 @pragma('dart2js:noInline')
 method5a({a, b}) {}
 
-/*element: method5b:params=1*/
+/*member: method5b:params=1*/
 @pragma('dart2js:noInline')
 method5b({a, b}) {}
 
-/*element: method5c:params=1*/
+/*member: method5c:params=1*/
 @pragma('dart2js:noInline')
 method5c({a, b}) {}
 
-/*element: method6a:params=0*/
+/*member: method6a:params=0*/
 @pragma('dart2js:noInline')
 method6a<T>() {}
 
-/*element: method7a:params=1*/
+/*member: method7a:params=1*/
 @pragma('dart2js:noInline')
 method7a(a, [b, c]) {}
 
-/*element: method7b:params=2*/
+/*member: method7b:params=2*/
 @pragma('dart2js:noInline')
 method7b(a, [b, c]) {}
 
-/*element: method7c:params=3*/
+/*member: method7c:params=3*/
 @pragma('dart2js:noInline')
 method7c(a, [b, c]) {}
 
-/*element: method8a:params=1*/
+/*member: method8a:params=1*/
 @pragma('dart2js:noInline')
 method8a(a, {b, c}) {}
 
-/*element: method8b:params=2*/
+/*member: method8b:params=2*/
 @pragma('dart2js:noInline')
 method8b(a, {b, c}) {}
 
-/*element: method8c:params=2*/
+/*member: method8c:params=2*/
 @pragma('dart2js:noInline')
 method8c(a, {b, c}) {}
 
-/*element: method9a:params=2*/
+/*member: method9a:params=2*/
 @pragma('dart2js:noInline')
 @pragma('dart2js:noElision')
 method9a([a, b]) {}
 
-/*element: method9b:params=2*/
+/*member: method9b:params=2*/
 @pragma('dart2js:noInline')
 @pragma('dart2js:noElision')
 method9b({a, b}) {}
 
-/*element: main:
+/*member: main:
  calls=[
   method1(0),
   method2a(0),
diff --git a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
index 75fa653..524b200 100644
--- a/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
+++ b/tests/compiler/dart2js/codegen/model_data/static_tearoff.dart
@@ -10,18 +10,18 @@
 
 class B implements I1, I2 {}
 
-/*element: foo:params=1*/
+/*member: foo:params=1*/
 @pragma('dart2js:noInline')
 void foo(I1 x) {}
 
-/*element: bar:params=1*/
+/*member: bar:params=1*/
 @pragma('dart2js:noInline')
 void bar(I2 x) {}
 
-/*strong.element: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*omit.element: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
-/*strongConst.element: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
-/*omitConst.element: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*strong.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
+/*omit.member: main:calls=[call$1(new F.A()),call$1(new F.B()),foo(1),foo(1),main__bar$closure(0),main__bar$closure(0)],params=0*/
+/*strongConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
+/*omitConst.member: main:calls=[bar(1),bar(1),foo(1),foo(1)],params=0*/
 main() {
   dynamic f = bar;
 
diff --git a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
index c10e7bd..c8e9b8e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/basic_deferred.dart
@@ -4,8 +4,8 @@
 
 import '../libs/basic_deferred_lib.dart' deferred as lib;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[FunctionConstant(funky)=OutputUnit(1, {lib})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
index b688215..6bd1661 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_class.dart
@@ -4,7 +4,7 @@
 
 import '../libs/deferred_class_library.dart' deferred as lib;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() {
   lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     return new lib.MyClass().foo(87);
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
index ccada1f..1ed34b3 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant1.dart
@@ -5,8 +5,8 @@
 import '../libs/deferred_constant1_lib1.dart';
 import '../libs/deferred_constant1_lib2.dart' deferred as lib2;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(value=ConstructedConstant(C(value=IntConstant(7)))))=OutputUnit(1, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
index 5a08d48..8306e71 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant2.dart
@@ -6,8 +6,8 @@
 
 import '../libs/deferred_constant2_lib.dart' deferred as lib;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(Constant(value=IntConstant(499)))=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
index 27c1129..17a05a9 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_constant3.dart
@@ -5,11 +5,11 @@
 import '../libs/deferred_constant3_shared.dart';
 import '../libs/deferred_constant3_lib1.dart' deferred as l1;
 
-/*strong.element: c1:OutputUnit(main, {})*/
+/*strong.member: c1:OutputUnit(main, {})*/
 const c1 = /*strong.OutputUnit(main, {})*/ const C(1);
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
index 80b59bf..cd5ae14 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_fail_and_retry.dart
@@ -9,7 +9,7 @@
 import "package:async_helper/async_helper.dart";
 import "dart:js" as js;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() {
   // We patch document.body.appendChild to change the script src on first
   // invocation.
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
index 89cedc8..47ecc4e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_function.dart
@@ -7,8 +7,8 @@
 
 import '../libs/deferred_function_lib.dart' deferred as lib;
 
-/*strong.element: readFoo:OutputUnit(main, {})*/
-/*strongConst.element: readFoo:
+/*strong.member: readFoo:OutputUnit(main, {})*/
+/*strongConst.member: readFoo:
  OutputUnit(main, {}),
  constants=[FunctionConstant(foo)=OutputUnit(1, {lib})]
 */
@@ -16,7 +16,7 @@
   return lib.foo;
 }
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() {
   lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     lib.foo('b');
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
index 754ee48..7919162 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_overlapping.dart
@@ -6,7 +6,7 @@
 import "../libs/deferred_overlapping_lib2.dart" deferred as lib2;
 
 // lib1.C1 and lib2.C2 has a shared base class. It will go in its own hunk.
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 void main() {
   lib1.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     new lib1.C1();
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
index 2aca8d8..deed5a1 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typed_map.dart
@@ -4,8 +4,8 @@
 
 import '../libs/deferred_typed_map_lib1.dart' deferred as lib;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   MapConstant(<int, dynamic Function({M b})>{IntConstant(1): FunctionConstant(f1), IntConstant(2): FunctionConstant(f2)})=OutputUnit(1, {lib})]
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
index 90343e4..23578ec 100644
--- a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
@@ -4,8 +4,8 @@
 
 import '../libs/deferred_typedef_lib1.dart' deferred as lib1;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(a=TypeConstant(void Function()),b=FunctionConstant(topLevelMethod)))=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
index 3e42dd2..8dab5c6 100644
--- a/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/dont_inline_deferred_global.dart
@@ -4,7 +4,7 @@
 
 import '../libs/dont_inline_deferred_global_lib.dart' deferred as lib;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 void main() {
   lib.loadLibrary().then(/*OutputUnit(main, {})*/ (_) {
     print(lib.finalVar);
diff --git a/tests/compiler/dart2js/deferred_loading/data/future_or.dart b/tests/compiler/dart2js/deferred_loading/data/future_or.dart
index 5927f8b..a31156a 100644
--- a/tests/compiler/dart2js/deferred_loading/data/future_or.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/future_or.dart
@@ -6,8 +6,8 @@
 import '../libs/future_or_lib1.dart' deferred as lib1;
 import '../libs/future_or_lib2.dart' as lib2;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(A())=OutputUnit(1, {lib1})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
index 0e41e0c..8e008fc 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation0.dart
@@ -9,7 +9,7 @@
 
 import '../libs/instantiation0_strong_lib1.dart' deferred as b;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   print(b.m(3));
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
index feaa5cd..174bc54c 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation1.dart
@@ -12,7 +12,7 @@
 import '../libs/instantiation1_strong_lib1.dart' deferred as b;
 import '../libs/instantiation1_strong_lib2.dart' deferred as c;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
index 198ec06..bd99ede 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation2.dart
@@ -11,7 +11,7 @@
 import '../libs/instantiation2_strong_lib1.dart' deferred as b;
 import '../libs/instantiation2_strong_lib2.dart' deferred as c;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
index 578710e..dcc3b55 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation3.dart
@@ -7,11 +7,11 @@
 /*class: global#Instantiation:OutputUnit(1, {b})*/
 /*class: global#Instantiation1:OutputUnit(1, {b})*/
 
-/*element: global#instantiate1:OutputUnit(1, {b})*/
+/*member: global#instantiate1:OutputUnit(1, {b})*/
 
 import '../libs/instantiation3_strong_lib1.dart' deferred as b;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   print(b.m(3));
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
index b7ed01a..4fe43c2 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation4.dart
@@ -9,13 +9,13 @@
 /*class: global#Instantiation1:OutputUnit(1, {b})*/
 /*class: global#Instantiation2:OutputUnit(3, {c})*/
 
-/*element: global#instantiate1:OutputUnit(1, {b})*/
-/*element: global#instantiate2:OutputUnit(3, {c})*/
+/*member: global#instantiate1:OutputUnit(1, {b})*/
+/*member: global#instantiate2:OutputUnit(3, {c})*/
 
 import '../libs/instantiation4_strong_lib1.dart' deferred as b;
 import '../libs/instantiation4_strong_lib2.dart' deferred as c;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart b/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
index 785b6bf..6397d89 100644
--- a/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/instantiation5.dart
@@ -8,12 +8,12 @@
 /*class: global#Instantiation:OutputUnit(1, {b, c})*/
 /*class: global#Instantiation1:OutputUnit(1, {b, c})*/
 
-/*element: global#instantiate1:OutputUnit(1, {b, c})*/
+/*member: global#instantiate1:OutputUnit(1, {b, c})*/
 
 import '../libs/instantiation5_strong_lib1.dart' deferred as b;
 import '../libs/instantiation5_strong_lib2.dart' deferred as c;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await b.loadLibrary();
   await c.loadLibrary();
diff --git a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart b/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
index a1bccc0..c082a4d 100644
--- a/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/shared_constant.dart
@@ -11,7 +11,7 @@
 import '../libs/shared_constant_a.dart';
 import '../libs/shared_constant_b.dart';
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   (await doA()).method();
   await doB();
diff --git a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
index 1f5a958..22404aa 100644
--- a/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/static_separate.dart
@@ -12,7 +12,7 @@
 import "../libs/static_separate_lib1.dart" deferred as lib1;
 import "../libs/static_separate_lib2.dart" deferred as lib2;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 void main() {
   asyncStart();
   Expect.throws(/*OutputUnit(main, {})*/ () {
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
index 80026e3..b64e30e 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_argument_dependency.dart
@@ -5,7 +5,7 @@
 import '../libs/type_argument_dependency_lib1.dart';
 import '../libs/type_argument_dependency_lib2.dart' deferred as c;
 
-/*element: main:OutputUnit(main, {})*/
+/*member: main:OutputUnit(main, {})*/
 main() async {
   await c.loadLibrary();
   c.createA();
diff --git a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart b/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
index 14f63696..a39b055 100644
--- a/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
+++ b/tests/compiler/dart2js/deferred_loading/data/type_arguments.dart
@@ -6,8 +6,8 @@
 import '../libs/type_arguments_lib2.dart' as lib2;
 import '../libs/type_arguments_lib3.dart' deferred as lib3;
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(A<B>())=OutputUnit(1, {lib1}),
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index b23c178..880c642 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -216,6 +216,7 @@
     Expect.fail("Duplicate id $id.");
   }
   if (value != null) {
-    actualMap[id] = new ActualData<T>(id, value, sourceSpan, object);
+    actualMap[id] =
+        new ActualData<T>(id, value, sourceSpan.uri, sourceSpan.begin, object);
   }
 }
diff --git a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
index 0091deb..25d4ccd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/basic_deferred_lib.dart
@@ -2,11 +2,11 @@
 // 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.
 
-/*element: defaultArg:OutputUnit(1, {lib})*/
+/*member: defaultArg:OutputUnit(1, {lib})*/
 defaultArg() => "";
 
-/*strong.element: funky:OutputUnit(1, {lib})*/
-/*strongConst.element: funky:
+/*strong.member: funky:OutputUnit(1, {lib})*/
+/*strongConst.member: funky:
  OutputUnit(1, {lib}),
  constants=[FunctionConstant(defaultArg)=OutputUnit(1, {lib})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
index 3e359eb..4910c2a 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_class_library.dart
@@ -8,10 +8,10 @@
 
 /*class: MyClass:OutputUnit(1, {lib})*/
 class MyClass {
-  /*element: MyClass.:OutputUnit(1, {lib})*/
+  /*member: MyClass.:OutputUnit(1, {lib})*/
   const MyClass();
 
-  /*element: MyClass.foo:OutputUnit(1, {lib})*/
+  /*member: MyClass.foo:OutputUnit(1, {lib})*/
   foo(x) {
     print('MyClass.foo($x)');
     return (x - 3) ~/ 2;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
index c304f13..afd84b4 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant1_lib3.dart
@@ -6,9 +6,9 @@
 
 /*class: C:OutputUnit(main, {})*/
 class C {
-  /*element: C.value:OutputUnit(main, {})*/
+  /*member: C.value:OutputUnit(main, {})*/
   final value;
-  /*strong.element: C.:OutputUnit(main, {})*/
+  /*strong.member: C.:OutputUnit(main, {})*/
   const C(this.value);
 }
 
@@ -16,14 +16,14 @@
 /// Constant used from main: not deferred.
 /// ---------------------------------------------------------------------------
 
-/*strong.element: C1:OutputUnit(main, {})*/
+/*strong.member: C1:OutputUnit(main, {})*/
 const C1 = /*strong.OutputUnit(main, {})*/ const C(1);
 
 /// ---------------------------------------------------------------------------
 /// Constant completely deferred.
 /// ---------------------------------------------------------------------------
 
-/*strong.element: C2:OutputUnit(1, {lib2})*/
+/*strong.member: C2:OutputUnit(1, {lib2})*/
 const C2 = /*strong.OutputUnit(1, {lib2})*/ const C(2);
 
 /// ---------------------------------------------------------------------------
@@ -31,25 +31,25 @@
 /// and the constants are in different output units.
 /// ---------------------------------------------------------------------------
 
-/*strong.element: C3:OutputUnit(1, {lib2})*/
+/*strong.member: C3:OutputUnit(1, {lib2})*/
 const C3 = /*strong.OutputUnit(main, {})*/ const C(1);
 
-/*strong.element: C4:OutputUnit(1, {lib2})*/
+/*strong.member: C4:OutputUnit(1, {lib2})*/
 const C4 = /*strong.OutputUnit(main, {})*/ const C(4);
 
 /// ---------------------------------------------------------------------------
 /// Constant value used form a closure within main.
 /// ---------------------------------------------------------------------------
 
-/*strong.element: C5:OutputUnit(1, {lib2})*/
+/*strong.member: C5:OutputUnit(1, {lib2})*/
 const C5 = /*strong.OutputUnit(main, {})*/ const C(5);
 
 /// ---------------------------------------------------------------------------
 /// Deferred constants, used after a deferred load.
 /// ---------------------------------------------------------------------------
 
-/*strong.element: C6:OutputUnit(1, {lib2})*/
+/*strong.member: C6:OutputUnit(1, {lib2})*/
 const C6 = "string6";
 
-/*strong.element: C7:OutputUnit(1, {lib2})*/
+/*strong.member: C7:OutputUnit(1, {lib2})*/
 const C7 = /*strong.OutputUnit(1, {lib2})*/ const C(const C(7));
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
index 12221777..dc1516d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant2_lib.dart
@@ -6,16 +6,16 @@
 
 /*class: Constant:OutputUnit(1, {lib})*/
 class Constant {
-  /*element: Constant.value:OutputUnit(1, {lib})*/
+  /*member: Constant.value:OutputUnit(1, {lib})*/
   final value;
-  /*strong.element: Constant.:OutputUnit(1, {lib})*/
+  /*strong.member: Constant.:OutputUnit(1, {lib})*/
   const Constant(this.value);
 
-  /*element: Constant.==:OutputUnit(1, {lib})*/
+  /*member: Constant.==:OutputUnit(1, {lib})*/
   operator ==(other) => other is Constant && value == other.value;
-  /*element: Constant.hashCode:OutputUnit(1, {lib})*/
+  /*member: Constant.hashCode:OutputUnit(1, {lib})*/
   get hashCode => 0;
 }
 
-/*strong.element: C1:OutputUnit(1, {lib})*/
+/*strong.member: C1:OutputUnit(1, {lib})*/
 const C1 = /*strong.OutputUnit(1, {lib})*/ const Constant(499);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
index ad37207..2edad58 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib1.dart
@@ -5,14 +5,14 @@
 import 'deferred_constant3_shared.dart';
 import 'deferred_constant3_lib2.dart' deferred as l2;
 
-/*strong.element: c2:OutputUnit(1, {l1})*/
+/*strong.member: c2:OutputUnit(1, {l1})*/
 const c2 = /*strong.OutputUnit(1, {l1})*/ const C(2);
 
-/*strong.element: c3:OutputUnit(1, {l1})*/
+/*strong.member: c3:OutputUnit(1, {l1})*/
 const c3 = /*strong.OutputUnit(1, {l1})*/ const C(3);
 
-/*strong.element: m1:OutputUnit(1, {l1})*/
-/*strongConst.element: m1:
+/*strong.member: m1:OutputUnit(1, {l1})*/
+/*strongConst.member: m1:
  OutputUnit(1, {l1}),
  constants=[
   ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
index b834b48..7dbbe8b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_lib2.dart
@@ -4,17 +4,17 @@
 
 import 'deferred_constant3_shared.dart';
 
-/*strong.element: c3:OutputUnit(2, {l2})*/
+/*strong.member: c3:OutputUnit(2, {l2})*/
 const c3 = /*strong.OutputUnit(main, {})*/ const C(1);
 
-/*strong.element: c4:OutputUnit(2, {l2})*/
+/*strong.member: c4:OutputUnit(2, {l2})*/
 const c4 = /*strong.OutputUnit(2, {l2})*/ const C(4);
 
-/*strong.element: c5:OutputUnit(2, {l2})*/
+/*strong.member: c5:OutputUnit(2, {l2})*/
 const c5 = /*strong.OutputUnit(2, {l2})*/ const C(5);
 
-/*strong.element: m2:OutputUnit(2, {l2})*/
-/*strongConst.element: m2:
+/*strong.member: m2:OutputUnit(2, {l2})*/
+/*strongConst.member: m2:
  OutputUnit(2, {l2}),
  constants=[
   ConstructedConstant(C(x=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
index d4480d1..f2a7bdd 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_constant3_shared.dart
@@ -4,9 +4,9 @@
 
 /*class: C:OutputUnit(main, {})*/
 class C {
-  /*strong.element: C.:OutputUnit(main, {})*/
+  /*strong.member: C.:OutputUnit(main, {})*/
   const C(this.x);
 
-  /*element: C.x:OutputUnit(main, {})*/
+  /*member: C.x:OutputUnit(main, {})*/
   final x;
 }
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
index ed22832..e2bccb3 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_fail_and_retry_lib.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:OutputUnit(1, {lib})*/
+/*member: foo:OutputUnit(1, {lib})*/
 foo() {
   return "loaded";
 }
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
index 5d40356..1424c6a 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_function_lib.dart
@@ -6,7 +6,7 @@
 
 library deferred_function_library;
 
-/*element: foo:OutputUnit(1, {lib})*/
+/*member: foo:OutputUnit(1, {lib})*/
 foo(x) {
   print('foo($x)');
   return 42;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
index 194e27d..47d7393 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib1.dart
@@ -5,5 +5,5 @@
 import "deferred_overlapping_lib3.dart";
 
 /*class: C1:OutputUnit(2, {lib1})*/
-/*element: C1.:OutputUnit(2, {lib1})*/
+/*member: C1.:OutputUnit(2, {lib1})*/
 class C1 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
index 3e49d22..10073a0 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib2.dart
@@ -5,5 +5,5 @@
 import "deferred_overlapping_lib3.dart";
 
 /*class: C2:OutputUnit(3, {lib2})*/
-/*element: C2.:OutputUnit(3, {lib2})*/
+/*member: C2.:OutputUnit(3, {lib2})*/
 class C2 extends C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
index 5167cc6..43a1071 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_overlapping_lib3.dart
@@ -3,5 +3,5 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /*class: C3:OutputUnit(1, {lib1, lib2})*/
-/*element: C3.:OutputUnit(1, {lib1, lib2})*/
+/*member: C3.:OutputUnit(1, {lib1, lib2})*/
 class C3 {}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
index cec8198..b435e6d 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typed_map_lib1.dart
@@ -7,13 +7,13 @@
 
 typedef dynamic FF({M b});
 
-/*strong.element: table:OutputUnit(1, {lib})*/
+/*strong.member: table:OutputUnit(1, {lib})*/
 const table =
 /*strong.OutputUnit(1, {lib})*/
     const <int, FF>{1: f1, 2: f2};
 
-/*element: f1:OutputUnit(1, {lib})*/
+/*member: f1:OutputUnit(1, {lib})*/
 dynamic f1({M b}) => null;
 
-/*element: f2:OutputUnit(1, {lib})*/
+/*member: f2:OutputUnit(1, {lib})*/
 dynamic f2({M b}) => null;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
index e8b71f2..4cdfe95 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
@@ -6,13 +6,13 @@
 
 /*class: C:OutputUnit(1, {lib1})*/
 class C {
-  /*element: C.a:OutputUnit(1, {lib1})*/
+  /*member: C.a:OutputUnit(1, {lib1})*/
   final a;
 
-  /*element: C.b:OutputUnit(1, {lib1})*/
+  /*member: C.b:OutputUnit(1, {lib1})*/
   final b;
 
-  /*strong.element: C.:OutputUnit(1, {lib1})*/
+  /*strong.member: C.:OutputUnit(1, {lib1})*/
   const C(this.a, this.b);
 }
 
@@ -20,11 +20,11 @@
 
 typedef void MyF2();
 
-/*element: topLevelMethod:OutputUnit(1, {lib1})*/
+/*member: topLevelMethod:OutputUnit(1, {lib1})*/
 topLevelMethod() {}
 
-/*strong.element: cA:OutputUnit(1, {lib1})*/
+/*strong.member: cA:OutputUnit(1, {lib1})*/
 const cA = /*strong.OutputUnit(1, {lib1})*/ const C(MyF1, topLevelMethod);
 
-/*strong.element: cB:OutputUnit(1, {lib1})*/
+/*strong.member: cB:OutputUnit(1, {lib1})*/
 const cB = /*strong.OutputUnit(1, {lib1})*/ MyF2;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
index a207e12..837d58c 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib1.dart
@@ -5,37 +5,37 @@
 import "dont_inline_deferred_constants_main.dart" show C;
 import "dont_inline_deferred_constants_main.dart" as main;
 
-/*strong.element: C1:OutputUnit(1, {lib1})*/
+/*strong.member: C1:OutputUnit(1, {lib1})*/
 const C1 = "string1";
 
-/*strong.element: C1b:OutputUnit(1, {lib1})*/
+/*strong.member: C1b:OutputUnit(1, {lib1})*/
 const C1b = /*strong.OutputUnit(1, {lib1})*/ const C("string1");
 
-/*strong.element: C2:OutputUnit(1, {lib1})*/
+/*strong.member: C2:OutputUnit(1, {lib1})*/
 const C2 = 1010;
 
-/*strong.element: C2b:OutputUnit(1, {lib1})*/
+/*strong.member: C2b:OutputUnit(1, {lib1})*/
 const C2b = /*strong.OutputUnit(1, {lib1})*/ const C(1010);
 
 /*class: D:null*/
 class D {
-  /*strong.element: D.C3:OutputUnit(1, {lib1})*/
+  /*strong.member: D.C3:OutputUnit(1, {lib1})*/
   static const C3 = "string2";
 
-  /*strong.element: D.C3b:OutputUnit(1, {lib1})*/
+  /*strong.member: D.C3b:OutputUnit(1, {lib1})*/
   static const C3b = /*strong.OutputUnit(1, {lib1})*/ const C("string2");
 }
 
-/*strong.element: C4:OutputUnit(1, {lib1})*/
+/*strong.member: C4:OutputUnit(1, {lib1})*/
 const C4 = "string4";
 
-/*strong.element: C5:OutputUnit(1, {lib1})*/
+/*strong.member: C5:OutputUnit(1, {lib1})*/
 const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
 
-/*strong.element: C6:OutputUnit(1, {lib1})*/
+/*strong.member: C6:OutputUnit(1, {lib1})*/
 const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
 
-/*element: foo:OutputUnit(1, {lib1})*/
+/*member: foo:OutputUnit(1, {lib1})*/
 foo() {
   print("lib1");
   main.foo();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
index 79948c6..f475d99 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_lib2.dart
@@ -5,16 +5,16 @@
 import "dont_inline_deferred_constants_main.dart" show C;
 import "dont_inline_deferred_constants_main.dart" as main;
 
-/*strong.element: C4:OutputUnit(3, {lib2})*/
+/*strong.member: C4:OutputUnit(3, {lib2})*/
 const C4 = "string4";
 
-/*strong.element: C5:OutputUnit(3, {lib2})*/
+/*strong.member: C5:OutputUnit(3, {lib2})*/
 const C5 = /*strong.OutputUnit(main, {})*/ const C(1);
 
-/*strong.element: C6:OutputUnit(3, {lib2})*/
+/*strong.member: C6:OutputUnit(3, {lib2})*/
 const C6 = /*strong.OutputUnit(2, {lib1, lib2})*/ const C(2);
 
-/*element: foo:OutputUnit(3, {lib2})*/
+/*member: foo:OutputUnit(3, {lib2})*/
 foo() {
   print("lib2");
   main.foo();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
index ae08f33..552be6b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_constants_main.dart
@@ -5,23 +5,23 @@
 import 'dont_inline_deferred_constants_lib1.dart' deferred as lib1;
 import 'dont_inline_deferred_constants_lib2.dart' deferred as lib2;
 
-/*strong.element: c:OutputUnit(main, {})*/
+/*strong.member: c:OutputUnit(main, {})*/
 const c = "string3";
 
 /*class: C:OutputUnit(main, {})*/
 class C {
-  /*element: C.p:OutputUnit(main, {})*/
+  /*member: C.p:OutputUnit(main, {})*/
   final p;
 
-  /*strong.element: C.:OutputUnit(main, {})*/
+  /*strong.member: C.:OutputUnit(main, {})*/
   const C(this.p);
 }
 
-/*element: foo:OutputUnit(2, {lib1, lib2})*/
+/*member: foo:OutputUnit(2, {lib1, lib2})*/
 foo() => print("main");
 
-/*strong.element: main:OutputUnit(main, {})*/
-/*strongConst.element: main:
+/*strong.member: main:OutputUnit(main, {})*/
+/*strongConst.member: main:
  OutputUnit(main, {}),
  constants=[
   ConstructedConstant(C(p=IntConstant(1)))=OutputUnit(main, {}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
index 626b672..262c084 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/dont_inline_deferred_global_lib.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*element: finalVar:OutputUnit(1, {lib})*/
+/*member: finalVar:OutputUnit(1, {lib})*/
 final finalVar = "string1";
 
-/*element: globalVar:OutputUnit(1, {lib})*/
+/*member: globalVar:OutputUnit(1, {lib})*/
 var globalVar = "string2";
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
index a5bf524..c11d4b8 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib1.dart
@@ -4,5 +4,5 @@
 
 import 'future_or_lib2.dart';
 
-/*strong.element: field:OutputUnit(1, {lib1})*/
+/*strong.member: field:OutputUnit(1, {lib1})*/
 const dynamic field = /*strong.OutputUnit(1, {lib1})*/ const A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
index 3c7fcbc..634a6b4 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/future_or_lib2.dart
@@ -4,9 +4,9 @@
 
 /*class: A:OutputUnit(main, {})*/
 class A {
-  /*strong.element: A.:OutputUnit(1, {lib1})*/
+  /*strong.member: A.:OutputUnit(1, {lib1})*/
   const A();
 
-  /*element: A.method:OutputUnit(main, {})*/
+  /*member: A.method:OutputUnit(main, {})*/
   method() {}
 }
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
index 67ababf..533595e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation0_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
  OutputUnit(1, {b}),
  constants=[InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
index 0124514..03ca1d9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
  OutputUnit(1, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(1, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
index 4f60650..eaf6318 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation1_strong_lib2.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
 T getFoo<T, S>(T v, S w) => v;
 
 typedef dynamic G<T, S>(T v, S w);
 
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int, int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
index 4a7f401..a5b2423 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(2, {b})*/
+/*member: getFoo:OutputUnit(2, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(2, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(2, {b})*/
+/*strongConst.member: m:
  OutputUnit(2, {b}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(2, {b})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
index 6b47d58..7e50462 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation2_strong_lib2.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
  OutputUnit(3, {c}),
  constants=[
   InstantiationConstant([int],FunctionConstant(getFoo))=OutputUnit(3, {c})]
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
index 89af87b..74a68cb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation3_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
  OutputUnit(1, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
index 89af87b..74a68cb 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(1, {b})*/
+/*member: getFoo:OutputUnit(1, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(1, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(1, {b})*/
+/*strongConst.member: m:
  OutputUnit(1, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(1, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
index 3d0891b..d1ac5bc 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation4_strong_lib2.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
 T getFoo<T, S>(T v, S w) => v;
 
 typedef dynamic G<T, S>(T v, S w);
 
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
  OutputUnit(3, {c}),
  constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
index dd75082..18813d7 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib1.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(2, {b})*/
+/*member: getFoo:OutputUnit(2, {b})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(2, {b})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(2, {b})*/
+/*strongConst.member: m:
  OutputUnit(2, {b}),
  constants=[FunctionConstant(getFoo)=OutputUnit(2, {b})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
index 17a6fdc..ddc4f0e9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/instantiation5_strong_lib2.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: getFoo:OutputUnit(3, {c})*/
+/*member: getFoo:OutputUnit(3, {c})*/
 T getFoo<T>(T v) => v;
 
 typedef dynamic G<T>(T v);
 
-/*strong.element: m:OutputUnit(3, {c})*/
-/*strongConst.element: m:
+/*strong.member: m:OutputUnit(3, {c})*/
+/*strongConst.member: m:
  OutputUnit(3, {c}),
  constants=[FunctionConstant(getFoo)=OutputUnit(3, {c})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
index dc47eae..7a5817c 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_a.dart
@@ -4,8 +4,8 @@
 
 import 'shared_constant_shared.dart' deferred as s1;
 
-/*strong.element: doA:OutputUnit(main, {})*/
-/*strongConst.element: doA:
+/*strong.member: doA:OutputUnit(main, {})*/
+/*strongConst.member: doA:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
index 8ec4363..e4cd5e7 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_b.dart
@@ -4,8 +4,8 @@
 
 import 'shared_constant_shared.dart' deferred as s2;
 
-/*strong.element: doB:OutputUnit(main, {})*/
-/*strongConst.element: doB:
+/*strong.member: doB:OutputUnit(main, {})*/
+/*strongConst.member: doB:
  OutputUnit(main, {}),
  constants=[ConstructedConstant(C())=OutputUnit(1, {s1, s2})]
 */
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
index 5c7759a..8d1d346 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_c.dart
@@ -4,9 +4,9 @@
 
 /*class: C:OutputUnit(1, {s1, s2})*/
 class C {
-  /*strong.element: C.:OutputUnit(1, {s1, s2})*/
+  /*strong.member: C.:OutputUnit(1, {s1, s2})*/
   const C();
 
-  /*element: C.method:OutputUnit(1, {s1, s2})*/
+  /*member: C.method:OutputUnit(1, {s1, s2})*/
   method() => print("1");
 }
diff --git a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
index b29aeba..d11cc9e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/shared_constant_shared.dart
@@ -4,6 +4,6 @@
 
 import 'shared_constant_c.dart';
 
-/*strong.element: constant:OutputUnit(1, {s1, s2})*/
+/*strong.member: constant:OutputUnit(1, {s1, s2})*/
 const constant =
     /*strong.OutputUnit(1, {s1, s2})*/ const C();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
index 4707d65..f61fbe9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib1.dart
@@ -6,15 +6,15 @@
 
 /*class: ConstClass:OutputUnit(2, {lib1, lib2})*/
 class ConstClass {
-  /*element: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
+  /*member: ConstClass.x:OutputUnit(2, {lib1, lib2})*/
   final x;
 
-  /*strong.element: ConstClass.:OutputUnit(2, {lib1, lib2})*/
+  /*strong.member: ConstClass.:OutputUnit(2, {lib1, lib2})*/
   const ConstClass(this.x);
 }
 
-/*strong.element: x:OutputUnit(2, {lib1, lib2})*/
-/*strongConst.element: x:
+/*strong.member: x:OutputUnit(2, {lib1, lib2})*/
+/*strongConst.member: x:
  OutputUnit(2, {lib1, lib2}),
  constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
 */
@@ -22,16 +22,16 @@
 
 /*class: C:OutputUnit(1, {lib1})*/
 class C {
-  /*element: C.foo:OutputUnit(3, {lib2})*/
+  /*member: C.foo:OutputUnit(3, {lib2})*/
   static foo() {
     /*OutputUnit(3, {lib2})*/ () {}(); // Hack to avoid inlining.
     return 1;
   }
 
-  /*element: C.:OutputUnit(1, {lib1})*/
+  /*member: C.:OutputUnit(1, {lib1})*/
   C();
 
-  /*element: C.bar:OutputUnit(1, {lib1})*/
+  /*member: C.bar:OutputUnit(1, {lib1})*/
   bar() {
     /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
     return 1;
@@ -40,8 +40,8 @@
 
 /*class: C1:null*/
 class C1 {
-  /*strong.element: C1.foo:OutputUnit(3, {lib2})*/
-  /*strongConst.element: C1.foo:
+  /*strong.member: C1.foo:OutputUnit(3, {lib2})*/
+  /*strongConst.member: C1.foo:
    OutputUnit(3, {lib2}),
    constants=[MapConstant({})=OutputUnit(3, {lib2})]
   */
@@ -51,59 +51,59 @@
 
 /*class: C2:OutputUnit(1, {lib1})*/
 class C2 {
-  /*element: C2.foo:OutputUnit(3, {lib2})*/
+  /*member: C2.foo:OutputUnit(3, {lib2})*/
   static var foo = new Map<int, int>.from({1: 2});
 
-  /*element: C2.bar:OutputUnit(1, {lib1})*/
+  /*member: C2.bar:OutputUnit(1, {lib1})*/
   var bar = new Map<int, int>.from({1: 2});
 
-  /*element: C2.:OutputUnit(1, {lib1})*/
+  /*member: C2.:OutputUnit(1, {lib1})*/
   C2();
 }
 
 /*class: C3:OutputUnit(1, {lib1})*/
 class C3 {
-  /*strong.element: C3.foo:OutputUnit(3, {lib2})*/
-  /*strongConst.element: C3.foo:
+  /*strong.member: C3.foo:OutputUnit(3, {lib2})*/
+  /*strongConst.member: C3.foo:
    OutputUnit(3, {lib2}),
    constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
   */
   static final foo = const ConstClass(const ConstClass(1));
 
-  /*strong.element: C3.bar:OutputUnit(1, {lib1})*/
-  /*strongConst.element: C3.bar:
+  /*strong.member: C3.bar:OutputUnit(1, {lib1})*/
+  /*strongConst.member: C3.bar:
    OutputUnit(1, {lib1}),
    constants=[ConstructedConstant(ConstClass(x=ConstructedConstant(ConstClass(x=IntConstant(1)))))=OutputUnit(2, {lib1, lib2})]
   */
   final bar = const ConstClass(const ConstClass(1));
 
-  /*element: C3.:OutputUnit(1, {lib1})*/
+  /*member: C3.:OutputUnit(1, {lib1})*/
   C3();
 }
 
 /*class: C4:OutputUnit(1, {lib1})*/
 class C4 {
-  /*element: C4.foo:OutputUnit(3, {lib2})*/
+  /*member: C4.foo:OutputUnit(3, {lib2})*/
   static final foo = new Map<ConstClass, ConstClass>.from({x: x});
 
-  /*element: C4.bar:OutputUnit(1, {lib1})*/
+  /*member: C4.bar:OutputUnit(1, {lib1})*/
   final bar = new Map<ConstClass, ConstClass>.from({x: x});
 
-  /*element: C4.:OutputUnit(1, {lib1})*/
+  /*member: C4.:OutputUnit(1, {lib1})*/
   C4();
 }
 
 /*class: C5:OutputUnit(1, {lib1})*/
 class C5 {
-  /*strong.element: C5.foo:OutputUnit(3, {lib2})*/
+  /*strong.member: C5.foo:OutputUnit(3, {lib2})*/
   static const foo = /*strong.OutputUnit(3, {lib2})*/ const [
     const {1: 3}
   ];
 
-  /*element: C5.:OutputUnit(1, {lib1})*/
+  /*member: C5.:OutputUnit(1, {lib1})*/
   C5();
 
-  /*element: C5.bar:OutputUnit(1, {lib1})*/
+  /*member: C5.bar:OutputUnit(1, {lib1})*/
   bar() {
     /*OutputUnit(1, {lib1})*/ () {}(); // Hack to avoid inlining.
     return 1;
diff --git a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
index bb0ca27..e0bf128 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/static_separate_lib2.dart
@@ -7,8 +7,8 @@
 import "package:expect/expect.dart";
 import "static_separate_lib1.dart";
 
-/*strong.element: foo:OutputUnit(3, {lib2})*/
-/*strongConst.element: foo:
+/*strong.member: foo:OutputUnit(3, {lib2})*/
+/*strongConst.member: foo:
  OutputUnit(3, {lib2}),
  constants=[
   ListConstant(<Map<int,int>>[MapConstant(<int, int>{IntConstant(1): IntConstant(3)})])=OutputUnit(3, {lib2}),
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
index d785ac6..c89d690 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib1.dart
@@ -4,5 +4,5 @@
 
 import 'type_argument_dependency_lib2.dart';
 
-/*element: doCast:OutputUnit(main, {})*/
+/*member: doCast:OutputUnit(main, {})*/
 doCast(List<dynamic> l) => l.cast<B>().map(/*OutputUnit(main, {})*/ (x) => 1);
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
index 4ed198d..452d66e 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_argument_dependency_lib2.dart
@@ -4,12 +4,12 @@
 
 /*class: A:OutputUnit(main, {})*/
 class A {
-  /*element: A.:OutputUnit(1, {c})*/
+  /*member: A.:OutputUnit(1, {c})*/
   A();
 }
 
 /*class: B:OutputUnit(main, {})*/
 class B extends A {}
 
-/*element: createA:OutputUnit(1, {c})*/
+/*member: createA:OutputUnit(1, {c})*/
 createA() => new A();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
index b66d8d2..7d907f9 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib1.dart
@@ -6,15 +6,15 @@
 
 /*class: A:OutputUnit(1, {lib1})*/
 class A<T> {
-  /*strong.element: A.:OutputUnit(1, {lib1})*/
+  /*strong.member: A.:OutputUnit(1, {lib1})*/
   const A();
 }
 
 /*class: B:OutputUnit(1, {lib1})*/
 class B {}
 
-/*strong.element: field1:OutputUnit(1, {lib1})*/
+/*strong.member: field1:OutputUnit(1, {lib1})*/
 const dynamic field1 = /*strong.OutputUnit(1, {lib1})*/ const A<B>();
 
-/*strong.element: field2:OutputUnit(1, {lib1})*/
+/*strong.member: field2:OutputUnit(1, {lib1})*/
 const dynamic field2 = /*strong.OutputUnit(1, {lib1})*/ const A<F>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
index 12b8c62..571959b 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib2.dart
@@ -4,12 +4,12 @@
 
 /*class: C:OutputUnit(main, {})*/
 class C<T> {
-  /*strong.element: C.:OutputUnit(main, {})*/
+  /*strong.member: C.:OutputUnit(main, {})*/
   const C();
 }
 
 /*class: D:OutputUnit(main, {})*/
 class D {}
 
-/*strong.element: field:OutputUnit(main, {})*/
+/*strong.member: field:OutputUnit(main, {})*/
 const dynamic field = /*strong.OutputUnit(main, {})*/ const C<D>();
diff --git a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
index c280a53..2ef8be5 100644
--- a/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
+++ b/tests/compiler/dart2js/deferred_loading/libs/type_arguments_lib3.dart
@@ -4,12 +4,12 @@
 
 /*class: E:OutputUnit(3, {lib3})*/
 class E<T> {
-  /*strong.element: E.:OutputUnit(3, {lib3})*/
+  /*strong.member: E.:OutputUnit(3, {lib3})*/
   const E();
 }
 
 /*class: F:OutputUnit(2, {lib1, lib3})*/
 class F {}
 
-/*strong.element: field:OutputUnit(3, {lib3})*/
+/*strong.member: field:OutputUnit(3, {lib3})*/
 const dynamic field = /*strong.OutputUnit(3, {lib3})*/ const E<F>();
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence.dart b/tests/compiler/dart2js/equivalence/id_equivalence.dart
index c6beb4da..762af65 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence.dart
@@ -7,493 +7,42 @@
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:expect/expect.dart';
 import 'package:kernel/ast.dart' as ir;
+import 'package:front_end/src/testing/id.dart';
+import 'package:front_end/src/testing/id_extractor.dart';
 
-enum IdKind {
-  element,
-  cls,
-  node,
-  invoke,
-  update,
-  iterator,
-  current,
-  moveNext,
+export 'package:front_end/src/testing/id.dart';
+export 'package:front_end/src/testing/id_extractor.dart';
+
+SourceSpan computeSourceSpanFromUriOffset(Uri uri, int offset) {
+  return uri != null ? new SourceSpan(uri, offset, offset + 1) : null;
 }
 
-/// Id for a code point or element with type inference information.
-abstract class Id {
-  IdKind get kind;
-  bool get isGlobal;
-
-  /// Display name for this id.
-  String get descriptor;
-}
-
-class IdValue {
-  final Id id;
-  final String value;
-
-  const IdValue(this.id, this.value);
-
-  @override
-  int get hashCode => id.hashCode * 13 + value.hashCode * 17;
-
-  @override
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! IdValue) return false;
-    return id == other.id && value == other.value;
-  }
-
-  @override
-  String toString() => idToString(id, value);
-
-  static String idToString(Id id, String value) {
-    switch (id.kind) {
-      case IdKind.element:
-        ElementId elementId = id;
-        return '$elementPrefix${elementId.name}:$value';
-      case IdKind.cls:
-        ClassId classId = id;
-        return '$classPrefix${classId.name}:$value';
-      case IdKind.node:
-        return value;
-      case IdKind.invoke:
-        return '$invokePrefix$value';
-      case IdKind.update:
-        return '$updatePrefix$value';
-      case IdKind.iterator:
-        return '$iteratorPrefix$value';
-      case IdKind.current:
-        return '$currentPrefix$value';
-      case IdKind.moveNext:
-        return '$moveNextPrefix$value';
-    }
-    throw new UnsupportedError("Unexpected id kind: ${id.kind}");
-  }
-
-  static const String globalPrefix = "global#";
-  static const String elementPrefix = "element: ";
-  static const String classPrefix = "class: ";
-  static const String invokePrefix = "invoke: ";
-  static const String updatePrefix = "update: ";
-  static const String iteratorPrefix = "iterator: ";
-  static const String currentPrefix = "current: ";
-  static const String moveNextPrefix = "moveNext: ";
-
-  static IdValue decode(int offset, String text) {
-    Id id;
-    String expected;
-    if (text.startsWith(elementPrefix)) {
-      text = text.substring(elementPrefix.length);
-      int colonPos = text.indexOf(':');
-      if (colonPos == -1) throw "Invalid element id: '$text'";
-      String name = text.substring(0, colonPos);
-      bool isGlobal = name.startsWith(globalPrefix);
-      if (isGlobal) {
-        name = name.substring(globalPrefix.length);
-      }
-      id = new ElementId(name, isGlobal: isGlobal);
-      expected = text.substring(colonPos + 1);
-    } else if (text.startsWith(classPrefix)) {
-      text = text.substring(classPrefix.length);
-      int colonPos = text.indexOf(':');
-      if (colonPos == -1) throw "Invalid class id: '$text'";
-      String name = text.substring(0, colonPos);
-      bool isGlobal = name.startsWith(globalPrefix);
-      if (isGlobal) {
-        name = name.substring(globalPrefix.length);
-      }
-      id = new ClassId(name, isGlobal: isGlobal);
-      expected = text.substring(colonPos + 1);
-    } else if (text.startsWith(invokePrefix)) {
-      id = new NodeId(offset, IdKind.invoke);
-      expected = text.substring(invokePrefix.length);
-    } else if (text.startsWith(updatePrefix)) {
-      id = new NodeId(offset, IdKind.update);
-      expected = text.substring(updatePrefix.length);
-    } else if (text.startsWith(iteratorPrefix)) {
-      id = new NodeId(offset, IdKind.iterator);
-      expected = text.substring(iteratorPrefix.length);
-    } else if (text.startsWith(currentPrefix)) {
-      id = new NodeId(offset, IdKind.current);
-      expected = text.substring(currentPrefix.length);
-    } else if (text.startsWith(moveNextPrefix)) {
-      id = new NodeId(offset, IdKind.moveNext);
-      expected = text.substring(moveNextPrefix.length);
-    } else {
-      id = new NodeId(offset, IdKind.node);
-      expected = text;
-    }
-    // Remove newlines.
-    expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
-    return new IdValue(id, expected);
-  }
-}
-
-/// Id for an member element.
-class ElementId implements Id {
-  final String className;
-  final String memberName;
-  @override
-  final bool isGlobal;
-
-  factory ElementId(String text, {bool isGlobal: false}) {
-    int dotPos = text.indexOf('.');
-    if (dotPos != -1) {
-      return new ElementId.internal(text.substring(dotPos + 1),
-          className: text.substring(0, dotPos), isGlobal: isGlobal);
-    } else {
-      return new ElementId.internal(text, isGlobal: isGlobal);
-    }
-  }
-
-  ElementId.internal(this.memberName, {this.className, this.isGlobal: false});
-
-  @override
-  int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;
-
-  @override
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! ElementId) return false;
-    return className == other.className && memberName == other.memberName;
-  }
-
-  @override
-  IdKind get kind => IdKind.element;
-
-  String get name => className != null ? '$className.$memberName' : memberName;
-
-  @override
-  String get descriptor => 'member $name';
-
-  @override
-  String toString() => 'element:$name';
-}
-
-/// Id for a class.
-class ClassId implements Id {
-  final String className;
-  @override
-  final bool isGlobal;
-
-  ClassId(this.className, {this.isGlobal: false});
-
-  @override
-  int get hashCode => className.hashCode * 13;
-
-  @override
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! ClassId) return false;
-    return className == other.className;
-  }
-
-  @override
-  IdKind get kind => IdKind.cls;
-
-  String get name => className;
-
-  @override
-  String get descriptor => 'class $name';
-
-  @override
-  String toString() => 'class:$name';
-}
-
-/// Id for a code point with type inference information.
-// TODO(johnniwinther): Create an [NodeId]-based equivalence with the kernel IR.
-class NodeId implements Id {
-  final int value;
-  @override
-  final IdKind kind;
-
-  const NodeId(this.value, this.kind);
-
-  @override
-  bool get isGlobal => false;
-
-  @override
-  int get hashCode => value.hashCode * 13 + kind.hashCode * 17;
-
-  @override
-  bool operator ==(other) {
-    if (identical(this, other)) return true;
-    if (other is! NodeId) return false;
-    return value == other.value && kind == other.kind;
-  }
-
-  @override
-  String get descriptor => 'offset $value ($kind)';
-
-  @override
-  String toString() => '$kind:$value';
-}
-
-class ActualData<T> {
-  final Id id;
-  final T value;
-  final SourceSpan sourceSpan;
-  final Object object;
-
-  ActualData(this.id, this.value, this.sourceSpan, this.object);
-
-  int get offset {
-    if (id is NodeId) {
-      NodeId nodeId = id;
-      return nodeId.value;
-    } else {
-      return sourceSpan.begin;
-    }
-  }
-
-  String get objectText {
-    return 'object `${'$object'.replaceAll('\n', '')}` (${object.runtimeType})';
-  }
-
-  @override
-  String toString() =>
-      'ActualData(id=$id,value=$value,sourceSpan=$sourceSpan,object=$objectText)';
-}
-
-abstract class DataRegistry<T> {
+abstract class IrDataRegistryMixin<T> implements DataRegistry<T> {
   DiagnosticReporter get reporter;
-  Map<Id, ActualData<T>> get actualMap;
 
-  void registerValue(SourceSpan sourceSpan, Id id, T value, Object object) {
-    if (actualMap.containsKey(id)) {
-      ActualData<T> existingData = actualMap[id];
-      reportHere(reporter, sourceSpan,
-          "Duplicate id ${id}, value=$value, object=$object");
-      reportHere(
-          reporter,
-          sourceSpan,
-          "Duplicate id ${id}, value=${existingData.value}, "
-          "object=${existingData.object}");
-      Expect.fail("Duplicate id $id.");
-    }
-    if (value != null) {
-      actualMap[id] = new ActualData<T>(id, value, sourceSpan, object);
-    }
+  @override
+  void report(Uri uri, int offset, String message) {
+    reportHere(reporter, computeSourceSpanFromUriOffset(uri, offset), message);
+  }
+
+  @override
+  void fail(String message) {
+    Expect.fail(message);
   }
 }
 
-/// Compute a canonical [Id] for kernel-based nodes.
-Id computeEntityId(ir.Member node) {
-  String className;
-  if (node.enclosingClass != null) {
-    className = node.enclosingClass.name;
-  }
-  String memberName = node.name.name;
-  if (node is ir.Procedure && node.kind == ir.ProcedureKind.Setter) {
-    memberName += '=';
-  }
-  return new ElementId.internal(memberName, className: className);
-}
-
-/// Abstract IR visitor for computing data corresponding to a node or element,
-/// and record it with a generic [Id]
-abstract class IrDataExtractor<T> extends ir.Visitor with DataRegistry<T> {
+abstract class IrDataExtractor<T> extends DataExtractor<T>
+    with IrDataRegistryMixin<T> {
   @override
   final DiagnosticReporter reporter;
-  @override
-  final Map<Id, ActualData<T>> actualMap;
 
-  /// Implement this to compute the data corresponding to [member].
-  ///
-  /// If `null` is returned, [member] has no associated data.
-  T computeMemberValue(Id id, ir.Member member);
-
-  /// Implement this to compute the data corresponding to [node].
-  ///
-  /// If `null` is returned, [node] has no associated data.
-  T computeNodeValue(Id id, ir.TreeNode node);
-
-  IrDataExtractor(this.reporter, this.actualMap);
-
-  void computeForMember(ir.Member member) {
-    ElementId id = computeEntityId(member);
-    if (id == null) return;
-    T value = computeMemberValue(id, member);
-    registerValue(computeSourceSpan(member), id, value, member);
-  }
-
-  void computeForNode(ir.TreeNode node, NodeId id) {
-    if (id == null) return;
-    T value = computeNodeValue(id, node);
-    registerValue(computeSourceSpan(node), id, value, node);
-  }
+  IrDataExtractor(this.reporter, Map<Id, ActualData<T>> actualMap)
+      : super(actualMap);
 
   SourceSpan computeSourceSpan(ir.TreeNode node) {
     return computeSourceSpanFromTreeNode(node);
   }
 
-  NodeId computeDefaultNodeId(ir.TreeNode node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on $node (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.node);
-  }
-
-  NodeId createInvokeId(ir.TreeNode node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on ${node} (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.invoke);
-  }
-
-  NodeId createUpdateId(ir.TreeNode node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on ${node} (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.update);
-  }
-
-  NodeId createIteratorId(ir.ForInStatement node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on ${node} (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.iterator);
-  }
-
-  NodeId createCurrentId(ir.ForInStatement node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on ${node} (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.current);
-  }
-
-  NodeId createMoveNextId(ir.ForInStatement node) {
-    assert(node.fileOffset != ir.TreeNode.noOffset,
-        "No fileOffset on ${node} (${node.runtimeType})");
-    return new NodeId(node.fileOffset, IdKind.moveNext);
-  }
-
-  NodeId createLabeledStatementId(ir.LabeledStatement node) =>
-      computeDefaultNodeId(node.body);
-  NodeId createLoopId(ir.TreeNode node) => computeDefaultNodeId(node);
-  NodeId createGotoId(ir.TreeNode node) => computeDefaultNodeId(node);
-  NodeId createSwitchId(ir.SwitchStatement node) => computeDefaultNodeId(node);
-  NodeId createSwitchCaseId(ir.SwitchCase node) =>
-      new NodeId(node.expressionOffsets.first, IdKind.node);
-
-  void run(ir.Node root) {
-    root.accept(this);
-  }
-
-  @override
-  defaultNode(ir.Node node) {
-    node.visitChildren(this);
-  }
-
-  @override
-  defaultMember(ir.Member node) {
-    super.defaultMember(node);
-    computeForMember(node);
-  }
-
-  @override
-  visitMethodInvocation(ir.MethodInvocation node) {
-    ir.TreeNode receiver = node.receiver;
-    if (receiver is ir.VariableGet &&
-        receiver.variable.parent is ir.FunctionDeclaration) {
-      // This is an invocation of a named local function.
-      computeForNode(node, createInvokeId(node.receiver));
-      node.arguments.accept(this);
-    } else if (node.name.name == '==' &&
-        receiver is ir.VariableGet &&
-        receiver.variable.name == null) {
-      // This is a desugared `?.`.
-    } else if (node.name.name == '[]') {
-      computeForNode(node, computeDefaultNodeId(node));
-      super.visitMethodInvocation(node);
-    } else if (node.name.name == '[]=') {
-      computeForNode(node, createUpdateId(node));
-      super.visitMethodInvocation(node);
-    } else {
-      computeForNode(node, createInvokeId(node));
-      super.visitMethodInvocation(node);
-    }
-  }
-
-  @override
-  visitLoadLibrary(ir.LoadLibrary node) {
-    computeForNode(node, createInvokeId(node));
-  }
-
-  @override
-  visitPropertyGet(ir.PropertyGet node) {
-    computeForNode(node, computeDefaultNodeId(node));
-    super.visitPropertyGet(node);
-  }
-
-  @override
-  visitVariableDeclaration(ir.VariableDeclaration node) {
-    if (node.name != null && node.parent is! ir.FunctionDeclaration) {
-      // Skip synthetic variables and function declaration variables.
-      computeForNode(node, computeDefaultNodeId(node));
-    }
-    super.visitVariableDeclaration(node);
-  }
-
-  @override
-  visitFunctionDeclaration(ir.FunctionDeclaration node) {
-    computeForNode(node, computeDefaultNodeId(node));
-    super.visitFunctionDeclaration(node);
-  }
-
-  @override
-  visitFunctionExpression(ir.FunctionExpression node) {
-    computeForNode(node, computeDefaultNodeId(node));
-    super.visitFunctionExpression(node);
-  }
-
-  @override
-  visitVariableGet(ir.VariableGet node) {
-    if (node.variable.name != null && !node.variable.isFieldFormal) {
-      // Skip use of synthetic variables.
-      computeForNode(node, computeDefaultNodeId(node));
-    }
-    super.visitVariableGet(node);
-  }
-
-  @override
-  visitPropertySet(ir.PropertySet node) {
-    computeForNode(node, createUpdateId(node));
-    super.visitPropertySet(node);
-  }
-
-  @override
-  visitVariableSet(ir.VariableSet node) {
-    if (node.variable.name != null) {
-      // Skip use of synthetic variables.
-      computeForNode(node, createUpdateId(node));
-    }
-    super.visitVariableSet(node);
-  }
-
-  @override
-  visitDoStatement(ir.DoStatement node) {
-    computeForNode(node, createLoopId(node));
-    super.visitDoStatement(node);
-  }
-
-  @override
-  visitForStatement(ir.ForStatement node) {
-    computeForNode(node, createLoopId(node));
-    super.visitForStatement(node);
-  }
-
-  @override
-  visitForInStatement(ir.ForInStatement node) {
-    computeForNode(node, createLoopId(node));
-    computeForNode(node, createIteratorId(node));
-    computeForNode(node, createCurrentId(node));
-    computeForNode(node, createMoveNextId(node));
-    super.visitForInStatement(node);
-  }
-
-  @override
-  visitWhileStatement(ir.WhileStatement node) {
-    computeForNode(node, createLoopId(node));
-    super.visitWhileStatement(node);
-  }
-
   @override
   visitLabeledStatement(ir.LabeledStatement node) {
     if (!JumpVisitor.canBeBreakTarget(node.body) &&
@@ -502,30 +51,4 @@
     }
     super.visitLabeledStatement(node);
   }
-
-  @override
-  visitBreakStatement(ir.BreakStatement node) {
-    computeForNode(node, createGotoId(node));
-    super.visitBreakStatement(node);
-  }
-
-  @override
-  visitSwitchStatement(ir.SwitchStatement node) {
-    computeForNode(node, createSwitchId(node));
-    super.visitSwitchStatement(node);
-  }
-
-  @override
-  visitSwitchCase(ir.SwitchCase node) {
-    if (node.expressionOffsets.isNotEmpty) {
-      computeForNode(node, createSwitchCaseId(node));
-    }
-    super.visitSwitchCase(node);
-  }
-
-  @override
-  visitContinueSwitchStatement(ir.ContinueSwitchStatement node) {
-    computeForNode(node, createGotoId(node));
-    super.visitContinueSwitchStatement(node);
-  }
 }
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 799be65..548568d 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -14,7 +14,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/util/features.dart';
 import 'package:expect/expect.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 
 import '../helpers/memory_compiler.dart';
 import '../equivalence/id_equivalence.dart';
@@ -280,7 +280,7 @@
   }
 
   for (Id id in globalIds) {
-    if (id is ElementId) {
+    if (id is MemberId) {
       MemberEntity member;
       if (id.className != null) {
         ClassEntity cls = getGlobalClass(id.className);
@@ -403,9 +403,7 @@
   String actualCode(Uri uri) {
     Map<int, List<String>> annotations = <int, List<String>>{};
     actualMaps[uri].forEach((Id id, ActualData<T> data) {
-      annotations
-          .putIfAbsent(data.sourceSpan.begin, () => [])
-          .add('${data.value}');
+      annotations.putIfAbsent(data.offset, () => []).add('${data.value}');
     });
     return withAnnotations(code[uri].sourceCode, annotations);
   }
@@ -863,7 +861,7 @@
         if (!dataValidator.isEmpty(actual)) {
           reportError(
               data.compiler.reporter,
-              actualData.sourceSpan,
+              computeSourceSpanFromUriOffset(actualData.uri, actualData.offset),
               'EXTRA $mode DATA for ${id.descriptor}:\n '
               'object   : ${actualData.objectText}\n '
               'actual   : ${colorizeActual('${IdValue.idToString(id, actualText)}')}\n '
@@ -879,7 +877,7 @@
         if (unexpectedMessage != null) {
           reportError(
               data.compiler.reporter,
-              actualData.sourceSpan,
+              computeSourceSpanFromUriOffset(actualData.uri, actualData.offset),
               'UNEXPECTED $mode DATA for ${id.descriptor}:\n '
               'detail  : ${colorizeMessage(unexpectedMessage)}\n '
               'object  : ${actualData.objectText}\n '
@@ -951,7 +949,7 @@
     ElementEnvironment elementEnvironment, Uri mainUri, Id id) {
   if (id is NodeId) {
     return new SourceSpan(mainUri, id.value, id.value + 1);
-  } else if (id is ElementId) {
+  } else if (id is MemberId) {
     String memberName = id.memberName;
     bool isSetter = false;
     if (memberName != '[]=' && memberName != '==' && memberName.endsWith('=')) {
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
index d85a4a0..e5874e3 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -10,14 +10,14 @@
 }
 
 class Class1 {
-  /*element: Class1.field1:constant=BoolConstant(false)*/
+  /*member: Class1.field1:constant=BoolConstant(false)*/
   final bool field1;
 
   const Class1({this.field1: false});
 }
 
 class Class2 {
-  /*strongConst.element: Class2.field2:constant=BoolConstant(true)*/
+  /*strongConst.member: Class2.field2:constant=BoolConstant(true)*/
   final bool field2;
 
   const Class2({this.field2: false});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
index b228203..fad3d3b 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
@@ -12,7 +12,7 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:elided*/
+  /*member: Class1a.field1:elided*/
   int field1;
 }
 
@@ -22,7 +22,7 @@
 }
 
 class Class2a<T> {
-  /*element: Class2a.field2:elided*/
+  /*member: Class2a.field2:elided*/
   T field2;
 }
 
@@ -32,12 +32,12 @@
 }
 
 class Class3a {
-  /*element: Class3a.field3:elided*/
+  /*member: Class3a.field3:elided*/
   int field3;
 }
 
 class Class3b {
-  /*element: Class3b.field3:elided*/
+  /*member: Class3b.field3:elided*/
   int field3;
 }
 
@@ -47,12 +47,12 @@
 }
 
 class Class4a {
-  /*element: Class4a.field4:elided*/
+  /*member: Class4a.field4:elided*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*element: Class4b.field4:elided*/
+  /*member: Class4b.field4:elided*/
   @override
   int field4;
 }
diff --git a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
index 27a4a61..a5a0fbf 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/effectively_constant_state.dart
@@ -3,13 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 enum Enum {
-  /*strong.element: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
+  /*strong.member: Enum.a:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.a"),index=IntConstant(0)))*/
   a,
 
-  /*strong.element: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
+  /*strong.member: Enum.b:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.b"),index=IntConstant(1)))*/
   b,
 
-  /*strong.element: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
+  /*strong.member: Enum.c:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
   c,
 }
 
@@ -23,10 +23,10 @@
 tester3() {}
 
 class Class {
-  /*element: Class.state1:constant=IntConstant(1)*/
+  /*member: Class.state1:constant=IntConstant(1)*/
   final int state1;
 
-  /*element: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
+  /*member: Class.state2:constant=ConstructedConstant(Enum(_name=StringConstant("Enum.c"),index=IntConstant(2)))*/
   final Enum state2;
 
   Class({this.state1: 1, this.state2: Enum.c});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
index d6120a4..f56c73f 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/multi_initializers.dart
@@ -23,22 +23,22 @@
   var field1 = 0;
   var field2;
 
-  /*element: Class1.field3a:allocator,initial=IntConstant(3)*/
+  /*member: Class1.field3a:allocator,initial=IntConstant(3)*/
   var field3a;
 
-  /*element: Class1.field3b:constant=IntConstant(3)*/
+  /*member: Class1.field3b:constant=IntConstant(3)*/
   var field3b;
 
-  /*element: Class1.field4a:allocator,initial=IntConstant(4)*/
+  /*member: Class1.field4a:allocator,initial=IntConstant(4)*/
   var field4a = 4;
 
-  /*element: Class1.field4b:constant=IntConstant(4)*/
+  /*member: Class1.field4b:constant=IntConstant(4)*/
   var field4b = 4;
 
-  /*element: Class1.field5a:allocator,initial=IntConstant(5)*/
+  /*member: Class1.field5a:allocator,initial=IntConstant(5)*/
   var field5a = 5;
 
-  /*element: Class1.field5b:constant=IntConstant(5)*/
+  /*member: Class1.field5b:constant=IntConstant(5)*/
   var field5b = 5;
 
   Class1.a()
diff --git a/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart b/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
index 715a521..3e0cbf5 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/optional_parameters.dart
@@ -35,52 +35,52 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:*/
+  /*member: Class1a.field1:*/
   var field1;
 
-  /*element: Class1a.field2:*/
+  /*member: Class1a.field2:*/
   var field2;
 
-  /*element: Class1a.field3:allocator,initial=IntConstant(3)*/
+  /*member: Class1a.field3:allocator,initial=IntConstant(3)*/
   var field3;
 
   Class1a(this.field1, [this.field2 = 2, this.field3 = 3]);
 }
 
 class Class1b {
-  /*element: Class1b.field1:*/
+  /*member: Class1b.field1:*/
   var field1;
 
-  /*element: Class1b.field2:*/
+  /*member: Class1b.field2:*/
   var field2;
 
-  /*element: Class1b.field3:constant=IntConstant(3)*/
+  /*member: Class1b.field3:constant=IntConstant(3)*/
   var field3;
 
   Class1b(this.field1, [this.field2 = 2, this.field3 = 3]);
 }
 
 class Class2a {
-  /*element: Class2a.field1:*/
+  /*member: Class2a.field1:*/
   var field1;
 
-  /*element: Class2a.field2:*/
+  /*member: Class2a.field2:*/
   var field2;
 
-  /*element: Class2a.field3:allocator,initial=IntConstant(3)*/
+  /*member: Class2a.field3:allocator,initial=IntConstant(3)*/
   var field3;
 
   Class2a(this.field1, {this.field2 = 2, this.field3 = 3});
 }
 
 class Class2b {
-  /*element: Class2b.field1:*/
+  /*member: Class2b.field1:*/
   var field1;
 
-  /*element: Class2b.field2:*/
+  /*member: Class2b.field2:*/
   var field2;
 
-  /*element: Class2b.field3:constant=IntConstant(3)*/
+  /*member: Class2b.field3:constant=IntConstant(3)*/
   var field3;
 
   Class2b(this.field1, {this.field2 = 2, this.field3 = 3});
diff --git a/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart b/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
index d798780..a719c2e 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/regress_36222.dart
@@ -11,7 +11,7 @@
     return x + y;
   }
 
-  /*element: A.foo:constant=FunctionConstant(A.defaultFoo)*/
+  /*member: A.foo:constant=FunctionConstant(A.defaultFoo)*/
   final BinaryFunc foo;
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
index a04f242..0958aad 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/simple_initializers.dart
@@ -113,196 +113,196 @@
   use(c2.field13b);
 }
 
-/*strong.element: const1:constant=BoolConstant(true)*/
+/*strong.member: const1:constant=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
-  /*element: Class1.field0a:allocator,initial=NullConstant*/
+  /*member: Class1.field0a:allocator,initial=NullConstant*/
   var field0a;
 
-  /*element: Class1.field0b:constant=NullConstant*/
+  /*member: Class1.field0b:constant=NullConstant*/
   var field0b;
 
-  /*element: Class1.field1a:allocator,initial=NullConstant*/
+  /*member: Class1.field1a:allocator,initial=NullConstant*/
   var field1a = null;
 
-  /*element: Class1.field1b:constant=NullConstant*/
+  /*member: Class1.field1b:constant=NullConstant*/
   var field1b = null;
 
-  /*element: Class1.field2a:allocator,initial=BoolConstant(true)*/
+  /*member: Class1.field2a:allocator,initial=BoolConstant(true)*/
   var field2a = true;
 
-  /*element: Class1.field2b:constant=BoolConstant(true)*/
+  /*member: Class1.field2b:constant=BoolConstant(true)*/
   var field2b = true;
 
-  /*element: Class1.field3a:allocator,initial=BoolConstant(false)*/
+  /*member: Class1.field3a:allocator,initial=BoolConstant(false)*/
   var field3a = false;
 
-  /*element: Class1.field3b:constant=BoolConstant(false)*/
+  /*member: Class1.field3b:constant=BoolConstant(false)*/
   var field3b = false;
 
-  /*element: Class1.field4a:allocator,initial=IntConstant(0)*/
+  /*member: Class1.field4a:allocator,initial=IntConstant(0)*/
   var field4a = 0;
 
-  /*element: Class1.field4b:constant=IntConstant(0)*/
+  /*member: Class1.field4b:constant=IntConstant(0)*/
   var field4b = 0;
 
-  /*element: Class1.field5a:allocator,initial=IntConstant(1)*/
+  /*member: Class1.field5a:allocator,initial=IntConstant(1)*/
   var field5a = 1;
 
-  /*element: Class1.field5b:constant=IntConstant(1)*/
+  /*member: Class1.field5b:constant=IntConstant(1)*/
   var field5b = 1;
 
-  /*element: Class1.field6a:allocator,initial=StringConstant("")*/
+  /*member: Class1.field6a:allocator,initial=StringConstant("")*/
   var field6a = '';
 
-  /*element: Class1.field6b:constant=StringConstant("")*/
+  /*member: Class1.field6b:constant=StringConstant("")*/
   var field6b = '';
 
-  /*element: Class1.field7a:allocator,initial=StringConstant("foo")*/
+  /*member: Class1.field7a:allocator,initial=StringConstant("foo")*/
   var field7a = 'foo';
 
-  /*element: Class1.field7b:constant=StringConstant("foo")*/
+  /*member: Class1.field7b:constant=StringConstant("foo")*/
   var field7b = 'foo';
 
-  /*element: Class1.field8a:initial=DoubleConstant(0.5)*/
+  /*member: Class1.field8a:initial=DoubleConstant(0.5)*/
   var field8a = 0.5;
 
-  /*element: Class1.field8b:constant=DoubleConstant(0.5)*/
+  /*member: Class1.field8b:constant=DoubleConstant(0.5)*/
   var field8b = 0.5;
 
-  /*element: Class1.field9a:initial=ListConstant([])*/
+  /*member: Class1.field9a:initial=ListConstant([])*/
   var field9a = const [];
 
-  /*element: Class1.field9b:constant=ListConstant([])*/
+  /*member: Class1.field9b:constant=ListConstant([])*/
   var field9b = const [];
 
-  /*element: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*member: Class1.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
   var field9c = const [0, 1];
 
-  /*element: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*member: Class1.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
   var field9d = const [0, 1, 2];
 
-  /*element: Class1.field10a:initial=MapConstant({})*/
+  /*member: Class1.field10a:initial=MapConstant({})*/
   var field10a = const {};
 
-  /*element: Class1.field10b:constant=MapConstant({})*/
+  /*member: Class1.field10b:constant=MapConstant({})*/
   var field10b = const {};
 
-  /*element: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*member: Class1.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
   var field10c = const {0: 1, 2: 3};
 
-  /*element: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*member: Class1.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
   var field10d = const {0: 1, 2: 3, 4: 5};
 
-  /*element: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+  /*member: Class1.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
   var field11a = #foo;
 
-  /*element: Class1.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+  /*member: Class1.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
   var field11b = #foo;
 
-  /*element: Class1.field12a:allocator,initial=IntConstant(5)*/
+  /*member: Class1.field12a:allocator,initial=IntConstant(5)*/
   var field12a = 2 + 3;
 
-  /*element: Class1.field12b:constant=IntConstant(5)*/
+  /*member: Class1.field12b:constant=IntConstant(5)*/
   var field12b = 2 + 3;
 
-  /*element: Class1.field13a:allocator,initial=BoolConstant(true)*/
+  /*member: Class1.field13a:allocator,initial=BoolConstant(true)*/
   var field13a = const1;
 
-  /*element: Class1.field13b:constant=BoolConstant(true)*/
+  /*member: Class1.field13b:constant=BoolConstant(true)*/
   var field13b = const1;
 }
 
 class Class2 {
-  /*element: Class2.field1a:allocator,initial=NullConstant*/
+  /*member: Class2.field1a:allocator,initial=NullConstant*/
   var field1a;
 
-  /*element: Class2.field1b:constant=NullConstant*/
+  /*member: Class2.field1b:constant=NullConstant*/
   var field1b;
 
-  /*element: Class2.field2a:allocator,initial=BoolConstant(true)*/
+  /*member: Class2.field2a:allocator,initial=BoolConstant(true)*/
   var field2a;
 
-  /*element: Class2.field2b:constant=BoolConstant(true)*/
+  /*member: Class2.field2b:constant=BoolConstant(true)*/
   var field2b;
 
-  /*element: Class2.field3a:allocator,initial=BoolConstant(false)*/
+  /*member: Class2.field3a:allocator,initial=BoolConstant(false)*/
   var field3a;
 
-  /*element: Class2.field3b:constant=BoolConstant(false)*/
+  /*member: Class2.field3b:constant=BoolConstant(false)*/
   var field3b;
 
-  /*element: Class2.field4a:allocator,initial=IntConstant(0)*/
+  /*member: Class2.field4a:allocator,initial=IntConstant(0)*/
   var field4a;
 
-  /*element: Class2.field4b:constant=IntConstant(0)*/
+  /*member: Class2.field4b:constant=IntConstant(0)*/
   var field4b;
 
-  /*element: Class2.field5a:allocator,initial=IntConstant(1)*/
+  /*member: Class2.field5a:allocator,initial=IntConstant(1)*/
   var field5a;
 
-  /*element: Class2.field5b:constant=IntConstant(1)*/
+  /*member: Class2.field5b:constant=IntConstant(1)*/
   var field5b;
 
-  /*element: Class2.field6a:allocator,initial=StringConstant("")*/
+  /*member: Class2.field6a:allocator,initial=StringConstant("")*/
   var field6a;
 
-  /*element: Class2.field6b:constant=StringConstant("")*/
+  /*member: Class2.field6b:constant=StringConstant("")*/
   var field6b;
 
-  /*element: Class2.field7a:allocator,initial=StringConstant("foo")*/
+  /*member: Class2.field7a:allocator,initial=StringConstant("foo")*/
   var field7a;
 
-  /*element: Class2.field7b:constant=StringConstant("foo")*/
+  /*member: Class2.field7b:constant=StringConstant("foo")*/
   var field7b;
 
-  /*element: Class2.field8a:initial=DoubleConstant(0.5)*/
+  /*member: Class2.field8a:initial=DoubleConstant(0.5)*/
   var field8a;
 
-  /*element: Class2.field8b:constant=DoubleConstant(0.5)*/
+  /*member: Class2.field8b:constant=DoubleConstant(0.5)*/
   var field8b;
 
-  /*element: Class2.field9a:initial=ListConstant([])*/
+  /*member: Class2.field9a:initial=ListConstant([])*/
   var field9a;
 
-  /*element: Class2.field9b:constant=ListConstant([])*/
+  /*member: Class2.field9b:constant=ListConstant([])*/
   var field9b;
 
-  /*element: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
+  /*member: Class2.field9c:initial=ListConstant(<int>[IntConstant(0), IntConstant(1)])*/
   var field9c;
 
-  /*element: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
+  /*member: Class2.field9d:constant=ListConstant(<int>[IntConstant(0), IntConstant(1), IntConstant(2)])*/
   var field9d;
 
-  /*element: Class2.field10a:initial=MapConstant({})*/
+  /*member: Class2.field10a:initial=MapConstant({})*/
   var field10a;
 
-  /*element: Class2.field10b:constant=MapConstant({})*/
+  /*member: Class2.field10b:constant=MapConstant({})*/
   var field10b;
 
-  /*element: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
+  /*member: Class2.field10c:initial=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3)})*/
   var field10c;
 
-  /*element: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
+  /*member: Class2.field10d:constant=MapConstant(<int, int>{IntConstant(0): IntConstant(1), IntConstant(2): IntConstant(3), IntConstant(4): IntConstant(5)})*/
   var field10d;
 
-  /*element: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+  /*member: Class2.field11a:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
   var field11a;
 
-  /*element: Class2.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+  /*member: Class2.field11b:constant=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
   var field11b;
 
-  /*element: Class2.field12a:allocator,initial=IntConstant(5)*/
+  /*member: Class2.field12a:allocator,initial=IntConstant(5)*/
   var field12a;
 
-  /*element: Class2.field12b:constant=IntConstant(5)*/
+  /*member: Class2.field12b:constant=IntConstant(5)*/
   var field12b;
 
-  /*element: Class2.field13a:allocator,initial=BoolConstant(true)*/
+  /*member: Class2.field13a:allocator,initial=BoolConstant(true)*/
   var field13a;
 
-  /*element: Class2.field13b:constant=BoolConstant(true)*/
+  /*member: Class2.field13b:constant=BoolConstant(true)*/
   var field13b;
 
   Class2()
diff --git a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
index deb273c..b6d316f 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/static_initializers.dart
@@ -69,37 +69,37 @@
   const factory Class.fact() = Class.generative;
 }
 
-/*element: field1a:constant=IntConstant(0)*/
+/*member: field1a:constant=IntConstant(0)*/
 final field1a = 0;
 
-/*element: field1b:constant=IntConstant(0)*/
+/*member: field1b:constant=IntConstant(0)*/
 var field1b = 0;
 
-/*element: field1c:initial=IntConstant(0)*/
+/*member: field1c:initial=IntConstant(0)*/
 var field1c = 0;
 
-/*element: field2a:constant=ListConstant([])*/
+/*member: field2a:constant=ListConstant([])*/
 final field2a = const [];
 
-/*element: field2b:constant=ListConstant([])*/
+/*member: field2b:constant=ListConstant([])*/
 var field2b = const [];
 
-/*element: field2c:initial=ListConstant([])*/
+/*member: field2c:initial=ListConstant([])*/
 var field2c = const [];
 
-/*element: field3a:eager,final*/
+/*member: field3a:eager,final*/
 final field3a = [];
 
-/*element: field3b:eager,final*/
+/*member: field3b:eager,final*/
 var field3b = [];
 
-/*element: field3c:eager*/
+/*member: field3c:eager*/
 var field3c = [];
 
-/*element: field3d:eager,final*/
+/*member: field3d:eager,final*/
 var field3d = [1, 2, 3];
 
-/*element: field3e:eager,final*/
+/*member: field3e:eager,final*/
 var field3e = [
   1,
   2,
@@ -110,7 +110,7 @@
   ]
 ];
 
-/*element: field3f:final,lazy*/
+/*member: field3f:final,lazy*/
 var field3f = [
   1,
   2,
@@ -121,99 +121,99 @@
   ]
 ];
 
-/*element: field3g:final,lazy*/
+/*member: field3g:final,lazy*/
 var field3g = [method()];
 
 // TODO(johnniwinther): Recognize this as of eager complexity.
-/*element: field3h:final,lazy*/
+/*member: field3h:final,lazy*/
 var field3h = [1 + 3];
 
-/*element: field4a:constant=IntConstant(5)*/
+/*member: field4a:constant=IntConstant(5)*/
 final field4a = 2 + 3;
 
-/*element: field4b:constant=IntConstant(5)*/
+/*member: field4b:constant=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*strong.element: field4c:constant=IntConstant(5)*/
+/*strong.member: field4c:constant=IntConstant(5)*/
 const field4c = 2 + 3;
 
-/*element: field5a:constant=FunctionConstant(method)*/
+/*member: field5a:constant=FunctionConstant(method)*/
 final field5a = method;
 
-/*element: field5b:constant=FunctionConstant(method)*/
+/*member: field5b:constant=FunctionConstant(method)*/
 var field5b = method;
 
-/*strong.element: field5c:constant=FunctionConstant(method)*/
+/*strong.member: field5c:constant=FunctionConstant(method)*/
 const field5c = method;
 
-/*element: field6a:constant=ConstructedConstant(Class())*/
+/*member: field6a:constant=ConstructedConstant(Class())*/
 var field6a = const Class.generative();
 
-/*element: field6b:constant=ConstructedConstant(Class())*/
+/*member: field6b:constant=ConstructedConstant(Class())*/
 var field6b = const Class.fact();
 
-/*element: field6c:final,lazy*/
+/*member: field6c:final,lazy*/
 var field6c = method();
 
-/*element: field7a:eager,final*/
+/*member: field7a:eager,final*/
 var field7a = {};
 
-/*element: field7b:eager,final*/
+/*member: field7b:eager,final*/
 var field7b = {0: 1};
 
-/*element: field7c:eager,final*/
+/*member: field7c:eager,final*/
 var field7c = {0: method};
 
-/*element: field7d:final,lazy*/
+/*member: field7d:final,lazy*/
 var field7d = {0: method()};
 
-/*element: field7e:final,lazy*/
+/*member: field7e:final,lazy*/
 var field7e = {method(): 0};
 
-/*element: field8a:eager,final*/
+/*member: field8a:eager,final*/
 var field8a = {};
 
-/*element: field8b:eager,final*/
+/*member: field8b:eager,final*/
 var field8b = {0};
 
-/*element: field8c:eager,final*/
+/*member: field8c:eager,final*/
 var field8c = {method};
 
-/*element: field8d:final,lazy*/
+/*member: field8d:final,lazy*/
 var field8d = {method()};
 
-/*element: field9g:eager=[field9d],final,index=1*/
+/*member: field9g:eager=[field9d],final,index=1*/
 var field9g = field9d;
 
-/*element: field9a:eager,final*/
+/*member: field9a:eager,final*/
 var field9a = [];
 
-/*element: field9c:eager=[field9b],final,index=3*/
+/*member: field9c:eager=[field9b],final,index=3*/
 var field9c = [field9b];
 
-/*element: field9b:eager=[field9a],final,index=2*/
+/*member: field9b:eager=[field9a],final,index=2*/
 var field9b = field9a;
 
 // Because [field9g] is declared first and it depends upon [field9d], [field9d]
 // must be created before [field9g] and thus has a lower index than, say,
 // [field9b].
-/*element: field9d:eager=[field9a],final,index=0*/
+/*member: field9d:eager=[field9a],final,index=0*/
 var field9d = [field9a];
 
-/*element: field9e:eager*/
+/*member: field9e:eager*/
 var field9e = [];
 
-/*element: field9f:final,lazy*/
+/*member: field9f:final,lazy*/
 var field9f = field9e;
 
-/*element: field9h:constant=ListConstant([])*/
+/*member: field9h:constant=ListConstant([])*/
 var field9h = const [];
 
-/*element: field9i:eager,final*/
+/*member: field9i:eager,final*/
 var field9i = [field9h];
 
-/*element: field10a:final,lazy*/
+/*member: field10a:final,lazy*/
 int field10a = field10b;
 
-/*element: field10b:final,lazy*/
+/*member: field10b:final,lazy*/
 int field10b = field10a;
diff --git a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
index 219c643..cc189f1 100644
--- a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
+++ b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class1 {
-  /*element: Class1.field:constant=IntConstant(87)*/
+  /*member: Class1.field:constant=IntConstant(87)*/
   final int field;
 
   Class1.constructor1({this.field = 42});
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index a28477b..1a7ebe6 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -6,7 +6,6 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/field_analysis.dart';
 import 'package:compiler/src/js_model/js_world.dart';
 import 'package:compiler/src/util/features.dart';
@@ -78,8 +77,9 @@
         features.add(Tags.isEffectivelyFinal);
       }
       Id id = computeEntityId(node);
-      actualMap[id] = new ActualData<Features>(
-          id, features, computeSourceSpanFromTreeNode(node), member);
+      ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+      actualMap[id] = new ActualData<Features>(id, features,
+          nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
     }
   }
 
diff --git a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
index df9b18b..a8fd083 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
@@ -10,21 +10,21 @@
 }
 
 class Class1 {
-  /*element: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/
+  /*member: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/
   final bool field1;
 
   const Class1({this.field1: false});
 }
 
 class Class2 {
-  /*element: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/
+  /*member: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/
   final bool field2;
 
   const Class2({this.field2: false});
 }
 
 class Class3 {
-  /*element: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/
+  /*member: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/
   final bool field3;
 
   const Class3({this.field3: false});
diff --git a/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
index 0d7200d..e00b39c 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/multi_initializers.dart
@@ -8,30 +8,30 @@
 }
 
 class Class1 {
-  /*element: Class1.field1:
+  /*member: Class1.field1:
     Class1.a=IntConstant(1),
     initial=IntConstant(0)
    */
   var field1 = 0;
 
-  /*element: Class1.field2:
+  /*member: Class1.field2:
    Class1.a=IntConstant(1),
    Class1.b=IntConstant(2),
    initial=NullConstant
   */
   var field2;
 
-  /*element: Class1.field3:
+  /*member: Class1.field3:
    Class1.a=IntConstant(3),
    Class1.b=IntConstant(3),
    initial=NullConstant
   */
   var field3;
 
-  /*element: Class1.field4:initial=IntConstant(4)*/
+  /*member: Class1.field4:initial=IntConstant(4)*/
   var field4 = 4;
 
-  /*element: Class1.field5:
+  /*member: Class1.field5:
    Class1.a=IntConstant(5),
    Class1.b=IntConstant(5),
    initial=IntConstant(5)
diff --git a/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart b/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
index 1dbbde0..8a9d632 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/optional_parameters.dart
@@ -10,19 +10,19 @@
 }
 
 class Class1 {
-  /*element: Class1.field1:
+  /*member: Class1.field1:
    Class1.=?,
    initial=NullConstant
   */
   var field1;
 
-  /*element: Class1.field2:
+  /*member: Class1.field2:
    Class1.=1:IntConstant(2),
    initial=NullConstant
   */
   var field2;
 
-  /*element: Class1.field3:
+  /*member: Class1.field3:
    Class1.=2:IntConstant(3),
    initial=NullConstant
   */
@@ -32,19 +32,19 @@
 }
 
 class Class2 {
-  /*element: Class2.field1:
+  /*member: Class2.field1:
    Class2.=?,
    initial=NullConstant
   */
   var field1;
 
-  /*element: Class2.field2:
+  /*member: Class2.field2:
    Class2.=field2:IntConstant(2),
    initial=NullConstant
   */
   var field2;
 
-  /*element: Class2.field3:
+  /*member: Class2.field3:
    Class2.=field3:IntConstant(3),
    initial=NullConstant
   */
diff --git a/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart b/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
index 6794ac8..2641396 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/regress_36222.dart
@@ -11,7 +11,7 @@
     return x + y;
   }
 
-  /*element: A.foo:A.=foo:FunctionConstant(A.defaultFoo),initial=NullConstant*/
+  /*member: A.foo:A.=foo:FunctionConstant(A.defaultFoo),initial=NullConstant*/
   final BinaryFunc foo;
 }
 
diff --git a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
index f6bff5f..b2002b6 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/simple_initializers.dart
@@ -7,97 +7,97 @@
   new Class2();
 }
 
-/*strong.element: const1:complexity=constant,initial=BoolConstant(true)*/
+/*strong.member: const1:complexity=constant,initial=BoolConstant(true)*/
 const bool const1 = true;
 
 class Class1 {
-  /*element: Class1.field0:initial=NullConstant*/
+  /*member: Class1.field0:initial=NullConstant*/
   var field0;
 
-  /*element: Class1.field1:initial=NullConstant*/
+  /*member: Class1.field1:initial=NullConstant*/
   var field1 = null;
 
-  /*element: Class1.field2:initial=BoolConstant(true)*/
+  /*member: Class1.field2:initial=BoolConstant(true)*/
   var field2 = true;
 
-  /*element: Class1.field3:initial=BoolConstant(false)*/
+  /*member: Class1.field3:initial=BoolConstant(false)*/
   var field3 = false;
 
-  /*element: Class1.field4:initial=IntConstant(0)*/
+  /*member: Class1.field4:initial=IntConstant(0)*/
   var field4 = 0;
 
-  /*element: Class1.field5:initial=IntConstant(1)*/
+  /*member: Class1.field5:initial=IntConstant(1)*/
   var field5 = 1;
 
-  /*element: Class1.field6:initial=StringConstant("")*/
+  /*member: Class1.field6:initial=StringConstant("")*/
   var field6 = '';
 
-  /*element: Class1.field7:initial=StringConstant("foo")*/
+  /*member: Class1.field7:initial=StringConstant("foo")*/
   var field7 = 'foo';
 
-  /*element: Class1.field8:initial=DoubleConstant(0.5)*/
+  /*member: Class1.field8:initial=DoubleConstant(0.5)*/
   var field8 = 0.5;
 
-  /*element: Class1.field9:initial=ListConstant([])*/
+  /*member: Class1.field9:initial=ListConstant([])*/
   var field9 = const [];
 
-  /*element: Class1.field10:initial=MapConstant({})*/
+  /*member: Class1.field10:initial=MapConstant({})*/
   var field10 = const {};
 
-  /*element: Class1.field11:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
+  /*member: Class1.field11:initial=ConstructedConstant(Symbol(_name=StringConstant("foo")))*/
   var field11 = #foo;
 
-  /*element: Class1.field12:initial=IntConstant(5)*/
+  /*member: Class1.field12:initial=IntConstant(5)*/
   var field12 = 2 + 3;
 
-  /*element: Class1.field13:initial=BoolConstant(true)*/
+  /*member: Class1.field13:initial=BoolConstant(true)*/
   var field13 = const1;
 
-  /*element: Class1.field14:*/
+  /*member: Class1.field14:*/
   var field14 = const1 is int;
 }
 
 class Class2 {
-  /*element: Class2.field1:Class2.=NullConstant,initial=NullConstant*/
+  /*member: Class2.field1:Class2.=NullConstant,initial=NullConstant*/
   var field1;
 
-  /*element: Class2.field2:Class2.=BoolConstant(true),initial=NullConstant*/
+  /*member: Class2.field2:Class2.=BoolConstant(true),initial=NullConstant*/
   var field2;
 
-  /*element: Class2.field3:Class2.=BoolConstant(false),initial=NullConstant*/
+  /*member: Class2.field3:Class2.=BoolConstant(false),initial=NullConstant*/
   var field3;
 
-  /*element: Class2.field4:Class2.=IntConstant(0),initial=NullConstant*/
+  /*member: Class2.field4:Class2.=IntConstant(0),initial=NullConstant*/
   var field4;
 
-  /*element: Class2.field5:Class2.=IntConstant(1),initial=NullConstant*/
+  /*member: Class2.field5:Class2.=IntConstant(1),initial=NullConstant*/
   var field5;
 
-  /*element: Class2.field6:Class2.=StringConstant(""),initial=NullConstant*/
+  /*member: Class2.field6:Class2.=StringConstant(""),initial=NullConstant*/
   var field6;
 
-  /*element: Class2.field7:Class2.=StringConstant("foo"),initial=NullConstant*/
+  /*member: Class2.field7:Class2.=StringConstant("foo"),initial=NullConstant*/
   var field7;
 
-  /*element: Class2.field8:Class2.=DoubleConstant(0.5),initial=NullConstant*/
+  /*member: Class2.field8:Class2.=DoubleConstant(0.5),initial=NullConstant*/
   var field8;
 
-  /*element: Class2.field9:Class2.=ListConstant([]),initial=NullConstant*/
+  /*member: Class2.field9:Class2.=ListConstant([]),initial=NullConstant*/
   var field9;
 
-  /*element: Class2.field10:Class2.=MapConstant({}),initial=NullConstant*/
+  /*member: Class2.field10:Class2.=MapConstant({}),initial=NullConstant*/
   var field10;
 
-  /*element: Class2.field11:Class2.=ConstructedConstant(Symbol(_name=StringConstant("foo"))),initial=NullConstant*/
+  /*member: Class2.field11:Class2.=ConstructedConstant(Symbol(_name=StringConstant("foo"))),initial=NullConstant*/
   var field11;
 
-  /*element: Class2.field12:Class2.=IntConstant(5),initial=NullConstant*/
+  /*member: Class2.field12:Class2.=IntConstant(5),initial=NullConstant*/
   var field12;
 
-  /*element: Class2.field13:Class2.=BoolConstant(true),initial=NullConstant*/
+  /*member: Class2.field13:Class2.=BoolConstant(true),initial=NullConstant*/
   var field13;
 
-  /*element: Class2.field14:Class2.=?,initial=NullConstant*/
+  /*member: Class2.field14:Class2.=?,initial=NullConstant*/
   var field14;
 
   Class2()
diff --git a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
index 4096f9e..b2c12c7 100644
--- a/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
+++ b/tests/compiler/dart2js/field_analysis/kdata/static_initializers.dart
@@ -59,37 +59,37 @@
   const factory Class.fact() = Class.generative;
 }
 
-/*element: field1a:complexity=constant,initial=IntConstant(0)*/
+/*member: field1a:complexity=constant,initial=IntConstant(0)*/
 final field1a = 0;
 
-/*element: field1b:complexity=constant,initial=IntConstant(0)*/
+/*member: field1b:complexity=constant,initial=IntConstant(0)*/
 var field1b = 0;
 
-/*strong.element: field1c:complexity=constant,initial=IntConstant(0)*/
+/*strong.member: field1c:complexity=constant,initial=IntConstant(0)*/
 const field1c = 0;
 
-/*element: field2a:complexity=constant,initial=ListConstant([])*/
+/*member: field2a:complexity=constant,initial=ListConstant([])*/
 final field2a = const [];
 
-/*element: field2b:complexity=constant,initial=ListConstant([])*/
+/*member: field2b:complexity=constant,initial=ListConstant([])*/
 var field2b = const [];
 
-/*strong.element: field2c:complexity=constant,initial=ListConstant([])*/
+/*strong.member: field2c:complexity=constant,initial=ListConstant([])*/
 const field2c = const [];
 
-/*element: field3a:complexity=eager*/
+/*member: field3a:complexity=eager*/
 final field3a = [];
 
-/*element: field3b:complexity=eager*/
+/*member: field3b:complexity=eager*/
 var field3b = [];
 
-/*element: field3c:complexity=eager*/
+/*member: field3c:complexity=eager*/
 var field3c = [];
 
-/*element: field3d:complexity=eager*/
+/*member: field3d:complexity=eager*/
 var field3d = [1, 2, 3];
 
-/*element: field3e:complexity=eager*/
+/*member: field3e:complexity=eager*/
 var field3e = [
   1,
   2,
@@ -100,7 +100,7 @@
   ]
 ];
 
-/*element: field3f:complexity=lazy*/
+/*member: field3f:complexity=lazy*/
 var field3f = [
   1,
   2,
@@ -111,79 +111,79 @@
   ]
 ];
 
-/*element: field3g:complexity=lazy*/
+/*member: field3g:complexity=lazy*/
 var field3g = [method()];
 
 // TODO(johnniwinther): Recognize this as of eager complexity.
-/*element: field3h:complexity=lazy*/
+/*member: field3h:complexity=lazy*/
 var field3h = [1 + 3];
 
 // TODO(johnniwinther): Recognize `field4*` as of constant complexity.
-/*element: field4a:complexity=lazy,initial=IntConstant(5)*/
+/*member: field4a:complexity=lazy,initial=IntConstant(5)*/
 final field4a = 2 + 3;
 
-/*element: field4b:complexity=lazy,initial=IntConstant(5)*/
+/*member: field4b:complexity=lazy,initial=IntConstant(5)*/
 var field4b = 2 + 3;
 
-/*strong.element: field4c:complexity=lazy,initial=IntConstant(5)*/
+/*strong.member: field4c:complexity=lazy,initial=IntConstant(5)*/
 const field4c = 2 + 3;
 
-/*element: field5a:complexity=constant,initial=FunctionConstant(method)*/
+/*member: field5a:complexity=constant,initial=FunctionConstant(method)*/
 final field5a = method;
 
-/*element: field5b:complexity=constant,initial=FunctionConstant(method)*/
+/*member: field5b:complexity=constant,initial=FunctionConstant(method)*/
 var field5b = method;
 
-/*strong.element: field5c:complexity=constant,initial=FunctionConstant(method)*/
+/*strong.member: field5c:complexity=constant,initial=FunctionConstant(method)*/
 const field5c = method;
 
-/*element: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
+/*member: field6a:complexity=constant,initial=ConstructedConstant(Class())*/
 var field6a = const Class.generative();
 
-/*element: field6b:complexity=constant,initial=ConstructedConstant(Class())*/
+/*member: field6b:complexity=constant,initial=ConstructedConstant(Class())*/
 var field6b = const Class.fact();
 
-/*element: field6c:complexity=lazy*/
+/*member: field6c:complexity=lazy*/
 var field6c = method();
 
-/*element: field7a:complexity=eager*/
+/*member: field7a:complexity=eager*/
 var field7a = {};
 
-/*element: field7b:complexity=eager*/
+/*member: field7b:complexity=eager*/
 var field7b = {0: 1};
 
-/*element: field7c:complexity=eager*/
+/*member: field7c:complexity=eager*/
 var field7c = {0: method};
 
-/*element: field7d:complexity=lazy*/
+/*member: field7d:complexity=lazy*/
 var field7d = {0: method()};
 
-/*element: field7e:complexity=lazy*/
+/*member: field7e:complexity=lazy*/
 var field7e = {method(): 0};
 
-/*element: field8a:complexity=eager*/
+/*member: field8a:complexity=eager*/
 var field8a = {};
 
-/*element: field8b:complexity=eager*/
+/*member: field8b:complexity=eager*/
 var field8b = {0};
 
-/*element: field8c:complexity=eager*/
+/*member: field8c:complexity=eager*/
 var field8c = {method};
 
-/*element: field8d:complexity=lazy*/
+/*member: field8d:complexity=lazy*/
 var field8d = {method()};
 
-/*element: field9a:complexity=eager*/
+/*member: field9a:complexity=eager*/
 var field9a = [];
 
-/*element: field9b:complexity=eager&fields=[field9a]*/
+/*member: field9b:complexity=eager&fields=[field9a]*/
 var field9b = field9a;
 
-/*element: field9c:complexity=eager&fields=[field9b]*/
+/*member: field9c:complexity=eager&fields=[field9b]*/
 var field9c = [field9b];
 
-/*element: field10a:complexity=eager&fields=[field10b]*/
+/*member: field10a:complexity=eager&fields=[field10b]*/
 int field10a = field10b;
 
-/*element: field10b:complexity=eager&fields=[field10a]*/
+/*member: field10b:complexity=eager&fields=[field10a]*/
 int field10b = field10a;
diff --git a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
index 9fe7c7d..1f8c21a 100644
--- a/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/kfield_analysis_test.dart
@@ -6,7 +6,6 @@
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/field_analysis.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/util/features.dart';
@@ -62,8 +61,9 @@
         features[Tags.complexity] = staticFieldData.complexity.shortText;
       }
       Id id = computeEntityId(node);
-      actualMap[id] = new ActualData<Features>(
-          id, features, computeSourceSpanFromTreeNode(node), member);
+      ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+      actualMap[id] = new ActualData<Features>(id, features,
+          nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
     }
   }
 
diff --git a/tests/compiler/dart2js/impact/data/as.dart b/tests/compiler/dart2js/impact/data/as.dart
index b7b196a..fd2fe10 100644
--- a/tests/compiler/dart2js/impact/data/as.dart
+++ b/tests/compiler/dart2js/impact/data/as.dart
@@ -2,21 +2,21 @@
 // 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.
 
-/*element: main:static=[explicitAs(1),implicitAs(1),promoted(1)],type=[inst:JSNull]*/
+/*member: main:static=[explicitAs(1),implicitAs(1),promoted(1)],type=[inst:JSNull]*/
 main() {
   explicitAs(null);
   implicitAs(null);
   promoted(null);
 }
 
-/*element: explicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
+/*member: explicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
 explicitAs(String i) {
   i.length;
   // ignore: unnecessary_cast
   return i as String;
 }
 
-/*element: implicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
+/*member: implicitAs:dynamic=[String.length],type=[inst:JSBool,param:String]*/
 String implicitAs(String i) {
   dynamic j = i;
   i.length;
@@ -24,7 +24,7 @@
   return j;
 }
 
-/*element: promoted:dynamic=[String.length],type=[inst:JSBool,inst:JSNull,is:String]*/
+/*member: promoted:dynamic=[String.length],type=[inst:JSBool,inst:JSNull,is:String]*/
 String promoted(dynamic i) {
   if (i is! String) return null;
   i.length;
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index bde8eb7..0684ce7 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testAnonymousAsync(0),
   testAnonymousAsyncStar(0),
@@ -31,7 +31,7 @@
   testAsyncForInTyped(null);
 }
 
-/*element: testSyncStar:
+/*member: testSyncStar:
  static=[
   _IterationMarker.endOfIteration(0),
   _IterationMarker.uncaughtError(1),
@@ -40,7 +40,7 @@
 */
 testSyncStar() sync* {}
 
-/*element: testAsync:
+/*member: testAsync:
  static=[
   StreamIterator.(1),
   _asyncAwait(2),
@@ -52,7 +52,7 @@
 */
 testAsync() async {}
 
-/*element: testAsyncStar:
+/*member: testAsyncStar:
  static=[
   StreamIterator.(1),
   _IterationMarker.yieldSingle(1),
@@ -64,7 +64,7 @@
 */
 testAsyncStar() async* {}
 
-/*element: testLocalSyncStar:
+/*member: testLocalSyncStar:
  static=[
   _IterationMarker.endOfIteration(0),
   _IterationMarker.uncaughtError(1),
@@ -88,7 +88,7 @@
   return local;
 }
 
-/*element: testLocalAsync:
+/*member: testLocalAsync:
  static=[
   StreamIterator.(1),
   _asyncAwait(2),
@@ -115,7 +115,7 @@
   return local;
 }
 
-/*element: testLocalAsyncStar:
+/*member: testLocalAsyncStar:
  static=[
   StreamIterator.(1),
   _IterationMarker.yieldSingle(1),
@@ -142,7 +142,7 @@
   return local;
 }
 
-/*element: testAnonymousSyncStar:
+/*member: testAnonymousSyncStar:
  static=[
   _IterationMarker.endOfIteration(0),
   _IterationMarker.uncaughtError(1),
@@ -165,7 +165,7 @@
   return () sync* {};
 }
 
-/*element: testAnonymousAsync:
+/*member: testAnonymousAsync:
  static=[
   StreamIterator.(1),
   _asyncAwait(2),
@@ -191,7 +191,7 @@
   return () async {};
 }
 
-/*element: testAnonymousAsyncStar:
+/*member: testAnonymousAsyncStar:
  static=[
   StreamIterator.(1),
   _IterationMarker.yieldSingle(1),
@@ -217,7 +217,7 @@
   return () async* {};
 }
 
-/*element: testAsyncForIn:
+/*member: testAsyncForIn:
  dynamic=[
   _StreamIterator.cancel(0),
   _StreamIterator.current,
@@ -241,7 +241,7 @@
   await for (var e in o) {}
 }
 
-/*element: testAsyncForInTyped:
+/*member: testAsyncForInTyped:
  dynamic=[
   _StreamIterator.cancel(0),
   _StreamIterator.current,
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index 5a067d6..d35718d 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testAbstractClassWithField(0),
   testEnum(0),
@@ -40,104 +40,104 @@
   testGenericNamedMixinInstantiation();
 }
 
-/*element: Super1.:static=[Object.(0)]*/
+/*member: Super1.:static=[Object.(0)]*/
 class Super1 {
-  /*element: Super1.foo:*/
+  /*member: Super1.foo:*/
   foo() {}
 }
 
 class Sub1 extends Super1 {
-  /*element: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
+  /*member: Sub1.:static=[Super1.(0),Super1.foo(0)]*/
   Sub1() {
     super.foo();
   }
 }
 
-/*element: testSuperCall:static=[Sub1.(0)]*/
+/*member: testSuperCall:static=[Sub1.(0)]*/
 testSuperCall() => new Sub1();
 
-/*element: Super2.:static=[Object.(0)]*/
+/*member: Super2.:static=[Object.(0)]*/
 class Super2 {
-  /*element: Super2.foo:type=[inst:JSNull]*/
+  /*member: Super2.foo:type=[inst:JSNull]*/
   var foo;
 }
 
 class Sub2 extends Super2 {
-  /*element: Sub2.:static=[Super2.(0),Super2.foo]*/
+  /*member: Sub2.:static=[Super2.(0),Super2.foo]*/
   Sub2() {
     super.foo;
   }
 }
 
-/*element: testSuperGet:static=[Sub2.(0)]*/
+/*member: testSuperGet:static=[Sub2.(0)]*/
 testSuperGet() => new Sub2();
 
-/*element: Super3.:static=[Object.(0)]*/
+/*member: Super3.:static=[Object.(0)]*/
 class Super3 {
-  /*element: Super3.foo:type=[inst:JSNull]*/
+  /*member: Super3.foo:type=[inst:JSNull]*/
   var foo;
 }
 
 class Sub3 extends Super3 {
-  /*element: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
+  /*member: Sub3.:static=[Super3.(0),set:Super3.foo],type=[inst:JSBool]*/
   Sub3() {
     super.foo = true;
   }
 }
 
-/*element: testSuperFieldSet:static=[Sub3.(0)]*/
+/*member: testSuperFieldSet:static=[Sub3.(0)]*/
 testSuperFieldSet() => new Sub3();
 
-/*element: Super4.:static=[Object.(0)]*/
+/*member: Super4.:static=[Object.(0)]*/
 class Super4 {
-  /*element: Super4.foo=:*/
+  /*member: Super4.foo=:*/
   set foo(_) {}
 }
 
 class Sub4 extends Super4 {
-  /*element: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
+  /*member: Sub4.:static=[Super4.(0),set:Super4.foo],type=[inst:JSBool]*/
   Sub4() {
     super.foo = true;
   }
 }
 
-/*element: testSuperSetterSet:static=[Sub4.(0)]*/
+/*member: testSuperSetterSet:static=[Sub4.(0)]*/
 testSuperSetterSet() => new Sub4();
 
-/*element: Super5.:static=[Object.(0)]*/
+/*member: Super5.:static=[Object.(0)]*/
 class Super5 {
-  /*element: Super5.foo:*/
+  /*member: Super5.foo:*/
   foo() {}
 }
 
-/*element: Sub5.:static=[Super5.(0),Super5.foo]*/
+/*member: Sub5.:static=[Super5.(0),Super5.foo]*/
 class Sub5 extends Super5 {
   Sub5() {
     super.foo;
   }
 }
 
-/*element: testSuperClosurization:static=[Sub5.(0)]*/
+/*member: testSuperClosurization:static=[Sub5.(0)]*/
 testSuperClosurization() => new Sub5();
 
 class EmptyMixin {}
 
 class ForwardingConstructorSuperClass {
-  /*element: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
+  /*member: ForwardingConstructorSuperClass.:static=[Object.(0)]*/
   ForwardingConstructorSuperClass(arg);
 }
 
 class ForwardingConstructorClass = ForwardingConstructorSuperClass
     with EmptyMixin;
 
-/*element: testForwardingConstructor:
+/*member: testForwardingConstructor:
  static=[ForwardingConstructorClass.(1)],
  type=[inst:JSNull]
 */
 testForwardingConstructor() => new ForwardingConstructorClass(null);
 
 class ForwardingConstructorTypedSuperClass {
-  /*element: ForwardingConstructorTypedSuperClass.:
+  /*member: ForwardingConstructorTypedSuperClass.:
    static=[Object.(0)],
    type=[inst:JSBool,param:int]
   */
@@ -147,14 +147,14 @@
 class ForwardingConstructorTypedClass = ForwardingConstructorTypedSuperClass
     with EmptyMixin;
 
-/*element: testForwardingConstructorTyped:
+/*member: testForwardingConstructorTyped:
  static=[ForwardingConstructorTypedClass.(1)],
  type=[inst:JSNull]
 */
 testForwardingConstructorTyped() => new ForwardingConstructorTypedClass(null);
 
 class ForwardingConstructorGenericSuperClass<T> {
-  /*element: ForwardingConstructorGenericSuperClass.:
+  /*member: ForwardingConstructorGenericSuperClass.:
    static=[
     Object.(0),
     checkSubtype(4),
@@ -179,7 +179,7 @@
 class ForwardingConstructorGenericClass<
     S> = ForwardingConstructorGenericSuperClass<S> with EmptyMixin;
 
-/*element: testForwardingConstructorGeneric:
+/*member: testForwardingConstructorGeneric:
  static=[
   ForwardingConstructorGenericClass.(1),
   assertIsSubtype(5),
@@ -191,7 +191,7 @@
 }
 
 enum Enum {
-  /*strong.element: Enum.A:static=[Enum.(2)],
+  /*strong.member: Enum.A:static=[Enum.(2)],
    type=[
     inst:JSBool,
     inst:JSDouble,
@@ -206,8 +206,8 @@
   A
 }
 
-/*strong.element: testEnum:static=[Enum.A]*/
-/*strongConst.element: testEnum:
+/*strong.member: testEnum:static=[Enum.A]*/
+/*strongConst.member: testEnum:
  static=[
   Enum._name=StringConstant("Enum.A"),
   Enum.index=IntConstant(0)],
@@ -223,7 +223,7 @@
 */
 testEnum() => Enum.A;
 
-/*element: staticGenericMethod:
+/*member: staticGenericMethod:
  static=[
   checkSubtype(4),
   checkSubtypeOfRuntimeType(2),
@@ -245,7 +245,7 @@
 */
 List<T> staticGenericMethod<T>(T arg) => [arg];
 
-/*element: testStaticGenericMethod:
+/*member: testStaticGenericMethod:
   static=[staticGenericMethod<bool>(1)],
   type=[inst:JSBool]
 */
@@ -253,7 +253,7 @@
   staticGenericMethod<bool>(true);
 }
 
-/*element: testInstanceGenericMethod:
+/*member: testInstanceGenericMethod:
  dynamic=[exact:GenericClass.genericMethod<bool>(1)],
  static=[
   GenericClass.generative(0),
@@ -269,20 +269,20 @@
   // ignore: UNUSED_FIELD
   final _field;
 
-  /*element: AbstractClass.:type=[inst:JSNull]*/
+  /*member: AbstractClass.:type=[inst:JSNull]*/
   factory AbstractClass() => null;
 }
 
-/*element: testAbstractClassWithField:static=[AbstractClass.(0)]*/
+/*member: testAbstractClassWithField:static=[AbstractClass.(0)]*/
 testAbstractClassWithField() => new AbstractClass();
 
-/*element: testMixinInstantiation:static=[Sub.(0)]*/
+/*member: testMixinInstantiation:static=[Sub.(0)]*/
 testMixinInstantiation() => new Sub();
 
-/*element: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
+/*member: testNamedMixinInstantiation:static=[NamedMixin.(0)]*/
 testNamedMixinInstantiation() => new NamedMixin();
 
-/*element: testGenericMixinInstantiation:
+/*member: testGenericMixinInstantiation:
  static=[
   GenericSub.(0),
   assertIsSubtype(5),
@@ -290,7 +290,7 @@
 */
 testGenericMixinInstantiation() => new GenericSub<int, String>();
 
-/*element: testGenericNamedMixinInstantiation:
+/*member: testGenericNamedMixinInstantiation:
  static=[
   GenericNamedMixin.(0),
   assertIsSubtype(5),
@@ -299,14 +299,14 @@
 testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
 
 class Class {
-  /*element: GenericClass.generative:static=[Object.(0)]*/
+  /*member: GenericClass.generative:static=[Object.(0)]*/
   const Class.generative();
 }
 
 class GenericClass<X, Y> {
   const GenericClass.generative();
 
-  /*element: GenericClass.genericMethod:
+  /*member: GenericClass.genericMethod:
    static=[
     checkSubtype(4),
     checkSubtypeOfRuntimeType(2),
@@ -330,26 +330,26 @@
   Map<X, T> genericMethod<T>(T arg) => {null: arg};
 }
 
-/*element: Super.:static=[Object.(0)]*/
+/*member: Super.:static=[Object.(0)]*/
 class Super {}
 
 class Mixin1 {}
 
 class Mixin2 {}
 
-/*element: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
+/*member: Sub.:static=[_Sub&Super&Mixin1&Mixin2.(0)]*/
 class Sub extends Super with Mixin1, Mixin2 {}
 
 class NamedMixin = Super with Mixin1, Mixin2;
 
-/*element: GenericSuper.:static=[Object.(0)]*/
+/*member: GenericSuper.:static=[Object.(0)]*/
 class GenericSuper<X1, Y1> {}
 
 class GenericMixin1<X2, Y2> {}
 
 class GenericMixin2<X3, Y3> {}
 
-/*element: GenericSub.:
+/*member: GenericSub.:
   static=[_GenericSub&GenericSuper&GenericMixin1&GenericMixin2.(0)]
 */
 class GenericSub<X4, Y4> extends GenericSuper<X4, Y4>
diff --git a/tests/compiler/dart2js/impact/data/constants.dart b/tests/compiler/dart2js/impact/data/constants.dart
index 12db520..9ad48e4 100644
--- a/tests/compiler/dart2js/impact/data/constants.dart
+++ b/tests/compiler/dart2js/impact/data/constants.dart
@@ -5,7 +5,7 @@
 import '../libs/constants_lib.dart';
 import '../libs/constants_lib.dart' deferred as defer;
 
-/*element: main:static=**/
+/*member: main:static=**/
 main() {
   nullLiteral();
   boolLiteral();
@@ -56,209 +56,209 @@
   staticTearOffDeferred();
 }
 
-/*element: nullLiteral:type=[inst:JSNull]*/
+/*member: nullLiteral:type=[inst:JSNull]*/
 nullLiteral() {
   const dynamic local = null;
   return local;
 }
 
-/*element: boolLiteral:type=[inst:JSBool]*/
+/*member: boolLiteral:type=[inst:JSBool]*/
 boolLiteral() {
   const dynamic local = true;
   return local;
 }
 
-/*element: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: intLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 intLiteral() {
   const dynamic local = 42;
   return local;
 }
 
-/*element: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: doubleLiteral:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 doubleLiteral() {
   const dynamic local = 0.5;
   return local;
 }
 
-/*element: stringLiteral:type=[inst:JSString]*/
+/*member: stringLiteral:type=[inst:JSString]*/
 stringLiteral() {
   const dynamic local = "foo";
   return local;
 }
 
-/*element: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*member: symbolLiteral:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteral() => #foo;
 
-/*element: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*member: listLiteral:type=[inst:JSBool,inst:List<bool>]*/
 listLiteral() => const [true, false];
 
-/*element: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*member: mapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
 mapLiteral() => const {true: false};
 
-/*element: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*member: stringMapLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
 stringMapLiteral() => const {'foo': false};
 
-/*element: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*member: setLiteral:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
 setLiteral() => const {true, false};
 
-/*strong.element: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
-/*strongConst.element: instanceConstant:
+/*strong.member: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
+/*strongConst.member: instanceConstant:
  static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
  type=[const:Class,inst:JSBool]
 */
 instanceConstant() => const Class(true, false);
 
-/*element: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+/*member: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
 typeLiteral() {
   const dynamic local = String;
   return local;
 }
 
-/*element: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*member: instantiation:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
 instantiation() {
   const int Function(int) local = id;
   return local;
 }
 
-/*element: topLevelTearOff:static=[topLevelMethod]*/
+/*member: topLevelTearOff:static=[topLevelMethod]*/
 topLevelTearOff() {
   const dynamic local = topLevelMethod;
   return local;
 }
 
-/*element: staticTearOff:static=[Class.staticMethodField]*/
+/*member: staticTearOff:static=[Class.staticMethodField]*/
 staticTearOff() {
   const dynamic local = Class.staticMethodField;
   return local;
 }
 
-/*strong.element: nullLiteralRef:static=[nullLiteralField]*/
-/*strongConst.element: nullLiteralRef:type=[inst:JSNull]*/
+/*strong.member: nullLiteralRef:static=[nullLiteralField]*/
+/*strongConst.member: nullLiteralRef:type=[inst:JSNull]*/
 nullLiteralRef() => nullLiteralField;
 
-/*strong.element: boolLiteralRef:static=[boolLiteralField]*/
-/*strongConst.element: boolLiteralRef:type=[inst:JSBool]*/
+/*strong.member: boolLiteralRef:static=[boolLiteralField]*/
+/*strongConst.member: boolLiteralRef:type=[inst:JSBool]*/
 boolLiteralRef() => boolLiteralField;
 
-/*strong.element: intLiteralRef:static=[intLiteralField]*/
-/*strongConst.element: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralRef:static=[intLiteralField]*/
+/*strongConst.member: intLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 intLiteralRef() => intLiteralField;
 
-/*strong.element: doubleLiteralRef:static=[doubleLiteralField]*/
-/*strongConst.element: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralRef:static=[doubleLiteralField]*/
+/*strongConst.member: doubleLiteralRef:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 doubleLiteralRef() => doubleLiteralField;
 
-/*strong.element: stringLiteralRef:static=[stringLiteralField]*/
-/*strongConst.element: stringLiteralRef:type=[inst:JSString]*/
+/*strong.member: stringLiteralRef:static=[stringLiteralField]*/
+/*strongConst.member: stringLiteralRef:type=[inst:JSString]*/
 stringLiteralRef() => stringLiteralField;
 
-/*strong.element: symbolLiteralRef:static=[symbolLiteralField]*/
-/*strongConst.element: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: symbolLiteralRef:static=[symbolLiteralField]*/
+/*strongConst.member: symbolLiteralRef:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteralRef() => symbolLiteralField;
 
-/*strong.element: listLiteralRef:static=[listLiteralField]*/
-/*strongConst.element: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
+/*strong.member: listLiteralRef:static=[listLiteralField]*/
+/*strongConst.member: listLiteralRef:type=[inst:JSBool,inst:List<bool>]*/
 listLiteralRef() => listLiteralField;
 
-/*strong.element: mapLiteralRef:static=[mapLiteralField]*/
-/*strongConst.element: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strong.member: mapLiteralRef:static=[mapLiteralField]*/
+/*strongConst.member: mapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
 mapLiteralRef() => mapLiteralField;
 
-/*strong.element: stringMapLiteralRef:static=[stringMapLiteralField]*/
-/*strongConst.element: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strong.member: stringMapLiteralRef:static=[stringMapLiteralField]*/
+/*strongConst.member: stringMapLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
 stringMapLiteralRef() => stringMapLiteralField;
 
-/*strong.element: setLiteralRef:static=[setLiteralField]*/
-/*strongConst.element: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strong.member: setLiteralRef:static=[setLiteralField]*/
+/*strongConst.member: setLiteralRef:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
 setLiteralRef() => setLiteralField;
 
-/*strong.element: instanceConstantRef:static=[instanceConstantField]*/
-/*strongConst.element: instanceConstantRef:
+/*strong.member: instanceConstantRef:static=[instanceConstantField]*/
+/*strongConst.member: instanceConstantRef:
  static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
  type=[const:Class,inst:JSBool]
 */
 instanceConstantRef() => instanceConstantField;
 
-/*strong.element: typeLiteralRef:static=[typeLiteralField]*/
-/*strongConst.element: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
+/*strong.member: typeLiteralRef:static=[typeLiteralField]*/
+/*strongConst.member: typeLiteralRef:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
 typeLiteralRef() => typeLiteralField;
 
-/*strong.element: instantiationRef:static=[instantiationField]*/
-/*strongConst.element: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*strong.member: instantiationRef:static=[instantiationField]*/
+/*strongConst.member: instantiationRef:static=[extractFunctionTypeObjectFromInternal(1),id,instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
 instantiationRef() => instantiationField;
 
-/*strong.element: topLevelTearOffRef:static=[topLevelTearOffField]*/
-/*strongConst.element: topLevelTearOffRef:static=[topLevelMethod]*/
+/*strong.member: topLevelTearOffRef:static=[topLevelTearOffField]*/
+/*strongConst.member: topLevelTearOffRef:static=[topLevelMethod]*/
 topLevelTearOffRef() => topLevelTearOffField;
 
-/*strong.element: staticTearOffRef:static=[staticTearOffField]*/
-/*strongConst.element: staticTearOffRef:static=[Class.staticMethodField]*/
+/*strong.member: staticTearOffRef:static=[staticTearOffField]*/
+/*strongConst.member: staticTearOffRef:static=[Class.staticMethodField]*/
 staticTearOffRef() => staticTearOffField;
 
-/*strong.element: nullLiteralDeferred:static=[nullLiteralField{defer}]*/
-/*strongConst.element: nullLiteralDeferred:type=[inst:JSNull]*/
+/*strong.member: nullLiteralDeferred:static=[nullLiteralField{defer}]*/
+/*strongConst.member: nullLiteralDeferred:type=[inst:JSNull]*/
 nullLiteralDeferred() => defer.nullLiteralField;
 
-/*strong.element: boolLiteralDeferred:static=[boolLiteralField{defer}]*/
-/*strongConst.element: boolLiteralDeferred:type=[inst:JSBool]*/
+/*strong.member: boolLiteralDeferred:static=[boolLiteralField{defer}]*/
+/*strongConst.member: boolLiteralDeferred:type=[inst:JSBool]*/
 boolLiteralDeferred() => defer.boolLiteralField;
 
-/*strong.element: intLiteralDeferred:static=[intLiteralField{defer}]*/
-/*strongConst.element: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralDeferred:static=[intLiteralField{defer}]*/
+/*strongConst.member: intLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 intLiteralDeferred() => defer.intLiteralField;
 
-/*strong.element: doubleLiteralDeferred:static=[doubleLiteralField{defer}]*/
-/*strongConst.element: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralDeferred:static=[doubleLiteralField{defer}]*/
+/*strongConst.member: doubleLiteralDeferred:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 doubleLiteralDeferred() => defer.doubleLiteralField;
 
-/*strong.element: stringLiteralDeferred:static=[stringLiteralField{defer}]*/
-/*strongConst.element: stringLiteralDeferred:type=[inst:JSString]*/
+/*strong.member: stringLiteralDeferred:static=[stringLiteralField{defer}]*/
+/*strongConst.member: stringLiteralDeferred:type=[inst:JSString]*/
 stringLiteralDeferred() => defer.stringLiteralField;
 
-/*strong.element: symbolLiteralDeferred:static=[symbolLiteralField{defer}]*/
+/*strong.member: symbolLiteralDeferred:static=[symbolLiteralField{defer}]*/
 // TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: symbolLiteralDeferred:static=[Symbol.(1)],type=[inst:Symbol]*/
 symbolLiteralDeferred() => defer.symbolLiteralField;
 
-/*strong.element: listLiteralDeferred:static=[listLiteralField{defer}]*/
+/*strong.member: listLiteralDeferred:static=[listLiteralField{defer}]*/
 // TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
+/*strongConst.member: listLiteralDeferred:type=[inst:JSBool,inst:List<bool>]*/
 listLiteralDeferred() => defer.listLiteralField;
 
-/*strong.element: mapLiteralDeferred:static=[mapLiteralField{defer}]*/
+/*strong.member: mapLiteralDeferred:static=[mapLiteralField{defer}]*/
 // TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strongConst.member: mapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
 mapLiteralDeferred() => defer.mapLiteralField;
 
-/*strong.element: stringMapLiteralDeferred:static=[stringMapLiteralField{defer}]*/
+/*strong.member: stringMapLiteralDeferred:static=[stringMapLiteralField{defer}]*/
 // TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strongConst.member: stringMapLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
 stringMapLiteralDeferred() => defer.stringMapLiteralField;
 
-/*strong.element: setLiteralDeferred:static=[setLiteralField{defer}]*/
+/*strong.member: setLiteralDeferred:static=[setLiteralField{defer}]*/
 // TODO(johnniwinther): Should we record that this is deferred?
-/*strongConst.element: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strongConst.member: setLiteralDeferred:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
 setLiteralDeferred() => defer.setLiteralField;
 
-/*strong.element: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
-/*strongConst.element: instanceConstantDeferred:
+/*strong.member: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
+/*strongConst.member: instanceConstantDeferred:
  static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
  type=[const:Class{defer},inst:JSBool]
 */
 instanceConstantDeferred() => defer.instanceConstantField;
 
-/*strong.element: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
-/*strongConst.element: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
+/*strong.member: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
+/*strongConst.member: typeLiteralDeferred:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String{defer}]*/
 typeLiteralDeferred() => defer.typeLiteralField;
 
-/*strong.element: instantiationDeferred:static=[instantiationField{defer}]*/
-/*strongConst.element: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
+/*strong.member: instantiationDeferred:static=[instantiationField{defer}]*/
+/*strongConst.member: instantiationDeferred:static=[extractFunctionTypeObjectFromInternal(1),id{defer},instantiate1(1),instantiatedGenericFunctionType(2)],type=[inst:Instantiation1<dynamic>]*/
 instantiationDeferred() => defer.instantiationField;
 
-/*strong.element: topLevelTearOffDeferred:static=[topLevelTearOffField{defer}]*/
-/*strongConst.element: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
+/*strong.member: topLevelTearOffDeferred:static=[topLevelTearOffField{defer}]*/
+/*strongConst.member: topLevelTearOffDeferred:static=[topLevelMethod{defer}]*/
 topLevelTearOffDeferred() => defer.topLevelTearOffField;
 
-/*strong.element: staticTearOffDeferred:static=[staticTearOffField{defer}]*/
-/*strongConst.element: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
+/*strong.member: staticTearOffDeferred:static=[staticTearOffField{defer}]*/
+/*strongConst.member: staticTearOffDeferred:static=[Class.staticMethodField{defer}]*/
 staticTearOffDeferred() => defer.staticTearOffField;
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index 6f98595..a58c2da 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testConstRedirectingFactoryInvoke(0),
   testConstRedirectingFactoryInvokeGeneric(0),
@@ -44,119 +44,119 @@
   testFactoryConstructor();
 }
 
-/*element: testConstructorInvoke:static=[Class.generative(0)]*/
+/*member: testConstructorInvoke:static=[Class.generative(0)]*/
 testConstructorInvoke() {
   new Class.generative();
 }
 
-/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
 testConstructorInvokeGeneric() {
   new GenericClass<int, String>.generative();
 }
 
-/*element: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*member: testConstructorInvokeGenericRaw:static=[GenericClass.generative(0)]*/
 testConstructorInvokeGenericRaw() {
   new GenericClass.generative();
 }
 
-/*element: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*member: testConstructorInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
 testConstructorInvokeGenericDynamic() {
   new GenericClass<dynamic, dynamic>.generative();
 }
 
-/*element: testFactoryInvoke:static=[Class.fact(0)]*/
+/*member: testFactoryInvoke:static=[Class.fact(0)]*/
 testFactoryInvoke() {
   new Class.fact();
 }
 
-/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype(5),throwTypeError(1)]*/
 testFactoryInvokeGeneric() {
   new GenericClass<int, String>.fact();
 }
 
-/*element: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
+/*member: testFactoryInvokeGenericRaw:static=[GenericClass.fact(0)]*/
 testFactoryInvokeGenericRaw() {
   new GenericClass.fact();
 }
 
-/*element: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
+/*member: testFactoryInvokeGenericDynamic:static=[GenericClass.fact(0)]*/
 testFactoryInvokeGenericDynamic() {
   new GenericClass<dynamic, dynamic>.fact();
 }
 
-/*element: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*member: testRedirectingFactoryInvoke:static=[Class.generative(0)]*/
 testRedirectingFactoryInvoke() {
   new Class.redirect();
 }
 
-/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*member: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
 testRedirectingFactoryInvokeGeneric() {
   new GenericClass<int, String>.redirect();
 }
 
-/*element: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*member: testRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
 testRedirectingFactoryInvokeGenericRaw() {
   new GenericClass.redirect();
 }
 
-/*element: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*member: testRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
 testRedirectingFactoryInvokeGenericDynamic() {
   new GenericClass<dynamic, dynamic>.redirect();
 }
 
-/*strong.element: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvoke:type=[const:Class]*/
+/*strong.member: testConstRedirectingFactoryInvoke:static=[Class.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvoke:type=[const:Class]*/
 testConstRedirectingFactoryInvoke() {
   const Class.redirect();
 }
 
-/*strong.element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGeneric:type=[const:GenericClass<int,String>]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
 
-/*strong.element: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericRaw:static=[GenericClass.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGenericRaw:type=[const:GenericClass<dynamic,dynamic>]*/
 testConstRedirectingFactoryInvokeGenericRaw() {
   const GenericClass.redirect();
 }
 
-/*strong.element: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
-/*strongConst.element: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
+/*strong.member: testConstRedirectingFactoryInvokeGenericDynamic:static=[GenericClass.generative(0)]*/
+/*strongConst.member: testConstRedirectingFactoryInvokeGenericDynamic:type=[const:GenericClass<dynamic,dynamic>]*/
 testConstRedirectingFactoryInvokeGenericDynamic() {
   const GenericClass<dynamic, dynamic>.redirect();
 }
 
-/*element: ClassImplicitConstructor.:static=[Object.(0)]*/
+/*member: ClassImplicitConstructor.:static=[Object.(0)]*/
 class ClassImplicitConstructor {}
 
-/*element: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
+/*member: testImplicitConstructor:static=[ClassImplicitConstructor.(0)]*/
 testImplicitConstructor() => new ClassImplicitConstructor();
 
 class ClassFactoryConstructor {
-  /*element: ClassFactoryConstructor.:type=[inst:JSNull]*/
+  /*member: ClassFactoryConstructor.:type=[inst:JSNull]*/
   factory ClassFactoryConstructor() => null;
 }
 
-/*element: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
+/*member: testFactoryConstructor:static=[ClassFactoryConstructor.(0)]*/
 testFactoryConstructor() => new ClassFactoryConstructor();
 
 class Class {
-  /*element: Class.generative:static=[Object.(0)]*/
+  /*member: Class.generative:static=[Object.(0)]*/
   const Class.generative();
 
-  /*element: Class.fact:type=[inst:JSNull]*/
+  /*member: Class.fact:type=[inst:JSNull]*/
   factory Class.fact() => null;
 
   const factory Class.redirect() = Class.generative;
 }
 
 class GenericClass<X, Y> {
-  /*element: GenericClass.generative:static=[Object.(0)]*/
+  /*member: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 
-  /*element: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
+  /*member: GenericClass.fact:type=[inst:JSBool,inst:JSNull,param:Object]*/
   factory GenericClass.fact() => null;
 
   const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
diff --git a/tests/compiler/dart2js/impact/data/effectively_final.dart b/tests/compiler/dart2js/impact/data/effectively_final.dart
index 305ca2b..9982845 100644
--- a/tests/compiler/dart2js/impact/data/effectively_final.dart
+++ b/tests/compiler/dart2js/impact/data/effectively_final.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   effectivelyFinalList(0),
   effectivelyFinalPromoted(0),
@@ -16,7 +16,7 @@
   effectivelyFinalPromotedInvalid();
 }
 
-/*element: effectivelyFinalList:
+/*member: effectivelyFinalList:
  dynamic=[
   List.add(1),
   List.length,
@@ -39,7 +39,7 @@
   c.length = 1;
 }
 
-/*element: notEffectivelyFinalList:
+/*member: notEffectivelyFinalList:
  dynamic=[
   +,
   add(1),
@@ -64,10 +64,10 @@
   c = null;
 }
 
-/*element: _method1:type=[inst:JSNull]*/
+/*member: _method1:type=[inst:JSNull]*/
 num _method1() => null;
 
-/*element: effectivelyFinalPromoted:
+/*member: effectivelyFinalPromoted:
  dynamic=[int.+,num.+],
  static=[_method1(0)],
  type=[
@@ -88,10 +88,10 @@
   }
 }
 
-/*element: _method2:type=[inst:JSNull]*/
+/*member: _method2:type=[inst:JSNull]*/
 String _method2() => null;
 
-/*element: effectivelyFinalPromotedInvalid:
+/*member: effectivelyFinalPromotedInvalid:
  dynamic=[String.+,int.+],
  static=[_method2(0)],
  type=[
diff --git a/tests/compiler/dart2js/impact/data/exact.dart b/tests/compiler/dart2js/impact/data/exact.dart
index 11a6d2d..1c6a6aa 100644
--- a/tests/compiler/dart2js/impact/data/exact.dart
+++ b/tests/compiler/dart2js/impact/data/exact.dart
@@ -2,28 +2,28 @@
 // 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.
 
-/*element: A.:static=[Object.(0)]*/
+/*member: A.:static=[Object.(0)]*/
 class A {
   method1() {}
   method2() {}
   method3() {}
 }
 
-/*element: B.:static=[A.(0)]*/
+/*member: B.:static=[A.(0)]*/
 class B extends A {
   method1() {}
   method2() {}
   method3() {}
 }
 
-/*element: C.:static=[B.(0)]*/
+/*member: C.:static=[B.(0)]*/
 class C extends B {
   method1() {}
   method2() {}
   method3() {}
 }
 
-/*element: main:static=[callOnEffectivelyFinalB(0),callOnNewB(0),callOnNewC(0)]*/
+/*member: main:static=[callOnEffectivelyFinalB(0),callOnNewB(0),callOnNewC(0)]*/
 main() {
   callOnNewB();
   callOnNewC();
@@ -31,17 +31,17 @@
   callOnEffectivelyFinalB();
 }
 
-/*element: callOnNewB:dynamic=[exact:B.method1(0)],static=[B.(0)]*/
+/*member: callOnNewB:dynamic=[exact:B.method1(0)],static=[B.(0)]*/
 callOnNewB() {
   new B().method1();
 }
 
-/*element: callOnNewC:dynamic=[exact:C.method2(0)],static=[C.(0)]*/
+/*member: callOnNewC:dynamic=[exact:C.method2(0)],static=[C.(0)]*/
 callOnNewC() {
   new C().method2();
 }
 
-/*element: callOnEffectivelyFinalB:dynamic=[exact:B.method3(0)],static=[B.(0)]*/
+/*member: callOnEffectivelyFinalB:dynamic=[exact:B.method3(0)],static=[B.(0)]*/
 callOnEffectivelyFinalB() {
   A a = new B();
   a.method3();
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index ca8a80d..612c3ce 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:static=[
+/*member: main:static=[
   testAs(1),
   testAsGeneric(1),
   testAsGenericDynamic(1),
@@ -68,47 +68,47 @@
   testSetIfNull(null);
 }
 
-/*element: testNot:type=[inst:JSBool]*/
+/*member: testNot:type=[inst:JSBool]*/
 testNot() => !false;
 
-/*element: testUnaryMinus:
+/*member: testUnaryMinus:
  dynamic=[int.unary-],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testUnaryMinus() => -1;
 
-/*element: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
+/*member: testConditional:type=[inst:JSBool,inst:JSNull,inst:JSString]*/
 // ignore: DEAD_CODE
 testConditional() => true ? null : '';
 
-/*element: testPostInc:
+/*member: testPostInc:
  dynamic=[+],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testPostInc(o) => o++;
 
-/*element: testPostDec:
+/*member: testPostDec:
  dynamic=[-],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testPostDec(o) => o--;
 
-/*element: testPreInc:
+/*member: testPreInc:
  dynamic=[+],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testPreInc(o) => ++o;
 
-/*element: testPreDec:
+/*member: testPreDec:
  dynamic=[-],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testPreDec(o) => --o;
 
-/*element: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIs:type=[inst:JSBool,inst:JSNull,is:Class]*/
 testIs() => null is Class;
 
-/*element: testIsGeneric:
+/*member: testIsGeneric:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -128,20 +128,20 @@
  */
 testIsGeneric() => null is GenericClass<int, String>;
 
-/*element: testIsGenericRaw:
+/*member: testIsGenericRaw:
  type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
 */
 testIsGenericRaw() => null is GenericClass;
 
-/*element: testIsGenericDynamic:
+/*member: testIsGenericDynamic:
  type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
 */
 testIsGenericDynamic() => null is GenericClass<dynamic, dynamic>;
 
-/*element: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
+/*member: testIsNot:type=[inst:JSBool,inst:JSNull,is:Class]*/
 testIsNot() => null is! Class;
 
-/*element: testIsNotGeneric:
+/*member: testIsNotGeneric:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -161,17 +161,17 @@
 */
 testIsNotGeneric() => null is! GenericClass<int, String>;
 
-/*element: testIsNotGenericRaw:
+/*member: testIsNotGenericRaw:
  type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
 */
 testIsNotGenericRaw() => null is! GenericClass;
 
-/*element: testIsNotGenericDynamic:
+/*member: testIsNotGenericDynamic:
  type=[inst:JSBool,inst:JSNull,is:GenericClass<dynamic,dynamic>]
 */
 testIsNotGenericDynamic() => null is! GenericClass<dynamic, dynamic>;
 
-/*element: testIsTypedef:
+/*member: testIsTypedef:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -191,7 +191,7 @@
 */
 testIsTypedef() => null is Typedef;
 
-/*element: testIsTypedefGeneric:
+/*member: testIsTypedefGeneric:
  static=[
  checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -210,7 +210,7 @@
   is:int Function(String)]*/
 testIsTypedefGeneric() => null is GenericTypedef<int, String>;
 
-/*element: testIsTypedefGenericRaw:
+/*member: testIsTypedefGenericRaw:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -229,7 +229,7 @@
   is:dynamic Function(dynamic)]*/
 testIsTypedefGenericRaw() => null is GenericTypedef;
 
-/*element: testIsTypedefGenericDynamic:
+/*member: testIsTypedefGenericDynamic:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -248,7 +248,7 @@
   is:dynamic Function(dynamic)]*/
 testIsTypedefGenericDynamic() => null is GenericTypedef<dynamic, dynamic>;
 
-/*element: testIsTypedefDeep:
+/*member: testIsTypedefDeep:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -267,14 +267,14 @@
   is:List<int Function(dynamic Function(dynamic))>]*/
 testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
 
-/*element: testAs:
+/*member: testAs:
  static=[throwRuntimeError(1)],
  type=[as:Class,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAs(dynamic o) => o as Class;
 
-/*element: testAsGeneric:static=[checkSubtype(4),
+/*member: testAsGeneric:static=[checkSubtype(4),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
   getRuntimeTypeInfo(1),
@@ -292,38 +292,38 @@
 // ignore: UNNECESSARY_CAST
 testAsGeneric(dynamic o) => o as GenericClass<int, String>;
 
-/*element: testAsGenericRaw:
+/*member: testAsGenericRaw:
  static=[throwRuntimeError(1)],
  type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAsGenericRaw(dynamic o) => o as GenericClass;
 
-/*element: testAsGenericDynamic:
+/*member: testAsGenericDynamic:
  static=[throwRuntimeError(1)],
  type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
 
-/*element: testThrow:
+/*member: testThrow:
  static=[throwExpression(1),wrapException(1)],
  type=[inst:JSString]*/
 testThrow() => throw '';
 
-/*element: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
+/*member: testIfNotNull:dynamic=[Object.==,foo],type=[inst:JSNull]*/
 testIfNotNull(o) => o?.foo;
 
-/*element: testTypedIfNotNull:dynamic=[Class.==,Class.field],type=[inst:JSBool,inst:JSNull,param:Class]*/
+/*member: testTypedIfNotNull:dynamic=[Class.==,Class.field],type=[inst:JSBool,inst:JSNull,param:Class]*/
 testTypedIfNotNull(Class o) => o?.field;
 
-/*element: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
+/*member: testIfNotNullSet:dynamic=[Object.==,foo=],type=[inst:JSBool,inst:JSNull]*/
 testIfNotNullSet(o) => o?.foo = true;
 
-/*element: testIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
+/*member: testIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
 testIfNull(o) => o ?? true;
 
-/*element: testSetIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
+/*member: testSetIfNull:dynamic=[Object.==],type=[inst:JSBool,inst:JSNull]*/
 testSetIfNull(o) => o ??= true;
 
 class Class {
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index 0f7f42a..9971b61 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -9,10 +9,10 @@
 
 class B<S, U> {}
 
-/*element: C.:static=[Object.(0)]*/
+/*member: C.:static=[Object.(0)]*/
 class C implements A<int>, B<String, bool> {}
 
-/*element: testA:
+/*member: testA:
  dynamic=[call<A.T>(0)],
  static=[
   checkSubtype(4),
@@ -34,7 +34,7 @@
 */
 testA(c, f) => extractTypeArguments<A>(c, f);
 
-/*element: testB:
+/*member: testB:
  dynamic=[call<B.S,B.U>(0)],
  static=[
   checkSubtype(4),
@@ -57,7 +57,7 @@
 */
 testB(c, f) => extractTypeArguments<B>(c, f);
 
-/*element: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
+/*member: main:static=[C.(0),testA(2),testB(2)],type=[inst:JSNull]*/
 main() {
   var c = new C();
   testA(c, null);
diff --git a/tests/compiler/dart2js/impact/data/future_or.dart b/tests/compiler/dart2js/impact/data/future_or.dart
index 21f6b17..40cdeea 100644
--- a/tests/compiler/dart2js/impact/data/future_or.dart
+++ b/tests/compiler/dart2js/impact/data/future_or.dart
@@ -4,7 +4,7 @@
 
 import "dart:async";
 
-/*element: main:
+/*member: main:
  dynamic=[runtimeType],
  runtimeType=[unknown:FutureOr<int>],
  static=[Future.value(1),assertIsSubtype(5),print(1),throwTypeError(1)],
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 3f954f9..53b2ff0 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testDefaultValuesNamed(0),
   testDefaultValuesPositional(0),
@@ -28,54 +28,54 @@
   testGenericClass();
 }
 
-/*strong.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
-/*strongConst.element: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+/*strong.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
+/*strongConst.member: testDefaultValuesPositional:type=[inst:JSBool,param:bool]*/
 testDefaultValuesPositional([bool value = false]) {}
 
-/*strong.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
-/*strongConst.element: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+/*strong.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
+/*strongConst.member: testDefaultValuesNamed:type=[inst:JSBool,param:bool]*/
 testDefaultValuesNamed({bool value: false}) {}
 
 class ClassFieldInitializer1 {
-  /*element: ClassFieldInitializer1.field:type=[inst:JSNull]*/
+  /*member: ClassFieldInitializer1.field:type=[inst:JSNull]*/
   var field;
 
-  /*element: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
+  /*member: ClassFieldInitializer1.:static=[Object.(0),init:ClassFieldInitializer1.field]*/
   ClassFieldInitializer1(this.field);
 }
 
-/*element: testFieldInitializer1:
+/*member: testFieldInitializer1:
  static=[ClassFieldInitializer1.(1)],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testFieldInitializer1() => new ClassFieldInitializer1(42);
 
 class ClassFieldInitializer2 {
-  /*element: ClassFieldInitializer2.field:type=[inst:JSNull]*/
+  /*member: ClassFieldInitializer2.field:type=[inst:JSNull]*/
   var field;
 
-  /*element: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
+  /*member: ClassFieldInitializer2.:static=[Object.(0),init:ClassFieldInitializer2.field]*/
   ClassFieldInitializer2(value) : field = value;
 }
 
-/*element: testFieldInitializer2:
+/*member: testFieldInitializer2:
  static=[ClassFieldInitializer2.(1)],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 testFieldInitializer2() => new ClassFieldInitializer2(42);
 
 class ClassFieldInitializer3 {
-  /*element: ClassFieldInitializer3.field:type=[inst:JSNull]*/
+  /*member: ClassFieldInitializer3.field:type=[inst:JSNull]*/
   var field;
 
-  /*element: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
+  /*member: ClassFieldInitializer3.a:static=[Object.(0),init:ClassFieldInitializer3.field],type=[inst:JSNull]*/
   ClassFieldInitializer3.a();
 
-  /*element: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
+  /*member: ClassFieldInitializer3.b:static=[Object.(0),init:ClassFieldInitializer3.field]*/
   ClassFieldInitializer3.b(value) : field = value;
 }
 
-/*element: testFieldInitializer3:
+/*member: testFieldInitializer3:
  static=[ClassFieldInitializer3.a(0),ClassFieldInitializer3.b(1)],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
@@ -84,45 +84,45 @@
   new ClassFieldInitializer3.b(42);
 }
 
-/*element: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
+/*member: ClassInstanceFieldWithInitializer.:static=[Object.(0)]*/
 class ClassInstanceFieldWithInitializer {
-  /*element: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
+  /*member: ClassInstanceFieldWithInitializer.field:type=[inst:JSBool,param:bool]*/
   var field = false;
 }
 
-/*element: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
+/*member: testInstanceFieldWithInitializer:static=[ClassInstanceFieldWithInitializer.(0)]*/
 testInstanceFieldWithInitializer() => new ClassInstanceFieldWithInitializer();
 
-/*element: ClassInstanceFieldTyped.:static=[Object.(0)]*/
+/*member: ClassInstanceFieldTyped.:static=[Object.(0)]*/
 class ClassInstanceFieldTyped {
-  /*element: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
+  /*member: ClassInstanceFieldTyped.field:type=[inst:JSBool,inst:JSNull,param:int]*/
   int field;
 }
 
-/*element: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
+/*member: testInstanceFieldTyped:static=[ClassInstanceFieldTyped.(0)]*/
 testInstanceFieldTyped() => new ClassInstanceFieldTyped();
 
 class ClassThisInitializer {
-  /*element: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
+  /*member: ClassThisInitializer.:static=[ClassThisInitializer.internal(0)]*/
   ClassThisInitializer() : this.internal();
 
-  /*element: ClassThisInitializer.internal:static=[Object.(0)]*/
+  /*member: ClassThisInitializer.internal:static=[Object.(0)]*/
   ClassThisInitializer.internal();
 }
 
-/*element: testThisInitializer:static=[ClassThisInitializer.(0)]*/
+/*member: testThisInitializer:static=[ClassThisInitializer.(0)]*/
 testThisInitializer() => new ClassThisInitializer();
 
 class ClassSuperInitializer extends ClassThisInitializer {
-  /*element: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
+  /*member: ClassSuperInitializer.:static=[ClassThisInitializer.internal(0)]*/
   ClassSuperInitializer() : super.internal();
 }
 
-/*element: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
+/*member: testSuperInitializer:static=[ClassSuperInitializer.(0)]*/
 testSuperInitializer() => new ClassSuperInitializer();
 
 class ClassGeneric<T> {
-  /*element: ClassGeneric.:
+  /*member: ClassGeneric.:
    static=[
     Object.(0),
     checkSubtype(4),
@@ -144,5 +144,5 @@
   ClassGeneric(T arg);
 }
 
-/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype(5),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype(5),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 testGenericClass() => new ClassGeneric<int>(0);
diff --git a/tests/compiler/dart2js/impact/data/injected_cast.dart b/tests/compiler/dart2js/impact/data/injected_cast.dart
index 526414c..9fa188c 100644
--- a/tests/compiler/dart2js/impact/data/injected_cast.dart
+++ b/tests/compiler/dart2js/impact/data/injected_cast.dart
@@ -12,13 +12,13 @@
 
 class E {}
 
-/*element: Class1.:static=[Object.(0)]*/
+/*member: Class1.:static=[Object.(0)]*/
 class Class1 {
-  /*element: Class1.field1:type=[inst:JSBool,inst:JSNull,param:A]*/
+  /*member: Class1.field1:type=[inst:JSBool,inst:JSNull,param:A]*/
   A field1;
 }
 
-/*element: method1:
+/*member: method1:
  dynamic=[Class1.field1=],
  type=[
   impl:A,
@@ -30,16 +30,16 @@
   o.field1 = value;
 }
 
-/*element: Class2.:static=[Object.(0)]*/
+/*member: Class2.:static=[Object.(0)]*/
 class Class2<T> {
-  /*element: Class2.field2:
+  /*member: Class2.field2:
    static=*,
    type=[inst:*,param:Class2.T]
    */
   T field2;
 }
 
-/*element: method2:
+/*member: method2:
  dynamic=[Class2.field2=],
  static=*,
  type=[
@@ -52,13 +52,13 @@
   o.field2 = value;
 }
 
-/*element: Class3.:static=[Object.(0)]*/
+/*member: Class3.:static=[Object.(0)]*/
 class Class3 {
-  /*element: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
+  /*member: Class3.method3:type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]*/
   method3(A a, [B b, C c]) {}
 }
 
-/*element: method3:
+/*member: method3:
  dynamic=[Class3.method3(3)],
  type=[
   impl:A,
@@ -72,15 +72,15 @@
   o.method3(a, b, c);
 }
 
-/*element: Class4.:static=[Object.(0)]*/
+/*member: Class4.:static=[Object.(0)]*/
 class Class4 {
-  /*element: Class4.method4:
+  /*member: Class4.method4:
    type=[inst:JSBool,inst:JSNull,param:A,param:B,param:C]
   */
   method4(A a, {B b, C c}) {}
 }
 
-/*element: method4:
+/*member: method4:
  dynamic=[Class4.method4(1,b,c)],
  type=[
   impl:A,
@@ -94,9 +94,9 @@
   o.method4(a, c: c, b: b);
 }
 
-/*element: Class5.:static=[Object.(0)]*/
+/*member: Class5.:static=[Object.(0)]*/
 class Class5<T1, T2> {
-  /*element: Class5.method5:
+  /*member: Class5.method5:
    static=*,
    type=[
     inst:*,
@@ -110,7 +110,7 @@
   method5<S1, S2>(T1 a, [T2 b, C c, S1 d, S2 e]) {}
 }
 
-/*element: method5:
+/*member: method5:
  dynamic=[Class5.method5<D,E>(5)],
  static=*,
  type=[
@@ -127,9 +127,9 @@
   o.method5<D, E>(a, b, c, d, e);
 }
 
-/*element: Class6.:static=[Object.(0)]*/
+/*member: Class6.:static=[Object.(0)]*/
 class Class6<T1, T2> {
-  /*element: Class6.method6:
+  /*member: Class6.method6:
    static=*,
    type=[
     inst:*,
@@ -143,7 +143,7 @@
   method6<S1, S2>(T1 a, {T2 b, C c, S1 d, S2 e}) {}
 }
 
-/*element: method6:
+/*member: method6:
  dynamic=[Class6.method6<D,E>(1,b,c,d,e)],
  static=*,
  type=[
@@ -160,13 +160,13 @@
   o.method6<D, E>(a, d: d, b: b, e: e, c: c);
 }
 
-/*element: Class7.:static=[Object.(0)]*/
+/*member: Class7.:static=[Object.(0)]*/
 class Class7 {
-  /*element: Class7.f:type=[inst:JSNull]*/
+  /*member: Class7.f:type=[inst:JSNull]*/
   A Function(A) get f => null;
 }
 
-/*element: method7:
+/*member: method7:
  dynamic=[Class7.f(1),call(1)],
  type=[impl:A,inst:JSBool,is:Class7]
 */
@@ -175,19 +175,19 @@
   o.f(a);
 }
 
-/*element: F.:static=[Object.(0)]*/
+/*member: F.:static=[Object.(0)]*/
 class F<T> {
-  /*element: F.method:static=*,type=[inst:*,param:List<F.T>]*/
+  /*member: F.method:static=*,type=[inst:*,param:List<F.T>]*/
   T method(List<T> list) => null;
 
-  /*element: F.field:static=*,type=[inst:*,param:F.T]*/
+  /*member: F.field:static=*,type=[inst:*,param:F.T]*/
   T field;
 }
 
-/*element: G.:static=[F.(0)]*/
+/*member: G.:static=[F.(0)]*/
 class G extends F<int> {}
 
-/*element: method8:
+/*member: method8:
  dynamic=[G.method(1)],
  static=*,
  type=[impl:List<int>,inst:*,is:G,param:Iterable<int>]
@@ -197,7 +197,7 @@
   return g.method(iterable);
 }
 
-/*element: method9:
+/*member: method9:
  dynamic=[G.field=],
  type=[impl:int,inst:JSBool,inst:JSNull,is:G,param:num]
 */
@@ -206,7 +206,7 @@
   return g.field = value;
 }
 
-/*element: main:**/
+/*member: main:**/
 main() {
   method1(new Class1(), null);
   method2(new Class2<A>(), null);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index 8a2c534..ffbbce5 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testClosure(0),
   testClosureInvoke(0),
@@ -75,16 +75,16 @@
   testDynamicPrivateMethodInvoke();
 }
 
-/*element: topLevelFunction1:*/
+/*member: topLevelFunction1:*/
 topLevelFunction1(a) {}
 
-/*element: topLevelFunction2:type=[inst:JSNull]*/
+/*member: topLevelFunction2:type=[inst:JSNull]*/
 topLevelFunction2(a, [b, c]) {}
 
-/*element: topLevelFunction3:type=[inst:JSNull]*/
+/*member: topLevelFunction3:type=[inst:JSNull]*/
 topLevelFunction3(a, {b, c}) {}
 
-/*element: testTopLevelInvoke:
+/*member: testTopLevelInvoke:
  static=[
   topLevelFunction1(1),
   topLevelFunction2(1),
@@ -115,10 +115,10 @@
   topLevelFunction3(15, c: 16, b: 17);
 }
 
-/*element: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
+/*member: topLevelFunction1Typed:type=[inst:JSBool,param:int]*/
 void topLevelFunction1Typed(int a) {}
 
-/*element: topLevelFunction2Typed:
+/*member: topLevelFunction2Typed:
  type=[
   inst:JSBool,
   inst:JSNull,
@@ -128,7 +128,7 @@
 */
 int topLevelFunction2Typed(String a, [num b, double c]) => null;
 
-/*element: topLevelFunction3Typed:
+/*member: topLevelFunction3Typed:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -152,7 +152,7 @@
   return null;
 }
 
-/*element: testTopLevelInvokeTyped:
+/*member: testTopLevelInvokeTyped:
  static=[
   topLevelFunction1Typed(1),
   topLevelFunction2Typed(1),
@@ -188,7 +188,7 @@
   topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
 }
 
-/*element: topLevelFunctionTyped1:
+/*member: topLevelFunctionTyped1:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -207,7 +207,7 @@
 */
 topLevelFunctionTyped1(void a(num b)) {}
 
-/*element: topLevelFunctionTyped2:
+/*member: topLevelFunctionTyped2:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -226,7 +226,7 @@
 */
 topLevelFunctionTyped2(void a(num b, [String c])) {}
 
-/*element: topLevelFunctionTyped3:
+/*member: topLevelFunctionTyped3:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -245,7 +245,7 @@
 */
 topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
 
-/*element: topLevelFunctionTyped4:
+/*member: topLevelFunctionTyped4:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -264,7 +264,7 @@
 */
 topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
 
-/*element: testTopLevelFunctionTyped:
+/*member: testTopLevelFunctionTyped:
  static=[
   topLevelFunctionTyped1(1),
   topLevelFunctionTyped2(1),
@@ -279,77 +279,77 @@
   topLevelFunctionTyped4(null);
 }
 
-/*element: testTopLevelFunctionGet:static=[topLevelFunction1]*/
+/*member: testTopLevelFunctionGet:static=[topLevelFunction1]*/
 testTopLevelFunctionGet() => topLevelFunction1;
 
-/*element: topLevelGetter:type=[inst:JSNull]*/
+/*member: topLevelGetter:type=[inst:JSNull]*/
 get topLevelGetter => null;
 
-/*element: testTopLevelGetterGet:static=[topLevelGetter]*/
+/*member: testTopLevelGetterGet:static=[topLevelGetter]*/
 testTopLevelGetterGet() => topLevelGetter;
 
-/*element: topLevelGetterTyped:type=[inst:JSNull]*/
+/*member: topLevelGetterTyped:type=[inst:JSNull]*/
 int get topLevelGetterTyped => null;
 
-/*element: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
+/*member: testTopLevelGetterGetTyped:static=[topLevelGetterTyped]*/
 testTopLevelGetterGetTyped() => topLevelGetterTyped;
 
-/*element: topLevelSetter=:*/
+/*member: topLevelSetter=:*/
 set topLevelSetter(_) {}
 
-/*element: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
+/*member: testTopLevelSetterSet:static=[set:topLevelSetter],type=[inst:JSNull]*/
 testTopLevelSetterSet() => topLevelSetter = null;
 
-/*element: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
+/*member: topLevelSetterTyped=:type=[inst:JSBool,param:int]*/
 void set topLevelSetterTyped(int value) {}
 
-/*element: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
+/*member: testTopLevelSetterSetTyped:static=[set:topLevelSetterTyped],type=[inst:JSNull]*/
 testTopLevelSetterSetTyped() => topLevelSetterTyped = null;
 
-/*element: topLevelField:type=[inst:JSNull]*/
+/*member: topLevelField:type=[inst:JSNull]*/
 var topLevelField;
 
-/*element: testTopLevelField:static=[topLevelField]*/
+/*member: testTopLevelField:static=[topLevelField]*/
 testTopLevelField() => topLevelField;
 
-/*element: topLevelFieldLazy:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
+/*member: topLevelFieldLazy:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
 var topLevelFieldLazy = topLevelFunction1(null);
 
-/*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
+/*member: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
 testTopLevelFieldLazy() => topLevelFieldLazy;
 
-/*strong.element: topLevelFieldConst:type=[inst:JSNull]*/
+/*strong.member: topLevelFieldConst:type=[inst:JSNull]*/
 const topLevelFieldConst = null;
 
-/*strong.element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
-/*strongConst.element: testTopLevelFieldConst:type=[inst:JSNull]*/
+/*strong.member: testTopLevelFieldConst:static=[topLevelFieldConst]*/
+/*strongConst.member: testTopLevelFieldConst:type=[inst:JSNull]*/
 testTopLevelFieldConst() => topLevelFieldConst;
 
-/*element: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
+/*member: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
 final topLevelFieldFinal = topLevelFunction1(null);
 
-/*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
+/*member: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
 testTopLevelFieldFinal() => topLevelFieldFinal;
 
-/*element: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
+/*member: topLevelFieldTyped:type=[inst:JSBool,inst:JSNull,param:int]*/
 int topLevelFieldTyped;
 
-/*element: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
+/*member: testTopLevelFieldTyped:static=[topLevelFieldTyped]*/
 testTopLevelFieldTyped() => topLevelFieldTyped;
 
-/*element: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric1:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
 GenericClass topLevelFieldGeneric1;
 
-/*element: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
+/*member: testTopLevelFieldGeneric1:static=[topLevelFieldGeneric1]*/
 testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
 
-/*element: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
+/*member: topLevelFieldGeneric2:type=[inst:JSBool,inst:JSNull,param:GenericClass<dynamic,dynamic>]*/
 GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
 
-/*element: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
+/*member: testTopLevelFieldGeneric2:static=[topLevelFieldGeneric2]*/
 testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
 
-/*element: topLevelFieldGeneric3:
+/*member: topLevelFieldGeneric3:
  static=[
   checkSubtype(4),
   getRuntimeTypeArgument(3),
@@ -369,21 +369,21 @@
 */
 GenericClass<int, String> topLevelFieldGeneric3;
 
-/*element: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
+/*member: testTopLevelFieldGeneric3:static=[topLevelFieldGeneric3]*/
 testTopLevelFieldGeneric3() => topLevelFieldGeneric3;
 
-/*element: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
+/*member: testTopLevelFieldWrite:static=[set:topLevelField],type=[inst:JSNull]*/
 testTopLevelFieldWrite() => topLevelField = null;
 
 class StaticFunctionGetClass {
-  /*element: StaticFunctionGetClass.foo:*/
+  /*member: StaticFunctionGetClass.foo:*/
   static foo() {}
 }
 
-/*element: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
+/*member: testStaticFunctionGet:static=[StaticFunctionGetClass.foo]*/
 testStaticFunctionGet() => StaticFunctionGetClass.foo;
 
-/*element: testDynamicInvoke:
+/*member: testDynamicInvoke:
  dynamic=[
   call(1),
   call(1,b),
@@ -421,10 +421,10 @@
   o.f9(15, c: 16, b: 17);
 }
 
-/*element: testDynamicGet:dynamic=[foo]*/
+/*member: testDynamicGet:dynamic=[foo]*/
 testDynamicGet(o) => o.foo;
 
-/*element: testDynamicSet:
+/*member: testDynamicSet:
  dynamic=[foo=],
  type=[
   inst:JSDouble,
@@ -437,13 +437,13 @@
 testDynamicSet(o) => o.foo = 42;
 
 // TODO(johnniwinther): Remove 'inst:Null'.
-/*element: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
+/*member: testLocalWithoutInitializer:type=[inst:JSNull,inst:Null]*/
 testLocalWithoutInitializer() {
   // ignore: UNUSED_LOCAL_VARIABLE
   var l;
 }
 
-/*element: testLocalWithInitializer:
+/*member: testLocalWithInitializer:
  type=[
   inst:JSDouble,
   inst:JSInt,
@@ -457,7 +457,7 @@
   var l = 42;
 }
 
-/*element: testLocalWithInitializerTyped:
+/*member: testLocalWithInitializerTyped:
  type=[
   inst:JSDouble,
   inst:JSInt,
@@ -471,7 +471,7 @@
   int l = 42;
 }
 
-/*element: testLocalFunction:
+/*member: testLocalFunction:
  static=[
   computeSignature(3),
   def:localFunction,
@@ -491,7 +491,7 @@
   localFunction() {}
 }
 
-/*element: testLocalFunctionTyped:
+/*member: testLocalFunctionTyped:
  static=[
   computeSignature(3),
   def:localFunction,
@@ -512,7 +512,7 @@
   int localFunction(String a) => null;
 }
 
-/*element: testLocalFunctionInvoke:
+/*member: testLocalFunctionInvoke:
  dynamic=[call(0)],
  static=[computeSignature(3),
   def:localFunction,
@@ -531,7 +531,7 @@
   localFunction();
 }
 
-/*element: testLocalFunctionGet:static=[computeSignature(3),
+/*member: testLocalFunctionGet:static=[computeSignature(3),
   def:localFunction,
   getRuntimeTypeArguments(3),
   getRuntimeTypeInfo(1),
@@ -547,7 +547,7 @@
   localFunction;
 }
 
-/*element: testClosure:static=[computeSignature(3),
+/*member: testClosure:static=[computeSignature(3),
   def:<anonymous>,
   getRuntimeTypeArguments(3),
   getRuntimeTypeInfo(1),
@@ -562,7 +562,7 @@
   () {};
 }
 
-/*element: testClosureInvoke:
+/*member: testClosureInvoke:
  dynamic=[call(0)],
  static=[computeSignature(3),
   def:<anonymous>,
@@ -580,7 +580,7 @@
   () {}();
 }
 
-/*element: testInvokeIndex:
+/*member: testInvokeIndex:
  dynamic=[[]],
  type=[inst:JSDouble,
   inst:JSInt,
@@ -591,7 +591,7 @@
 */
 testInvokeIndex(o) => o[42];
 
-/*element: testInvokeIndexSet:
+/*member: testInvokeIndexSet:
  dynamic=[[]=],
  type=[inst:JSDouble,
   inst:JSInt,
@@ -603,7 +603,7 @@
 */
 testInvokeIndexSet(o) => o[42] = null;
 
-/*element: testDynamicPrivateMethodInvoke:
+/*member: testDynamicPrivateMethodInvoke:
  dynamic=[_privateMethod(0),call(0)],
  type=[inst:JSNull]
 */
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index 4eccd23..2f40854 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -7,7 +7,7 @@
 
 import 'package:js/js.dart';
 
-/*element: main:
+/*member: main:
  static=[
   testJsInteropClass(0),
   testJsInteropMethod(0),
@@ -19,16 +19,16 @@
   testJsInteropClass();
 }
 
-/*element: testJsInteropMethod:*/
+/*member: testJsInteropMethod:*/
 @JS()
 external int testJsInteropMethod();
 
 @JS()
 class JsInteropClass {
-  /*element: JsInteropClass.:static=[JavaScriptObject.(0)]*/
+  /*member: JsInteropClass.:static=[JavaScriptObject.(0)]*/
   external JsInteropClass();
 
-  /*element: JsInteropClass.method:
+  /*member: JsInteropClass.method:
    type=[
     native:ApplicationCacheErrorEvent,
     native:DomError,
@@ -48,7 +48,7 @@
   external double method();
 }
 
-/*element: testJsInteropClass:
+/*member: testJsInteropClass:
  dynamic=[JavaScriptObject.method(0)],
  static=[JsInteropClass.(0)]
 */
@@ -56,10 +56,10 @@
 
 typedef void Callback<T>(T value);
 
-/*element: GenericClass.:static=[JavaScriptObject.(0)]*/
+/*member: GenericClass.:static=[JavaScriptObject.(0)]*/
 @JS()
 class GenericClass<T> {
-  /*element: GenericClass.method:
+  /*member: GenericClass.method:
    static=[
     checkSubtype(4),
     getRuntimeTypeArgument(3),
@@ -80,7 +80,7 @@
   external GenericClass method([Callback<T> callback]);
 }
 
-/*element: testOptionalGenericFunctionTypeArgument:
+/*member: testOptionalGenericFunctionTypeArgument:
  dynamic=[JavaScriptObject.method(0)],
  static=[GenericClass.(0)]
 */
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index c0e5f7d..afb6bdd 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:static=[
+/*member: main:static=[
  testBoolFromEnvironment(0),
  testComplexConstSymbol(0),
  testConstSymbol(0),
@@ -59,74 +59,74 @@
   testNonEmptyMapLiteral();
 }
 
-/*element: testEmpty:*/
+/*member: testEmpty:*/
 testEmpty() {}
 
-/*element: testNull:type=[inst:JSNull]*/
+/*member: testNull:type=[inst:JSNull]*/
 testNull() => null;
 
-/*element: testTrue:type=[inst:JSBool]*/
+/*member: testTrue:type=[inst:JSBool]*/
 testTrue() => true;
 
-/*element: testFalse:type=[inst:JSBool]*/
+/*member: testFalse:type=[inst:JSBool]*/
 testFalse() => false;
 
-/*element: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testInt:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 testInt() => 42;
 
-/*element: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*member: testDouble:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 testDouble() => 37.5;
 
-/*element: testString:type=[inst:JSString]*/
+/*member: testString:type=[inst:JSString]*/
 testString() => 'foo';
 
-/*element: testStringInterpolation:
+/*member: testStringInterpolation:
  dynamic=[toString(0)],
  static=[S(1)],type=[inst:JSBool,inst:JSString]
 */
 testStringInterpolation() => '${true}';
 
-/*strong.element: testStringInterpolationConst:
+/*strong.member: testStringInterpolationConst:
  dynamic=[toString(0)],
  static=[S(1)],type=[inst:JSBool,inst:JSString]
 */
-/*strongConst.element: testStringInterpolationConst:type=[inst:JSString]*/
+/*strongConst.member: testStringInterpolationConst:type=[inst:JSString]*/
 testStringInterpolationConst() {
   const b = '${true}';
   return b;
 }
 
-/*element: testStringJuxtaposition:
+/*member: testStringJuxtaposition:
  dynamic=[toString(0)],
  static=[S(1)],
  type=[inst:JSString]
 */
 testStringJuxtaposition() => 'a' 'b';
 
-/*element: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*member: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testSymbol() => #main;
 
-/*strong.element: testConstSymbol:
+/*strong.member: testConstSymbol:
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
  type=[inst:JSString,inst:Symbol]
 */
-/*strongConst.element: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testConstSymbol() => const Symbol('main');
 
-/*strong.element: complexSymbolField1:
+/*strong.member: complexSymbolField1:
  dynamic=[String.length,int.==],
  type=[inst:JSBool,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32,param:bool]
 */
 const complexSymbolField1 = "true".length == 4;
 
-/*strong.element: complexSymbolField2:
+/*strong.member: complexSymbolField2:
  dynamic=[toString(0)],
  static=[S(1)],
  type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]
 */
 const complexSymbolField2 = "true" "false" "${true}${null}";
 
-/*strong.element: complexSymbolField3:
+/*strong.member: complexSymbolField3:
   dynamic=[int.+,int.unary-],
   static=[
    GenericClass.generative(0),
@@ -178,7 +178,7 @@
   override: const GenericClass<int, String>.generative(),
 };
 
-/*strong.element: complexSymbolField:
+/*strong.member: complexSymbolField:
  static=[
   complexSymbolField1,
   complexSymbolField2,
@@ -188,56 +188,56 @@
 const complexSymbolField =
     complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
 
-/*strong.element: testComplexConstSymbol:
+/*strong.member: testComplexConstSymbol:
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1),complexSymbolField],
  type=[impl:String,inst:JSBool,inst:Symbol]
 */
-/*strongConst.element: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testComplexConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testComplexConstSymbol() => const Symbol(complexSymbolField);
 
-/*strong.element: testIfNullConstSymbol:
+/*strong.member: testIfNullConstSymbol:
  dynamic=[Null.==],
  static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
  type=[inst:JSNull,inst:JSString,inst:Symbol]
 */
-/*strongConst.element: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strongConst.member: testIfNullConstSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
-/*element: testTypeLiteral:
+/*member: testTypeLiteral:
  static=[createRuntimeType(1)],
  type=[inst:Type,inst:TypeImpl,lit:Object]
 */
 testTypeLiteral() => Object;
 
-/*strong.element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
-/*strongConst.element: testBoolFromEnvironment:type=[inst:JSBool]*/
+/*strong.member: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
+/*strongConst.member: testBoolFromEnvironment:type=[inst:JSBool]*/
 testBoolFromEnvironment() => const bool.fromEnvironment('FOO');
 
-/*element: testEmptyListLiteral:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteral:type=[inst:List<dynamic>]*/
 testEmptyListLiteral() => [];
 
-/*element: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteralDynamic:type=[inst:List<dynamic>]*/
 testEmptyListLiteralDynamic() => <dynamic>[];
 
-/*element: testEmptyListLiteralTyped:type=[inst:List<String>]*/
+/*member: testEmptyListLiteralTyped:type=[inst:List<String>]*/
 testEmptyListLiteralTyped() => <String>[];
 
-/*element: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
+/*member: testEmptyListLiteralConstant:type=[inst:List<dynamic>]*/
 testEmptyListLiteralConstant() => const [];
 
-/*element: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
+/*member: testNonEmptyListLiteral:type=[inst:JSBool,inst:List<bool>]*/
 testNonEmptyListLiteral() => [true];
 
-/*element: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
+/*member: testEmptyMapLiteral:type=[inst:Map<dynamic,dynamic>]*/
 testEmptyMapLiteral() => {};
 
-/*element: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
+/*member: testEmptyMapLiteralDynamic:type=[inst:Map<dynamic,dynamic>]*/
 testEmptyMapLiteralDynamic() => <dynamic, dynamic>{};
 
-/*element: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
+/*member: testEmptyMapLiteralTyped:type=[inst:Map<String,int>]*/
 testEmptyMapLiteralTyped() => <String, int>{};
 
-/*element: testEmptyMapLiteralConstant:
+/*member: testEmptyMapLiteralConstant:
 type=[
  inst:ConstantMap<dynamic,dynamic>,
  inst:ConstantProtoMap<dynamic,dynamic>,
@@ -246,10 +246,10 @@
 */
 testEmptyMapLiteralConstant() => const {};
 
-/*element: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
+/*member: testNonEmptyMapLiteral:type=[inst:JSBool,inst:JSNull,inst:Map<Null,bool>]*/
 testNonEmptyMapLiteral() => {null: true};
 
 class GenericClass<X, Y> {
-  /*strong.element: GenericClass.generative:static=[Object.(0)]*/
+  /*strong.member: GenericClass.generative:static=[Object.(0)]*/
   const GenericClass.generative();
 }
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index 2f9884d..678528c 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -8,7 +8,7 @@
 import 'dart:_js_helper';
 import 'dart:html_common';
 
-/*element: main:static=[testJSCall(0),
+/*member: main:static=[testJSCall(0),
   testNativeField(1),
   testNativeMethod(0),
   testNativeMethodCreates(0),
@@ -22,7 +22,7 @@
   testNativeMethodReturns();
 }
 
-/*element: testJSCall:
+/*member: testJSCall:
  static=[JS<dynamic>(3)],
  type=[inst:JSNull,inst:JSString,native:bool,native:int]
 */
@@ -31,13 +31,13 @@
     '#',
     null);
 
-/*element: testNativeMethod:*/
+/*member: testNativeMethod:*/
 @JSName('foo')
 @SupportedBrowser(SupportedBrowser.CHROME)
 // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
 testNativeMethod() native;
 
-/*element: testNativeMethodCreates:
+/*member: testNativeMethodCreates:
  type=[native:JSArray<JSArray.E>,native:Null,native:int]
 */
 @Creates('int|Null|JSArray')
@@ -49,14 +49,14 @@
 // dependency on the particular types. If `testNativeMethodReturns` was not
 // called `testNativeMethodCreates` would instead trigger the native
 // instantiations, so the blame is a bit arbitrary.
-/*element: testNativeMethodReturns:type=[*]*/
+/*member: testNativeMethodReturns:type=[*]*/
 @Returns('String|Null|JSArray')
 // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
 testNativeMethodReturns() native;
 
 @Native("NativeClass")
 class NativeClass {
-  /*element: NativeClass.field:
+  /*member: NativeClass.field:
    type=[
     inst:JSBool,
     inst:JSNull,
@@ -76,7 +76,7 @@
   }
 }
 
-/*element: testNativeField:
+/*member: testNativeField:
  dynamic=[NativeClass.field],
  static=[defineProperty(3)],
  type=[inst:JSBool,param:NativeClass]
diff --git a/tests/compiler/dart2js/impact/data/promotion.dart b/tests/compiler/dart2js/impact/data/promotion.dart
index a36673d..6b36fb0 100644
--- a/tests/compiler/dart2js/impact/data/promotion.dart
+++ b/tests/compiler/dart2js/impact/data/promotion.dart
@@ -8,7 +8,7 @@
   method() {}
 }
 
-/*element: main:
+/*member: main:
  static=[
   dynamicToEquals(1),
   dynamicToHashCode(1),
@@ -37,58 +37,58 @@
   dynamicToNoSuchMethodTearOff(null);
 }
 
-/*element: positiveTyped:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass,param:Class]*/
+/*member: positiveTyped:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass,param:Class]*/
 positiveTyped(Class cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*element: positiveDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
+/*member: positiveDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
 positiveDynamic(dynamic cls) {
   if (cls is SubClass) cls.method();
 }
 
-/*element: negativeDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
+/*member: negativeDynamic:dynamic=[SubClass.method(0)],type=[inst:JSBool,is:SubClass]*/
 negativeDynamic(dynamic cls) {
   if (cls is! SubClass) return;
   cls.method();
 }
 
-/*element: dynamicToString:dynamic=[Object.toString(0)]*/
+/*member: dynamicToString:dynamic=[Object.toString(0)]*/
 dynamicToString(dynamic cls) {
   cls.toString();
 }
 
-/*element: dynamicToStringWrong:dynamic=[call(1),toString(1)],type=[inst:JSNull]*/
+/*member: dynamicToStringWrong:dynamic=[call(1),toString(1)],type=[inst:JSNull]*/
 dynamicToStringWrong(dynamic cls) {
   cls.toString(null);
 }
 
-/*element: dynamicToStringTearOff:dynamic=[Object.toString]*/
+/*member: dynamicToStringTearOff:dynamic=[Object.toString]*/
 dynamicToStringTearOff(dynamic cls) {
   cls.toString;
 }
 
-/*element: dynamicToEquals:dynamic=[Object.==],type=[inst:JSNull]*/
+/*member: dynamicToEquals:dynamic=[Object.==],type=[inst:JSNull]*/
 dynamicToEquals(dynamic cls) {
   cls == null;
 }
 
-/*element: dynamicToHashCode:dynamic=[Object.hashCode]*/
+/*member: dynamicToHashCode:dynamic=[Object.hashCode]*/
 dynamicToHashCode(dynamic cls) {
   cls.hashCode;
 }
 
-/*element: dynamicToNoSuchMethod:dynamic=[Object.noSuchMethod(1)],type=[inst:JSNull]*/
+/*member: dynamicToNoSuchMethod:dynamic=[Object.noSuchMethod(1)],type=[inst:JSNull]*/
 dynamicToNoSuchMethod(dynamic cls) {
   cls.noSuchMethod(null);
 }
 
-/*element: dynamicToNoSuchMethodWrong:dynamic=[call(0),noSuchMethod(0)]*/
+/*member: dynamicToNoSuchMethodWrong:dynamic=[call(0),noSuchMethod(0)]*/
 dynamicToNoSuchMethodWrong(dynamic cls) {
   cls.noSuchMethod();
 }
 
-/*element: dynamicToNoSuchMethodTearOff:dynamic=[Object.noSuchMethod]*/
+/*member: dynamicToNoSuchMethodTearOff:dynamic=[Object.noSuchMethod]*/
 dynamicToNoSuchMethodTearOff(dynamic cls) {
   cls.noSuchMethod;
 }
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index d5d911b..78bfeeb 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -2,9 +2,9 @@
 // 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.
 
-/*element: Class1a.:static=[Object.(0)]*/
+/*member: Class1a.:static=[Object.(0)]*/
 class Class1a<T> {
-  /*element: Class1a.==:
+  /*member: Class1a.==:
    dynamic=[this:Class1a.runtimeType,Object.runtimeType,Type.==],
    runtimeType=[equals:Class1a<Class1a.T>/Object]
   */
@@ -13,9 +13,9 @@
   }
 }
 
-/*element: Class1b.:static=[Class1a.(0)]*/
+/*member: Class1b.:static=[Class1a.(0)]*/
 class Class1b<T> extends Class1a<T> {
-  /*element: Class1b.==:
+  /*member: Class1b.==:
    dynamic=[this:Class1b.runtimeType,Object.runtimeType,Type.==],
    runtimeType=[equals:Object/Class1b<Class1b.T>]
   */
@@ -24,9 +24,9 @@
   }
 }
 
-/*element: Class1c.:static=[Object.(0)]*/
+/*member: Class1c.:static=[Object.(0)]*/
 class Class1c<T> implements Class1a<T> {
-  /*element: Class1c.==:
+  /*member: Class1c.==:
    dynamic=[this:Class1c.runtimeType,Object.==,Object.runtimeType,Type.==],
    runtimeType=[equals:Class1c<Class1c.T>/Object],
    type=[inst:JSNull]
@@ -36,9 +36,9 @@
   }
 }
 
-/*element: Class1d.:static=[Object.(0)]*/
+/*member: Class1d.:static=[Object.(0)]*/
 class Class1d<T> implements Class1a<T> {
-  /*element: Class1d.==:
+  /*member: Class1d.==:
    dynamic=[this:Class1d.runtimeType,Object.==,Object.runtimeType,Type.==],
    runtimeType=[equals:Object/Class1d<Class1d.T>],
    type=[inst:JSNull]
@@ -48,19 +48,19 @@
   }
 }
 
-/*element: Class2.:static=[Object.(0)]*/
+/*member: Class2.:static=[Object.(0)]*/
 class Class2<T> {}
 
-/*element: Class3.:static=[Object.(0)]*/
+/*member: Class3.:static=[Object.(0)]*/
 class Class3 {
-  /*element: Class3.field:type=[inst:JSNull]*/
+  /*member: Class3.field:type=[inst:JSNull]*/
   var field;
 }
 
-/*element: Class4.:static=[Object.(0)]*/
+/*member: Class4.:static=[Object.(0)]*/
 class Class4 {}
 
-/*element: toString1:
+/*member: toString1:
  dynamic=[Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -83,7 +83,7 @@
 */
 toString1(Class2<int> c) => '${c.runtimeType}';
 
-/*element: toString2:
+/*member: toString2:
  dynamic=[Class2.==,Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -107,7 +107,7 @@
 */
 toString2(Class2<int> c) => '${c?.runtimeType}';
 
-/*element: toString3:
+/*member: toString3:
  dynamic=[Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -128,7 +128,7 @@
 */
 toString3(Class2<int> c) => c.runtimeType.toString();
 
-/*element: toString4:
+/*member: toString4:
  dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -150,7 +150,7 @@
 */
 toString4(Class2<int> c) => c.runtimeType?.toString();
 
-/*element: toString5:
+/*member: toString5:
  dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -172,7 +172,7 @@
 */
 toString5(Class2<int> c) => c?.runtimeType?.toString();
 
-/*element: toString6:
+/*member: toString6:
  dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
@@ -194,7 +194,7 @@
 */
 toString6(Class2<int> c) => c?.runtimeType.toString();
 
-/*element: unknown:
+/*member: unknown:
  dynamic=[Class2.runtimeType],
  runtimeType=[unknown:Class2<int>],
  static=[
@@ -215,7 +215,7 @@
 */
 unknown(Class2<int> c) => c.runtimeType;
 
-/*element: equals1:
+/*member: equals1:
  dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],
  runtimeType=[equals:Class1a<int>/Class1d<int>],
  static=[
@@ -238,147 +238,147 @@
 */
 equals1(Class1a<int> a, Class1d<int> b) => a?.runtimeType == b?.runtimeType;
 
-/*element: almostEquals1:
+/*member: almostEquals1:
  dynamic=[Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals1(Class3 a) => a.runtimeType == null;
 
-/*element: almostEquals2:
+/*member: almostEquals2:
  dynamic=[Class3.==,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals2(Class3 a) => a?.runtimeType == null;
 
-/*element: almostEquals3:
+/*member: almostEquals3:
  dynamic=[Class3.runtimeType,Null.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals3(Class3 a) => null == a.runtimeType;
 
-/*element: almostEquals4:
+/*member: almostEquals4:
  dynamic=[Class3.==,Class3.runtimeType,Null.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals4(Class3 a) => null == a?.runtimeType;
 
-/*element: almostEquals5:
+/*member: almostEquals5:
  dynamic=[Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostEquals5(Class3 a) => a.runtimeType == a.field;
 
-/*element: almostEquals6:
+/*member: almostEquals6:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals6(Class3 a) => a?.runtimeType == a.field;
 
-/*element: almostEquals7:
+/*member: almostEquals7:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals7(Class3 a) => a.runtimeType == a?.field;
 
-/*element: almostEquals8:
+/*member: almostEquals8:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Type.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals8(Class3 a) => a?.runtimeType == a?.field;
 
-/*element: almostEquals9:
+/*member: almostEquals9:
  dynamic=[Class3.field,Class3.runtimeType,Object.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostEquals9(Class3 a) => a.field == a.runtimeType;
 
-/*element: almostEquals10:
+/*member: almostEquals10:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals10(Class3 a) => a?.field == a.runtimeType;
 
-/*element: almostEquals11:
+/*member: almostEquals11:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals11(Class3 a) => a.field == a?.runtimeType;
 
-/*element: almostEquals12:
+/*member: almostEquals12:
  dynamic=[Class3.==,Class3.field,Class3.runtimeType,Object.==],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostEquals12(Class3 a) => a?.field == a?.runtimeType;
 
-/*element: almostToString1:
+/*member: almostToString1:
  dynamic=[Class3.runtimeType,Type.toString],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,param:Class3]
 */
 almostToString1(Class3 a) => a.runtimeType.toString;
 
-/*element: almostToString2:
+/*member: almostToString2:
  dynamic=[Class3.==,Class3.runtimeType,Type.==,Type.toString],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString2(Class3 a) => a?.runtimeType?.toString;
 
-/*element: almostToString3:
+/*member: almostToString3:
  dynamic=[Class3.runtimeType,Type.noSuchMethod(1)],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString3(Class3 a) => a.runtimeType.noSuchMethod(null);
 
-/*element: almostToString4:
+/*member: almostToString4:
  dynamic=[Class3.==,Class3.runtimeType,Type.noSuchMethod(1)],
  runtimeType=[unknown:Class3],
  type=[inst:JSBool,inst:JSNull,param:Class3]
 */
 almostToString4(Class3 a) => a?.runtimeType.noSuchMethod(null);
 
-/*element: notEquals1:
+/*member: notEquals1:
  dynamic=[Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,param:Class3,param:Class4]
 */
 notEquals1(Class3 a, Class4 b) => a.runtimeType != b.runtimeType;
 
-/*element: notEquals2:
+/*member: notEquals2:
  dynamic=[Class3.==,Class3.runtimeType,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals2(Class3 a, Class4 b) => a?.runtimeType != b.runtimeType;
 
-/*element: notEquals3:
+/*member: notEquals3:
  dynamic=[Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals3(Class3 a, Class4 b) => a.runtimeType != b?.runtimeType;
 
-/*element: notEquals4:
+/*member: notEquals4:
  dynamic=[Class3.==,Class3.runtimeType,Class4.==,Class4.runtimeType,Type.==],
  runtimeType=[equals:Class3/Class4],
  type=[inst:JSBool,inst:JSNull,param:Class3,param:Class4]
 */
 notEquals4(Class3 a, Class4 b) => a?.runtimeType != b?.runtimeType;
 
-/*element: main:
+/*member: main:
  dynamic=[exact:Class1a.==],
  static=[
   Class1a.(0),
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index 7a89d28..77936d3 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:
+/*member: main:
  static=[
   testAssert(0),
   testAssertWithMessage(0),
@@ -31,7 +31,7 @@
   testAssertWithMessage();
 }
 
-/*element: testIfThen:
+/*member: testIfThen:
  type=[
   inst:JSBool,
   inst:JSDouble,
@@ -47,7 +47,7 @@
   return 1;
 }
 
-/*element: testIfThenElse:
+/*member: testIfThenElse:
  type=[
   inst:JSBool,
   inst:JSDouble,
@@ -65,7 +65,7 @@
     return 1;
 }
 
-/*element: testForIn:
+/*member: testForIn:
  dynamic=[
   Iterator.current,
   Iterator.iterator,
@@ -82,7 +82,7 @@
   for (var e in o) {}
 }
 
-/*element: testForInTyped:
+/*member: testForInTyped:
  dynamic=[
   Iterator.current,
   Iterator.iterator,
@@ -100,7 +100,7 @@
   for (int e in o) {}
 }
 
-/*element: testTryCatch:
+/*member: testTryCatch:
  static=[unwrapException(1)],
  type=[
   inst:PlainJavaScriptObject,
@@ -110,7 +110,7 @@
   try {} catch (e) {}
 }
 
-/*element: testTryCatchOn:
+/*member: testTryCatchOn:
  static=[unwrapException(1)],
  type=[
   catch:String,
@@ -123,7 +123,7 @@
   try {} on String catch (e) {}
 }
 
-/*element: testTryCatchStackTrace:
+/*member: testTryCatchStackTrace:
  static=[
   getTraceFromException(1),
   unwrapException(1)],
@@ -137,12 +137,12 @@
   try {} catch (e, s) {}
 }
 
-/*element: testTryFinally:*/
+/*member: testTryFinally:*/
 testTryFinally() {
   try {} finally {}
 }
 
-/*element: testSwitchWithoutFallthrough:
+/*member: testSwitchWithoutFallthrough:
  static=[
   throwExpression(1),
   wrapException(1)],
@@ -171,12 +171,12 @@
   }
 }
 
-/*element: testAssert:static=[assertHelper(1)],type=[inst:JSBool]*/
+/*member: testAssert:static=[assertHelper(1)],type=[inst:JSBool]*/
 testAssert() {
   assert(true);
 }
 
-/*element: testAssertWithMessage:static=[assertTest(1),assertThrow(1)],type=[inst:JSBool,inst:JSString]*/
+/*member: testAssertWithMessage:static=[assertTest(1),assertThrow(1)],type=[inst:JSBool,inst:JSString]*/
 testAssertWithMessage() {
   assert(true, 'ok');
 }
diff --git a/tests/compiler/dart2js/impact/data/this.dart b/tests/compiler/dart2js/impact/data/this.dart
index 73a03d1..f06504e 100644
--- a/tests/compiler/dart2js/impact/data/this.dart
+++ b/tests/compiler/dart2js/impact/data/this.dart
@@ -2,36 +2,36 @@
 // 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.
 
-/*element: Class.:static=[Object.(0)]*/
+/*member: Class.:static=[Object.(0)]*/
 class Class {
-  /*element: Class.field1:type=[inst:JSNull]*/
+  /*member: Class.field1:type=[inst:JSNull]*/
   var field1;
 
-  /*element: Class.field2:type=[inst:JSNull]*/
+  /*member: Class.field2:type=[inst:JSNull]*/
   var field2;
 
-  /*element: Class.method1:dynamic=[this:Class.method2(0)]*/
+  /*member: Class.method1:dynamic=[this:Class.method2(0)]*/
   method1() {
     method2();
   }
 
-  /*element: Class.method2:dynamic=[this:Class.field1=,this:Class.field2]*/
+  /*member: Class.method2:dynamic=[this:Class.field1=,this:Class.field2]*/
   method2() {
     field1 = field2;
   }
 }
 
-/*element: Subclass.:static=[Class.(0)]*/
+/*member: Subclass.:static=[Class.(0)]*/
 class Subclass extends Class {
-  /*element: Subclass.field1:type=[inst:JSNull]*/
+  /*member: Subclass.field1:type=[inst:JSNull]*/
   var field1;
-  /*element: Subclass.field2:type=[inst:JSNull]*/
+  /*member: Subclass.field2:type=[inst:JSNull]*/
   var field2;
 
-  /*element: Subclass.method1:*/
+  /*member: Subclass.method1:*/
   method1() {}
 
-  /*element: Subclass.method2:dynamic=[this:Subclass.method3(0)]*/
+  /*member: Subclass.method2:dynamic=[this:Subclass.method3(0)]*/
   method2() {
     method3();
   }
@@ -39,11 +39,11 @@
   method3() {}
 }
 
-/*element: Subtype.:static=[Object.(0)]*/
+/*member: Subtype.:static=[Object.(0)]*/
 class Subtype implements Class {
-  /*element: Subtype.field1:type=[inst:JSNull]*/
+  /*member: Subtype.field1:type=[inst:JSNull]*/
   var field1;
-  /*element: Subtype.field2:type=[inst:JSNull]*/
+  /*member: Subtype.field2:type=[inst:JSNull]*/
   var field2;
 
   method1() {}
@@ -57,7 +57,7 @@
   }
 }
 
-/*element: main:
+/*member: main:
  dynamic=[Class.method1(0)],
  static=[Class.(0),Subclass.(0),Subtype.(0)]
 */
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index ec60875..879ff50 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -7,7 +7,6 @@
 import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/universe/feature.dart';
 import 'package:compiler/src/universe/use.dart';
@@ -86,8 +85,9 @@
       }
     }
     Id id = computeEntityId(node);
-    actualMap[id] = new ActualData<Features>(
-        id, features, computeSourceSpanFromTreeNode(node), member);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    actualMap[id] = new ActualData<Features>(id, features,
+        nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
   }
 
   @override
diff --git a/tests/compiler/dart2js/impact/libs/constants_lib.dart b/tests/compiler/dart2js/impact/libs/constants_lib.dart
index 051cbea..02bbc81 100644
--- a/tests/compiler/dart2js/impact/libs/constants_lib.dart
+++ b/tests/compiler/dart2js/impact/libs/constants_lib.dart
@@ -2,64 +2,64 @@
 // 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.
 
-/*strong.element: nullLiteralField:type=[inst:JSNull]*/
+/*strong.member: nullLiteralField:type=[inst:JSNull]*/
 const dynamic nullLiteralField = null;
 
-/*strong.element: boolLiteralField:type=[inst:JSBool]*/
+/*strong.member: boolLiteralField:type=[inst:JSBool]*/
 const dynamic boolLiteralField = true;
 
-/*strong.element: intLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: intLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 const dynamic intLiteralField = 42;
 
-/*strong.element: doubleLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*strong.member: doubleLiteralField:type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 const dynamic doubleLiteralField = 0.5;
 
-/*strong.element: stringLiteralField:type=[inst:JSString]*/
+/*strong.member: stringLiteralField:type=[inst:JSString]*/
 const dynamic stringLiteralField = "foo";
 
-/*strong.element: symbolLiteralField:static=[Symbol.(1)],type=[inst:Symbol]*/
+/*strong.member: symbolLiteralField:static=[Symbol.(1)],type=[inst:Symbol]*/
 const dynamic symbolLiteralField = #foo;
 
-/*strong.element: listLiteralField:type=[inst:JSBool,inst:List<bool>]*/
+/*strong.member: listLiteralField:type=[inst:JSBool,inst:List<bool>]*/
 const dynamic listLiteralField = [true, false];
 
-/*strong.element: mapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
+/*strong.member: mapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool]*/
 const dynamic mapLiteralField = {true: false};
 
-/*strong.element: stringMapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
+/*strong.member: stringMapLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:JSString]*/
 const dynamic stringMapLiteralField = {'foo': false};
 
-/*strong.element: setLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
+/*strong.member: setLiteralField:type=[inst:ConstantMap<dynamic,dynamic>,inst:ConstantProtoMap<dynamic,dynamic>,inst:ConstantStringMap<dynamic,dynamic>,inst:GeneralConstantMap<dynamic,dynamic>,inst:JSBool,inst:_UnmodifiableSet<dynamic>]*/
 const dynamic setLiteralField = {true, false};
 
 class SuperClass {
-  /*element: SuperClass.field1:type=[inst:JSNull]*/
+  /*member: SuperClass.field1:type=[inst:JSNull]*/
   final field1;
 
-  /*strong.element: SuperClass.:static=[Object.(0),init:SuperClass.field1]*/
+  /*strong.member: SuperClass.:static=[Object.(0),init:SuperClass.field1]*/
   const SuperClass(this.field1);
 }
 
 class Class extends SuperClass {
-  /*element: Class.field2:type=[inst:JSNull]*/
+  /*member: Class.field2:type=[inst:JSNull]*/
   final field2;
 
-  /*strong.element: Class.:static=[SuperClass.(1),init:Class.field2]*/
+  /*strong.member: Class.:static=[SuperClass.(1),init:Class.field2]*/
   const Class(field1, this.field2) : super(field1);
 
   static staticMethodField() {}
 }
 
-/*strong.element: instanceConstantField:static=[Class.(2)],type=[inst:JSBool,param:Class]*/
+/*strong.member: instanceConstantField:static=[Class.(2)],type=[inst:JSBool,param:Class]*/
 const instanceConstantField = const Class(true, false);
 
-/*strong.element: typeLiteralField:static=[createRuntimeType(1)],type=[inst:JSBool,inst:Type,inst:TypeImpl,lit:String,param:Type]*/
+/*strong.member: typeLiteralField:static=[createRuntimeType(1)],type=[inst:JSBool,inst:Type,inst:TypeImpl,lit:String,param:Type]*/
 const typeLiteralField = String;
 
-/*element: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
+/*member: id:static=[checkSubtype(4),checkSubtypeOfRuntimeType(2),getRuntimeTypeArgument(3),getRuntimeTypeArgumentIntercepted(4),getRuntimeTypeInfo(1),getTypeArgumentByIndex(2),setRuntimeTypeInfo(2)],type=[inst:JSArray<dynamic>,inst:JSBool,inst:JSExtendableArray<dynamic>,inst:JSFixedArray<dynamic>,inst:JSMutableArray<dynamic>,inst:JSUnmodifiableArray<dynamic>,param:Object,param:id.T]*/
 T id<T>(T t) => t;
 
-/*strong.element: _instantiation:
+/*strong.member: _instantiation:
  static=[
   checkSubtype(4),
   extractFunctionTypeObjectFromInternal(1),
@@ -82,13 +82,13 @@
 */
 const int Function(int) _instantiation = id;
 
-/*strong.element: instantiationField:static=[_instantiation]*/
+/*strong.member: instantiationField:static=[_instantiation]*/
 const dynamic instantiationField = _instantiation;
 
 topLevelMethod() {}
 
-/*strong.element: topLevelTearOffField:static=[topLevelMethod]*/
+/*strong.member: topLevelTearOffField:static=[topLevelMethod]*/
 const dynamic topLevelTearOffField = topLevelMethod;
 
-/*strong.element: staticTearOffField:static=[Class.staticMethodField]*/
+/*strong.member: staticTearOffField:static=[Class.staticMethodField]*/
 const dynamic staticTearOffField = Class.staticMethodField;
diff --git a/tests/compiler/dart2js/inference/callers/field_access.dart b/tests/compiler/dart2js/inference/callers/field_access.dart
index 71699e9..4cad4a1 100644
--- a/tests/compiler/dart2js/inference/callers/field_access.dart
+++ b/tests/compiler/dart2js/inference/callers/field_access.dart
@@ -2,15 +2,15 @@
 // 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.
 
-/*element: B.:[main]*/
+/*member: B.:[main]*/
 class A {
-  /*element: A.field:[main]*/
+  /*member: A.field:[main]*/
   var field;
 }
 
-/*element: A.:[main]*/
+/*member: A.:[main]*/
 class B {
-  /*element: B.field:[main]*/
+  /*member: B.field:[main]*/
   var field;
 }
 
diff --git a/tests/compiler/dart2js/inference/data/abstract_method.dart b/tests/compiler/dart2js/inference/data/abstract_method.dart
index 30a2e1f..b6076c4 100644
--- a/tests/compiler/dart2js/inference/data/abstract_method.dart
+++ b/tests/compiler/dart2js/inference/data/abstract_method.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   abstractEquals();
 }
@@ -11,10 +11,10 @@
 // Call abstract method implemented by superclass.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
   operator ==(_);
 }
 
-/*element: abstractEquals:[exact=JSBool]*/
+/*member: abstractEquals:[exact=JSBool]*/
 abstractEquals() => new Class1() /*invoke: [exact=Class1]*/ == new Class1();
diff --git a/tests/compiler/dart2js/inference/data/and_or.dart b/tests/compiler/dart2js/inference/data/and_or.dart
index e1b9c27..36602da 100644
--- a/tests/compiler/dart2js/inference/data/and_or.dart
+++ b/tests/compiler/dart2js/inference/data/and_or.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*element: X.:[exact=X]*/
+/*member: X.:[exact=X]*/
 class X {}
 
-/*element: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn1() {
   var a;
   ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
@@ -13,7 +13,7 @@
   return a;
 }
 
-/*element: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn2() {
   var a;
   ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
@@ -21,14 +21,14 @@
   return a;
 }
 
-/*element: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn3() {
   var a;
   a = a == 54 ? 'foo' : 31;
   return a;
 }
 
-/*element: returnDyn4:Union([exact=JSUInt31], [exact=X])*/
+/*member: returnDyn4:Union([exact=JSUInt31], [exact=X])*/
 returnDyn4() {
   var a;
   ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
@@ -36,7 +36,7 @@
   return a;
 }
 
-/*element: returnDyn5:Union([exact=JSUInt31], [exact=X])*/
+/*member: returnDyn5:Union([exact=JSUInt31], [exact=X])*/
 returnDyn5() {
   var a;
   ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
@@ -44,20 +44,20 @@
   return a;
 }
 
-/*element: returnDyn6:Union([exact=JSString], [exact=X])*/
+/*member: returnDyn6:Union([exact=JSString], [exact=X])*/
 returnDyn6() {
   var a;
   a = a == 54 ? 'foo' : new X();
   return a;
 }
 
-/*element: returnDyn7b:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn7b:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn7b(
     /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
   return x;
 }
 
-/*element: returnDyn7:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn7:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn7() {
   dynamic a = "foo";
   if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -69,13 +69,13 @@
   return a;
 }
 
-/*element: returnDyn8:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn8:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn8(
     /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
   return x;
 }
 
-/*element: test8:Union([exact=JSUInt31], [null|exact=JSString])*/ test8() {
+/*member: test8:Union([exact=JSUInt31], [null|exact=JSString])*/ test8() {
   dynamic a = "foo";
   if (a. /*Value([exact=JSString], value: "foo")*/ length
       /*invoke: [subclass=JSInt]*/ ==
@@ -86,13 +86,13 @@
   if ((false && a is! String) || returnDyn8(a)) return a;
 }
 
-/*element: returnDyn9:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn9:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn9(
     /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
   return x;
 }
 
-/*element: test9:[null]*/
+/*member: test9:[null]*/
 test9() {
   dynamic a = "foo";
   if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -103,11 +103,11 @@
   if (!(a is bool && a is bool)) returnDyn9(a);
 }
 
-/*element: returnString:[exact=JSString]*/ returnString(
+/*member: returnString:[exact=JSString]*/ returnString(
         /*[exact=JSString]*/ x) =>
     x;
 
-/*element: test10:[null]*/
+/*member: test10:[null]*/
 test10() {
   dynamic a = "foo";
   if (a. /*Value([exact=JSString], value: "foo")*/ length
@@ -118,7 +118,7 @@
   if (!(a is num) && a is String) returnString(a);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnDyn1();
   returnDyn2();
diff --git a/tests/compiler/dart2js/inference/data/as.dart b/tests/compiler/dart2js/inference/data/as.dart
index d7ae559e..3a66972 100644
--- a/tests/compiler/dart2js/inference/data/as.dart
+++ b/tests/compiler/dart2js/inference/data/as.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   asIntWithString();
   asIntWithNegative();
@@ -15,10 +15,10 @@
 // As int of int and non-int types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _asIntWithString:[exact=JSUInt31]*/
+/*member: _asIntWithString:[exact=JSUInt31]*/
 _asIntWithString(/*Union([exact=JSString], [exact=JSUInt31])*/ o) => o as int;
 
-/*element: asIntWithString:[null]*/
+/*member: asIntWithString:[null]*/
 asIntWithString() {
   _asIntWithString(0);
   _asIntWithString('');
@@ -28,10 +28,10 @@
 // As int of known int and an unknown int types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _asIntWithNegative:[subclass=JSInt]*/
+/*member: _asIntWithNegative:[subclass=JSInt]*/
 _asIntWithNegative(/*[subclass=JSInt]*/ o) => o as int;
 
-/*element: asIntWithNegative:[null]*/
+/*member: asIntWithNegative:[null]*/
 asIntWithNegative() {
   _asIntWithNegative(0);
   _asIntWithNegative(/*invoke: [exact=JSUInt31]*/ -1);
@@ -41,10 +41,10 @@
 // As int of 0.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _asIntOfZero:[exact=JSUInt31]*/
+/*member: _asIntOfZero:[exact=JSUInt31]*/
 _asIntOfZero(/*[exact=JSUInt31]*/ o) => o as int;
 
-/*element: asIntOfZero:[null]*/
+/*member: asIntOfZero:[null]*/
 asIntOfZero() {
   _asIntOfZero(0);
 }
@@ -53,10 +53,10 @@
 // As int of -1.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _asIntOfMinusOne:[subclass=JSInt]*/
+/*member: _asIntOfMinusOne:[subclass=JSInt]*/
 _asIntOfMinusOne(/*[subclass=JSInt]*/ o) => o as int;
 
-/*element: asIntOfMinusOne:[null]*/
+/*member: asIntOfMinusOne:[null]*/
 asIntOfMinusOne() {
   _asIntOfMinusOne(/*invoke: [exact=JSUInt31]*/ -1);
 }
@@ -65,10 +65,10 @@
 // As int of string.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _asIntOfString:[empty]*/
+/*member: _asIntOfString:[empty]*/
 _asIntOfString(/*Value([exact=JSString], value: "")*/ o) => o as int;
 
-/*element: asIntOfString:[null]*/
+/*member: asIntOfString:[null]*/
 asIntOfString() {
   _asIntOfString('');
 }
diff --git a/tests/compiler/dart2js/inference/data/assert.dart b/tests/compiler/dart2js/inference/data/assert.dart
index e06b0a5..8f470ae 100644
--- a/tests/compiler/dart2js/inference/data/assert.dart
+++ b/tests/compiler/dart2js/inference/data/assert.dart
@@ -6,7 +6,7 @@
 /// file 'assert_ea.dart' contains similar tests for when assertions are
 /// _enabled_.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleAssert();
   failingAssert();
@@ -22,7 +22,7 @@
 // Simple assert statement known to be valid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleAssert:[null]*/
+/*member: simpleAssert:[null]*/
 simpleAssert() {
   assert(true);
 }
@@ -31,7 +31,7 @@
 // Simple assert statement known to be invalid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: failingAssert:[exact=JSUInt31]*/
+/*member: failingAssert:[exact=JSUInt31]*/
 failingAssert() {
   assert(false);
   return 0;
@@ -41,7 +41,7 @@
 // Simple assert statement with message known to be valid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleAssertWithMessage:[null]*/
+/*member: simpleAssertWithMessage:[null]*/
 simpleAssertWithMessage() {
   assert(true, 'foo');
 }
@@ -50,14 +50,14 @@
 // Assert statement that promotes a local.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _promoteLocalAssert:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _promoteLocalAssert:Union([exact=JSString], [exact=JSUInt31])*/
 _promoteLocalAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
   var local = o;
   assert(local is int);
   return local;
 }
 
-/*element: promoteLocalAssert:[null]*/
+/*member: promoteLocalAssert:[null]*/
 promoteLocalAssert() {
   _promoteLocalAssert(0);
   _promoteLocalAssert('');
@@ -67,13 +67,13 @@
 // Assert statement that promotes a parameter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _promoteParameterAssert:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _promoteParameterAssert:Union([exact=JSString], [exact=JSUInt31])*/
 _promoteParameterAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
   assert(o is int);
   return o;
 }
 
-/*element: promoteParameterAssert:[null]*/
+/*member: promoteParameterAssert:[null]*/
 promoteParameterAssert() {
   _promoteParameterAssert(0);
   _promoteParameterAssert('');
@@ -83,7 +83,7 @@
 // Assert statement with an unreachable throw.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: unreachableThrow:[exact=JSUInt31]*/
+/*member: unreachableThrow:[exact=JSUInt31]*/
 unreachableThrow() {
   assert(true, throw "unreachable");
   return 0;
@@ -93,14 +93,14 @@
 // Assert with a side effect in the message.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _messageWithSideEffect:[null]*/
+/*member: _messageWithSideEffect:[null]*/
 _messageWithSideEffect(/*[exact=JSBool]*/ b) {
   var a;
   assert(b, a = 42);
   return a;
 }
 
-/*element: messageWithSideEffect:[null]*/
+/*member: messageWithSideEffect:[null]*/
 messageWithSideEffect() {
   _messageWithSideEffect(true);
   _messageWithSideEffect(false);
@@ -110,7 +110,7 @@
 // Assert with a caught side effect in the message.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _messageWithCaughtSideEffect:[null]*/
+/*member: _messageWithCaughtSideEffect:[null]*/
 _messageWithCaughtSideEffect(/*[exact=JSBool]*/ b) {
   var a;
   try {
@@ -119,7 +119,7 @@
   return a;
 }
 
-/*element: messageWithCaughtSideEffect:[null]*/
+/*member: messageWithCaughtSideEffect:[null]*/
 messageWithCaughtSideEffect() {
   _messageWithCaughtSideEffect(true);
   _messageWithCaughtSideEffect(false);
diff --git a/tests/compiler/dart2js/inference/data/assert_ea.dart b/tests/compiler/dart2js/inference/data/assert_ea.dart
index 7b216e5..5faff4e 100644
--- a/tests/compiler/dart2js/inference/data/assert_ea.dart
+++ b/tests/compiler/dart2js/inference/data/assert_ea.dart
@@ -6,7 +6,7 @@
 /// file 'assert.dart' contains similar tests for when assertions are
 /// _disabled_.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleAssert();
   failingAssert();
@@ -22,7 +22,7 @@
 // Simple assert statement known to be valid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleAssert:[null]*/
+/*member: simpleAssert:[null]*/
 simpleAssert() {
   assert(true);
 }
@@ -31,7 +31,7 @@
 // Simple assert statement known to be invalid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: failingAssert:[exact=JSUInt31]*/
+/*member: failingAssert:[exact=JSUInt31]*/
 failingAssert() {
   assert(false);
   return 0;
@@ -41,7 +41,7 @@
 // Simple assert statement with message known to be valid.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleAssertWithMessage:[null]*/
+/*member: simpleAssertWithMessage:[null]*/
 simpleAssertWithMessage() {
   assert(true, 'foo');
 }
@@ -50,14 +50,14 @@
 // Assert statement that promotes a local.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _promoteLocalAssert:[exact=JSUInt31]*/
+/*member: _promoteLocalAssert:[exact=JSUInt31]*/
 _promoteLocalAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
   var local = o;
   assert(local is int);
   return local;
 }
 
-/*element: promoteLocalAssert:[null]*/
+/*member: promoteLocalAssert:[null]*/
 promoteLocalAssert() {
   _promoteLocalAssert(0);
   _promoteLocalAssert('');
@@ -67,13 +67,13 @@
 // Assert statement that promotes a parameter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _promoteParameterAssert:[exact=JSUInt31]*/
+/*member: _promoteParameterAssert:[exact=JSUInt31]*/
 _promoteParameterAssert(/*Union([exact=JSString], [exact=JSUInt31])*/ o) {
   assert(o is int);
   return o;
 }
 
-/*element: promoteParameterAssert:[null]*/
+/*member: promoteParameterAssert:[null]*/
 promoteParameterAssert() {
   _promoteParameterAssert(0);
   _promoteParameterAssert('');
@@ -83,7 +83,7 @@
 // Assert statement with an unreachable throw.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: unreachableThrow:[exact=JSUInt31]*/
+/*member: unreachableThrow:[exact=JSUInt31]*/
 unreachableThrow() {
   assert(true, throw "unreachable");
   return 0;
@@ -93,14 +93,14 @@
 // Assert with a side effect in the message.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _messageWithSideEffect:[null]*/
+/*member: _messageWithSideEffect:[null]*/
 _messageWithSideEffect(/*[exact=JSBool]*/ b) {
   var a;
   assert(b, a = 42);
   return a;
 }
 
-/*element: messageWithSideEffect:[null]*/
+/*member: messageWithSideEffect:[null]*/
 messageWithSideEffect() {
   _messageWithSideEffect(true);
   _messageWithSideEffect(false);
@@ -110,7 +110,7 @@
 // Assert with a caught side effect in the message.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _messageWithCaughtSideEffect:[null|exact=JSUInt31]*/
+/*member: _messageWithCaughtSideEffect:[null|exact=JSUInt31]*/
 _messageWithCaughtSideEffect(/*[exact=JSBool]*/ b) {
   var a;
   try {
@@ -119,7 +119,7 @@
   return a;
 }
 
-/*element: messageWithCaughtSideEffect:[null]*/
+/*member: messageWithCaughtSideEffect:[null]*/
 messageWithCaughtSideEffect() {
   _messageWithCaughtSideEffect(true);
   _messageWithCaughtSideEffect(false);
diff --git a/tests/compiler/dart2js/inference/data/assert_message_throw.dart b/tests/compiler/dart2js/inference/data/assert_message_throw.dart
index d310309..1115952 100644
--- a/tests/compiler/dart2js/inference/data/assert_message_throw.dart
+++ b/tests/compiler/dart2js/inference/data/assert_message_throw.dart
@@ -6,7 +6,7 @@
 /// file 'assert_message_throw_ea.dart' contains similar tests for when
 /// assertions are _enabled_.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main(/*[null|subclass=Object]*/ args) {
   test0();
   test1(args == null);
@@ -15,7 +15,7 @@
 }
 
 // Check that `throw` in the message is handled conditionally.
-/*element: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
 test0() {
   assert(true, throw "unreachable");
   var list = [];
@@ -24,7 +24,7 @@
 
 // Check that side-effects of the assert message is not included after the
 // assert.
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1(/*[exact=JSBool]*/ b) {
   var a;
   assert(b, a = 42);
@@ -33,7 +33,7 @@
 
 // Check that side-effects of the assert message is included after the assert
 // through the thrown exception.
-/*element: test2:[null]*/
+/*member: test2:[null]*/
 test2(/*[exact=JSBool]*/ b) {
   var a;
   try {
@@ -43,7 +43,7 @@
 }
 
 // Check that type tests are preserved after the assert.
-/*element: test3:[null|subclass=Object]*/
+/*member: test3:[null|subclass=Object]*/
 test3(/*[null|subclass=Object]*/ a) {
   assert(a is int);
   return a;
diff --git a/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart b/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
index c3f0a1b..72e4618 100644
--- a/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
+++ b/tests/compiler/dart2js/inference/data/assert_message_throw_ea.dart
@@ -6,7 +6,7 @@
 /// file 'assert_message_throw.dart' contains similar tests for when assertions
 /// are _disabled_.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main(/*[null|subclass=Object]*/ args) {
   test0();
   test1(args == null);
@@ -15,7 +15,7 @@
 }
 
 // Check that `throw` in the message is handled conditionally.
-/*element: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: test0:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
 test0() {
   assert(true, throw "unreachable");
   var list = [];
@@ -24,7 +24,7 @@
 
 // Check that side-effects of the assert message is not included after the
 // assert.
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1(/*[exact=JSBool]*/ b) {
   var a;
   assert(b, a = 42);
@@ -33,7 +33,7 @@
 
 // Check that side-effects of the assert message is included after the assert
 // through the thrown exception.
-/*element: test2:[null|exact=JSUInt31]*/
+/*member: test2:[null|exact=JSUInt31]*/
 test2(/*[exact=JSBool]*/ b) {
   var a;
   try {
@@ -43,7 +43,7 @@
 }
 
 // Check that type tests are preserved after the assert.
-/*element: test3:[subclass=JSInt]*/
+/*member: test3:[subclass=JSInt]*/
 test3(/*[null|subclass=Object]*/ a) {
   assert(a is int);
   return a;
diff --git a/tests/compiler/dart2js/inference/data/assign_op.dart b/tests/compiler/dart2js/inference/data/assign_op.dart
index 6b6dbaa..94d63dc 100644
--- a/tests/compiler/dart2js/inference/data/assign_op.dart
+++ b/tests/compiler/dart2js/inference/data/assign_op.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   assignPlus();
   assignAnd();
@@ -16,25 +16,25 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: assignPlus:[subclass=JSUInt32]*/
+/*member: assignPlus:[subclass=JSUInt32]*/
 assignPlus() {
   var i = 87;
   return i /*invoke: [exact=JSUInt31]*/ += 42;
 }
 
-/*element: assignAnd:[exact=JSUInt31]*/
+/*member: assignAnd:[exact=JSUInt31]*/
 assignAnd() {
   var i = 87;
   return i /*invoke: [exact=JSUInt31]*/ &= 42;
 }
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[subclass=JSPositiveInt]*/
+  /*member: Class1.field:[subclass=JSPositiveInt]*/
   var field = 87;
 }
 
-/*element: instanceAssignPlus:[subclass=JSPositiveInt]*/
+/*member: instanceAssignPlus:[subclass=JSPositiveInt]*/
 instanceAssignPlus() {
   var c = new Class1();
   return c.
@@ -42,13 +42,13 @@
       /*invoke: [subclass=JSPositiveInt]*/ += 42;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[exact=JSUInt31]*/
+  /*member: Class2.field:[exact=JSUInt31]*/
   var field = 87;
 }
 
-/*element: instanceAssignAnd:[exact=JSUInt31]*/
+/*member: instanceAssignAnd:[exact=JSUInt31]*/
 instanceAssignAnd() {
   var c = new Class2();
   return c.
@@ -56,7 +56,7 @@
       /*invoke: [exact=JSUInt31]*/ &= 42;
 }
 
-/*element: assignIndexPlus:[subclass=JSPositiveInt]*/
+/*member: assignIndexPlus:[subclass=JSPositiveInt]*/
 assignIndexPlus() {
   var i = [87];
   return i
@@ -65,7 +65,7 @@
       [0] /*invoke: [subclass=JSPositiveInt]*/ += 42;
 }
 
-/*element: assignIndexAnd:[exact=JSUInt31]*/
+/*member: assignIndexAnd:[exact=JSUInt31]*/
 assignIndexAnd() {
   var i = [87];
   return i
@@ -74,7 +74,7 @@
       [0] /*invoke: [exact=JSUInt31]*/ &= 42;
 }
 
-/*element: assignIndexInc:[subclass=JSPositiveInt]*/
+/*member: assignIndexInc:[subclass=JSPositiveInt]*/
 assignIndexInc() {
   var i = [87];
   return i
@@ -83,7 +83,7 @@
       [0] /*invoke: [subclass=JSPositiveInt]*/ ++;
 }
 
-/*element: assignIndexDec:[subclass=JSInt]*/
+/*member: assignIndexDec:[subclass=JSInt]*/
 assignIndexDec() {
   var i = [87];
   return
diff --git a/tests/compiler/dart2js/inference/data/async_marker.dart b/tests/compiler/dart2js/inference/data/async_marker.dart
index 724c4d8..97a9464 100644
--- a/tests/compiler/dart2js/inference/data/async_marker.dart
+++ b/tests/compiler/dart2js/inference/data/async_marker.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   asyncMethod();
   asyncMethodWithReturn();
@@ -10,16 +10,16 @@
   syncStarMethod();
 }
 
-/*element: asyncMethod:[exact=_Future]*/
+/*member: asyncMethod:[exact=_Future]*/
 asyncMethod() async {}
 
-/*element: asyncMethodWithReturn:Union([exact=JSUInt31], [exact=_Future])*/
+/*member: asyncMethodWithReturn:Union([exact=JSUInt31], [exact=_Future])*/
 asyncMethodWithReturn() async {
   return 0;
 }
 
-/*element: asyncStarMethod:[exact=_ControllerStream]*/
+/*member: asyncStarMethod:[exact=_ControllerStream]*/
 asyncStarMethod() async* {}
 
-/*element: syncStarMethod:[exact=_SyncStarIterable]*/
+/*member: syncStarMethod:[exact=_SyncStarIterable]*/
 syncStarMethod() sync* {}
diff --git a/tests/compiler/dart2js/inference/data/await.dart b/tests/compiler/dart2js/inference/data/await.dart
index de21806..1f7bfea 100644
--- a/tests/compiler/dart2js/inference/data/await.dart
+++ b/tests/compiler/dart2js/inference/data/await.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   awaitOfFuture();
   awaitOfInt();
@@ -15,10 +15,10 @@
 // Await of Future.value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[null]*/
+/*member: _method1:[null]*/
 _method1(/*[null|subclass=JSInt]*/ o) {}
 
-/*element: awaitOfFuture:[exact=_Future]*/
+/*member: awaitOfFuture:[exact=_Future]*/
 awaitOfFuture() async {
   var future = new Future.value(0);
   var local = await future;
@@ -29,10 +29,10 @@
 // Await of int.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method2:[null]*/
+/*member: _method2:[null]*/
 _method2(/*[null|subclass=JSInt]*/ o) {}
 
-/*element: awaitOfInt:[exact=_Future]*/
+/*member: awaitOfInt:[exact=_Future]*/
 awaitOfInt() async {
   var local = await 0;
   _method2(local);
@@ -42,15 +42,15 @@
 // Await for of Stream.fromIterable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method3:[null]*/
+/*member: _method3:[null]*/
 _method3(
     /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
     o) {}
 
-/*element: _method4:[null]*/
+/*member: _method4:[null]*/
 _method4(/*[null|subclass=JSInt]*/ o) {}
 
-/*element: awaitForOfStream:[exact=_Future]*/
+/*member: awaitForOfStream:[exact=_Future]*/
 awaitForOfStream() async {
   var list = [0];
   _method3(list);
diff --git a/tests/compiler/dart2js/inference/data/break_continue.dart b/tests/compiler/dart2js/inference/data/break_continue.dart
index 6ef1d84..989c474 100644
--- a/tests/compiler/dart2js/inference/data/break_continue.dart
+++ b/tests/compiler/dart2js/inference/data/break_continue.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   breakInWhile();
   noBreakInWhile();
@@ -16,7 +16,7 @@
 // A break statement in a while loop.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _breakInWhile:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _breakInWhile:Union([exact=JSString], [exact=JSUInt31])*/
 _breakInWhile(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   while (b) {
@@ -29,7 +29,7 @@
   return local;
 }
 
-/*element: breakInWhile:[null]*/
+/*member: breakInWhile:[null]*/
 breakInWhile() {
   _breakInWhile(true);
   _breakInWhile(false);
@@ -39,7 +39,7 @@
 // The while loop above _without_ the break statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _noBreakInWhile:[exact=JSUInt31]*/
+/*member: _noBreakInWhile:[exact=JSUInt31]*/
 _noBreakInWhile(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   while (b) {
@@ -51,7 +51,7 @@
   return local;
 }
 
-/*element: noBreakInWhile:[null]*/
+/*member: noBreakInWhile:[null]*/
 noBreakInWhile() {
   _noBreakInWhile(true);
   _noBreakInWhile(false);
@@ -61,7 +61,7 @@
 // A continue statement in a while loop.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _continueInWhile:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _continueInWhile:Union([exact=JSString], [exact=JSUInt31])*/
 _continueInWhile(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   while (b) {
@@ -75,7 +75,7 @@
   return local;
 }
 
-/*element: continueInWhile:[null]*/
+/*member: continueInWhile:[null]*/
 continueInWhile() {
   _continueInWhile(true);
   _continueInWhile(false);
@@ -85,7 +85,7 @@
 // The while loop above _without_ the continue statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _noContinueInWhile:[exact=JSUInt31]*/
+/*member: _noContinueInWhile:[exact=JSUInt31]*/
 _noContinueInWhile(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   while (b) {
@@ -98,7 +98,7 @@
   return local;
 }
 
-/*element: noContinueInWhile:[null]*/
+/*member: noContinueInWhile:[null]*/
 noContinueInWhile() {
   _noContinueInWhile(true);
   _noContinueInWhile(false);
@@ -108,7 +108,7 @@
 // A break statement in a labeled statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _breakInIf:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _breakInIf:Union([exact=JSString], [exact=JSUInt31])*/
 _breakInIf(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   label:
@@ -122,7 +122,7 @@
   return local;
 }
 
-/*element: breakInIf:[null]*/
+/*member: breakInIf:[null]*/
 breakInIf() {
   _breakInIf(true);
   _breakInIf(false);
@@ -132,7 +132,7 @@
 // The "labeled statement" above _without_ the break statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _noBreakInIf:[exact=JSUInt31]*/
+/*member: _noBreakInIf:[exact=JSUInt31]*/
 _noBreakInIf(/*[exact=JSBool]*/ b) {
   dynamic local = 42;
   {
@@ -143,7 +143,7 @@
   return local;
 }
 
-/*element: noBreakInIf:[null]*/
+/*member: noBreakInIf:[null]*/
 noBreakInIf() {
   _noBreakInIf(true);
   _noBreakInIf(false);
diff --git a/tests/compiler/dart2js/inference/data/call_in_loop.dart b/tests/compiler/dart2js/inference/data/call_in_loop.dart
index 5c1a6eb..f91fbc9 100644
--- a/tests/compiler/dart2js/inference/data/call_in_loop.dart
+++ b/tests/compiler/dart2js/inference/data/call_in_loop.dart
@@ -4,9 +4,9 @@
 
 /// Regression test for [ClosureCallSiteTypeInformation] in loops.
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class<T> {
-  /*element: Class.method:[null]*/
+  /*member: Class.method:[null]*/
   method() {
     /*iterator: Container([exact=JSExtendableArray], element: [empty], length: 0)*/
     /*current: [exact=ArrayIterator]*/
@@ -20,7 +20,7 @@
   }
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new Class(). /*invoke: [exact=Class]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
index 9fc9e74..d9c18f2 100644
--- a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-/*element: f:[subclass=JSInt]*/
+/*member: f:[subclass=JSInt]*/
 int f(
         int
             /*strong.[null|subclass=Object]*/
@@ -18,11 +18,11 @@
 
 typedef int IntToInt(int x);
 
-/*element: test:[null]*/
+/*member: test:[null]*/
 test(/*[null|subclass=Object]*/ a, /*[subclass=Closure]*/ b) =>
     Expect.identical(a, b);
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   // It is possible to use `.call` on a function-typed value (even though it is
   // redundant).  Similarly, it is possible to tear off `.call` on a
diff --git a/tests/compiler/dart2js/inference/data/call_site.dart b/tests/compiler/dart2js/inference/data/call_site.dart
index 5af853c..c945208 100644
--- a/tests/compiler/dart2js/inference/data/call_site.dart
+++ b/tests/compiler/dart2js/inference/data/call_site.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
@@ -25,201 +25,201 @@
   test19();
 }
 
-/*element: A1.:[exact=A1]*/
+/*member: A1.:[exact=A1]*/
 class A1 {
-  /*element: A1.x1:Value([exact=JSString], value: "s")*/
+  /*member: A1.x1:Value([exact=JSString], value: "s")*/
   x1(
           /*Value([exact=JSString], value: "s")*/ p) =>
       p;
 }
 
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1() {
   new A1(). /*invoke: [exact=A1]*/ x1("s");
 }
 
-/*element: A2.:[exact=A2]*/
+/*member: A2.:[exact=A2]*/
 class A2 {
-  /*element: A2.x2:[exact=JSUInt31]*/
+  /*member: A2.x2:[exact=JSUInt31]*/
   x2(/*[exact=JSUInt31]*/ p) => p;
 }
 
-/*element: test2:[null]*/
+/*member: test2:[null]*/
 test2() {
   new A2(). /*invoke: [exact=A2]*/ x2(1);
 }
 
-/*element: A3.:[exact=A3]*/
+/*member: A3.:[exact=A3]*/
 class A3 {
-  /*element: A3.x3:[empty]*/
+  /*member: A3.x3:[empty]*/
   x3(/*[subclass=JSInt]*/ p) => /*invoke: [exact=A3]*/ x3(
       p /*invoke: [subclass=JSInt]*/ - 1);
 }
 
-/*element: test3:[null]*/
+/*member: test3:[null]*/
 test3() {
   new A3(). /*invoke: [exact=A3]*/ x3(1);
 }
 
-/*element: A4.:[exact=A4]*/
+/*member: A4.:[exact=A4]*/
 class A4 {
-  /*element: A4.x4:[empty]*/
+  /*member: A4.x4:[empty]*/
   x4(/*[subclass=JSNumber]*/ p) => /*invoke: [exact=A4]*/ x4(
       p /*invoke: [subclass=JSNumber]*/ - 1);
 }
 
-/*element: test4:[null]*/
+/*member: test4:[null]*/
 test4() {
   new A4(). /*invoke: [exact=A4]*/ x4(1.5);
 }
 
-/*element: A5.:[exact=A5]*/
+/*member: A5.:[exact=A5]*/
 class A5 {
-  /*element: A5.x5:Union([exact=JSDouble], [exact=JSUInt31])*/
+  /*member: A5.x5:Union([exact=JSDouble], [exact=JSUInt31])*/
   x5(
           /*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
       p;
 }
 
-/*element: test5:[null]*/
+/*member: test5:[null]*/
 test5() {
   new A5(). /*invoke: [exact=A5]*/ x5(1);
   new A5(). /*invoke: [exact=A5]*/ x5(1.5);
 }
 
-/*element: A6.:[exact=A6]*/
+/*member: A6.:[exact=A6]*/
 class A6 {
-  /*element: A6.x6:Union([exact=JSDouble], [exact=JSUInt31])*/
+  /*member: A6.x6:Union([exact=JSDouble], [exact=JSUInt31])*/
   x6(
           /*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
       p;
 }
 
-/*element: test6:[null]*/
+/*member: test6:[null]*/
 test6() {
   new A6(). /*invoke: [exact=A6]*/ x6(1.5);
   new A6(). /*invoke: [exact=A6]*/ x6(1);
 }
 
-/*element: A7.:[exact=A7]*/
+/*member: A7.:[exact=A7]*/
 class A7 {
-  /*element: A7.x7:[empty]*/
+  /*member: A7.x7:[empty]*/
   x7(
       /*Union([exact=JSString], [exact=JSUInt31])*/ p) => /*invoke: [exact=A7]*/ x7("x");
 }
 
-/*element: test7:[null]*/
+/*member: test7:[null]*/
 test7() {
   new A7(). /*invoke: [exact=A7]*/ x7(1);
 }
 
-/*element: A8.:[exact=A8]*/
+/*member: A8.:[exact=A8]*/
 class A8 {
-  /*element: A8.x8:[empty]*/
+  /*member: A8.x8:[empty]*/
   x8(
           /*Union([exact=JSString], [subclass=JsLinkedHashMap])*/ p) =>
       /*invoke: [exact=A8]*/ x8("x");
 }
 
-/*element: test8:[null]*/
+/*member: test8:[null]*/
 test8() {
   new A8(). /*invoke: [exact=A8]*/ x8({});
 }
 
-/*element: A9.:[exact=A9]*/
+/*member: A9.:[exact=A9]*/
 class A9 {
-  /*element: A9.x9:[empty]*/ x9(
+  /*member: A9.x9:[empty]*/ x9(
           /*[exact=JSUInt31]*/ p1,
           /*Union([exact=JSString], [exact=JSUInt31])*/ p2,
           /*Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ p3) =>
       /*invoke: [exact=A9]*/ x9(p1, "x", {});
 }
 
-/*element: test9:[null]*/
+/*member: test9:[null]*/
 test9() {
   new A9(). /*invoke: [exact=A9]*/ x9(1, 2, 3);
 }
 
-/*element: A10.:[exact=A10]*/
+/*member: A10.:[exact=A10]*/
 class A10 {
-  /*element: A10.x10:[empty]*/ x10(
+  /*member: A10.x10:[empty]*/ x10(
       /*[exact=JSUInt31]*/ p1,
       /*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A10]*/ x10(p1, p2);
 }
 
-/*element: test10:[null]*/
+/*member: test10:[null]*/
 test10() {
   new A10(). /*invoke: [exact=A10]*/ x10(1, 2);
 }
 
-/*element: A11.:[exact=A11]*/
+/*member: A11.:[exact=A11]*/
 class A11 {
-  /*element: A11.x11:[empty]*/
+  /*member: A11.x11:[empty]*/
   x11(
       /*[exact=JSUInt31]*/ p1,
       /*[exact=JSUInt31]*/ p2) => /*invoke: [exact=A11]*/ x11(p1, p2);
 }
 
-/*element: f11:[null]*/
+/*member: f11:[null]*/
 void f11(/*[null]*/ p) {
   p. /*invoke: [null]*/ x11("x", "y");
 }
 
-/*element: test11:[null]*/
+/*member: test11:[null]*/
 test11() {
   f11(null);
   new A11(). /*invoke: [exact=A11]*/ x11(1, 2);
 }
 
-/*element: A12.:[exact=A12]*/
+/*member: A12.:[exact=A12]*/
 class A12 {
-  /*element: A12.x12:[empty]*/
+  /*member: A12.x12:[empty]*/
   x12(
           /*Union([exact=JSString], [exact=JSUInt31])*/ p1,
           /*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
       /*invoke: [exact=A12]*/ x12(1, 2);
 }
 
-/*element: test12:[null]*/
+/*member: test12:[null]*/
 test12() {
   new A12(). /*invoke: [exact=A12]*/ x12("x", "y");
 }
 
-/*element: A13.:[exact=A13]*/
+/*member: A13.:[exact=A13]*/
 class A13 {
-  /*element: A13.x13:[exact=JSUInt31]*/
+  /*member: A13.x13:[exact=JSUInt31]*/
   x13(
           /*Value([exact=JSString], value: "x")*/ p1,
           [/*[exact=JSUInt31]*/ p2 = 1]) =>
       1;
 }
 
-/*element: test13:[null]*/
+/*member: test13:[null]*/
 test13() {
   new A13(). /*invoke: [exact=A13]*/ x13("x", 1);
   new A13(). /*invoke: [exact=A13]*/ x13("x");
 }
 
-/*element: A14.:[exact=A14]*/
+/*member: A14.:[exact=A14]*/
 class A14 {
-  /*element: A14.x14:[exact=JSUInt31]*/
+  /*member: A14.x14:[exact=JSUInt31]*/
   x14(
           /*Union([exact=JSDouble], [exact=JSUInt31])*/ p) =>
       1;
 }
 
-/*element: f14:[exact=JSUInt31]*/
+/*member: f14:[exact=JSUInt31]*/
 f14(/*[exact=A14]*/ p) => p. /*invoke: [exact=A14]*/ x14(2.2);
 
-/*element: test14:[null]*/
+/*member: test14:[null]*/
 test14() {
   new A14(). /*invoke: [exact=A14]*/ x14(1);
   f14(new A14());
 }
 
-/*element: A15.:[exact=A15]*/
+/*member: A15.:[exact=A15]*/
 class A15 {
-  /*element: A15.x15:[exact=JSUInt31]*/
+  /*member: A15.x15:[exact=JSUInt31]*/
   x15(/*[exact=JSUInt31]*/ p1,
       [/*Value([exact=JSString], value: "s")*/ p2 = "s"]) {
     p2. /*Value([exact=JSString], value: "s")*/ length;
@@ -227,39 +227,39 @@
   }
 }
 
-/*element: test15:[null]*/
+/*member: test15:[null]*/
 test15() {
   new A15(). /*invoke: [exact=A15]*/ x15(1);
 }
 
-/*element: A16.:[exact=A16]*/
+/*member: A16.:[exact=A16]*/
 class A16 {
-  /*element: A16.x16:[exact=JSUInt31]*/
+  /*member: A16.x16:[exact=JSUInt31]*/
   x16(
           /*Value([exact=JSString], value: "x")*/ p1,
           [/*[exact=JSBool]*/ p2 = true]) =>
       1;
 }
 
-/*element: f16:[empty]*/
+/*member: f16:[empty]*/
 f16(/*[null]*/ p) => p. /*invoke: [null]*/ a("x");
 
-/*element: test16:[null]*/
+/*member: test16:[null]*/
 test16() {
   new A16(). /*invoke: [exact=A16]*/ x16("x");
   new A16(). /*invoke: [exact=A16]*/ x16("x", false);
   f16(null);
 }
 
-/*element: A17.:[exact=A17]*/
+/*member: A17.:[exact=A17]*/
 class A17 {
-  /*element: A17.x17:[exact=JSUInt31]*/
+  /*member: A17.x17:[exact=JSUInt31]*/
   x17(/*[exact=JSUInt31]*/ p1,
           [/*[exact=JSUInt31]*/ p2 = 1, /*[exact=JSString]*/ p3 = "s"]) =>
       1;
 }
 
-/*element: test17:[null]*/
+/*member: test17:[null]*/
 test17() {
   new A17(). /*invoke: [exact=A17]*/ x17(1);
   new A17(). /*invoke: [exact=A17]*/ x17(1, 2);
@@ -274,15 +274,15 @@
   d. /*invoke: [exact=A17]*/ x17(1, p2: 2, p3: "x");
 }
 
-/*element: A18.:[exact=A18]*/
+/*member: A18.:[exact=A18]*/
 class A18 {
-  /*element: A18.x18:[exact=JSUInt31]*/
+  /*member: A18.x18:[exact=JSUInt31]*/
   x18(/*[exact=JSUInt31]*/ p1,
           [/*[exact=JSBool]*/ p2 = 1, /*[exact=JSDouble]*/ p3 = "s"]) =>
       1;
 }
 
-/*element: test18:[null]*/
+/*member: test18:[null]*/
 test18() {
   new A18(). /*invoke: [exact=A18]*/ x18(1, true, 1.1);
   new A18(). /*invoke: [exact=A18]*/ x18(1, false, 2.2);
@@ -292,19 +292,19 @@
   b. /*invoke: [exact=A18]*/ x18(1, p2: false, p3: 4.4);
 }
 
-/*element: A19.:[exact=A19]*/
+/*member: A19.:[exact=A19]*/
 class A19 {
-  /*element: A19.x19:[empty]*/
+  /*member: A19.x19:[empty]*/
   x19(
           /*Union([exact=JSString], [exact=JSUInt31])*/ p1,
           /*Union([exact=JSString], [exact=JSUInt31])*/ p2) =>
       /*invoke: [subclass=A19]*/ x19(p1, p2);
 }
 
-/*element: B19.:[exact=B19]*/
+/*member: B19.:[exact=B19]*/
 class B19 extends A19 {}
 
-/*element: test19:[null]*/
+/*member: test19:[null]*/
 test19() {
   new B19(). /*invoke: [exact=B19]*/ x19("a", "b");
   new A19(). /*invoke: [exact=A19]*/ x19(1, 2);
diff --git a/tests/compiler/dart2js/inference/data/catch.dart b/tests/compiler/dart2js/inference/data/catch.dart
index 46a150a..d87f53a 100644
--- a/tests/compiler/dart2js/inference/data/catch.dart
+++ b/tests/compiler/dart2js/inference/data/catch.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   catchUntyped();
   catchTyped();
@@ -13,7 +13,7 @@
 /// Untyped catch clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: catchUntyped:[subclass=Object]*/
+/*member: catchUntyped:[subclass=Object]*/
 catchUntyped() {
   dynamic local = 0;
   try {} catch (e) {
@@ -26,7 +26,7 @@
 /// Typed catch clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: catchTyped:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: catchTyped:Union([exact=JSString], [exact=JSUInt31])*/
 catchTyped() {
   dynamic local = 0;
   try {} on String catch (e) {
@@ -39,7 +39,7 @@
 /// Catch clause with stack trace.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: catchStackTrace:[null|subclass=Object]*/
+/*member: catchStackTrace:[null|subclass=Object]*/
 catchStackTrace() {
   dynamic local = 0;
   try {} catch (_, s) {
diff --git a/tests/compiler/dart2js/inference/data/closure.dart b/tests/compiler/dart2js/inference/data/closure.dart
index 544b6ce..e4f2243 100644
--- a/tests/compiler/dart2js/inference/data/closure.dart
+++ b/tests/compiler/dart2js/inference/data/closure.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInClosure();
   accessInClosure();
@@ -17,7 +17,7 @@
   postfixInClosure();
 }
 
-/*element: returnInClosure:[exact=JSUInt31]*/
+/*member: returnInClosure:[exact=JSUInt31]*/
 returnInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -28,7 +28,7 @@
   return lines;
 }
 
-/*element: accessInClosure:[exact=JSUInt31]*/
+/*member: accessInClosure:[exact=JSUInt31]*/
 accessInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -39,7 +39,7 @@
   return lines;
 }
 
-/*element: invokeInClosure:[exact=JSUInt31]*/
+/*member: invokeInClosure:[exact=JSUInt31]*/
 invokeInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -50,7 +50,7 @@
   return lines;
 }
 
-/*element: operatorInClosure:[exact=JSUInt31]*/
+/*member: operatorInClosure:[exact=JSUInt31]*/
 operatorInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -61,7 +61,7 @@
   return lines;
 }
 
-/*element: assignInClosure:[subclass=JSInt]*/
+/*member: assignInClosure:[subclass=JSInt]*/
 assignInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -72,7 +72,7 @@
   return lines;
 }
 
-/*element: assignInTwoClosures:[subclass=JSInt]*/
+/*member: assignInTwoClosures:[subclass=JSInt]*/
 assignInTwoClosures() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -86,7 +86,7 @@
   return lines;
 }
 
-/*element: accessAssignInClosure:[subclass=JSInt]*/
+/*member: accessAssignInClosure:[subclass=JSInt]*/
 accessAssignInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -97,7 +97,7 @@
   return lines;
 }
 
-/*element: accessBeforeAssignInClosure:[exact=JSUInt31]*/
+/*member: accessBeforeAssignInClosure:[exact=JSUInt31]*/
 accessBeforeAssignInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -109,7 +109,7 @@
   return lines;
 }
 
-/*element: accessAfterAssignInClosure:[exact=JSUInt31]*/
+/*member: accessAfterAssignInClosure:[exact=JSUInt31]*/
 accessAfterAssignInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -121,7 +121,7 @@
   return lines;
 }
 
-/*element: compoundInClosure:[subclass=JSInt]*/
+/*member: compoundInClosure:[subclass=JSInt]*/
 compoundInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
@@ -132,7 +132,7 @@
   return lines;
 }
 
-/*element: postfixInClosure:[subclass=JSPositiveInt]*/
+/*member: postfixInClosure:[subclass=JSPositiveInt]*/
 postfixInClosure() {
   /*[null|subclass=Object]*/ local(/*[subclass=Closure]*/ f) => f();
 
diff --git a/tests/compiler/dart2js/inference/data/closure2.dart b/tests/compiler/dart2js/inference/data/closure2.dart
index 285ff02..5d03f44 100644
--- a/tests/compiler/dart2js/inference/data/closure2.dart
+++ b/tests/compiler/dart2js/inference/data/closure2.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
 returnInt1() {
   var a = 42;
   // ignore: unused_local_variable
@@ -12,7 +12,7 @@
   return a;
 }
 
-/*element: returnDyn1:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn1:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 returnDyn1() {
   dynamic a = 42;
   // ignore: unused_local_variable
@@ -22,7 +22,7 @@
   return a;
 }
 
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
 returnInt2() {
   var a = 42;
   // ignore: unused_local_variable
@@ -32,7 +32,7 @@
   return a;
 }
 
-/*element: returnDyn2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 returnDyn2() {
   dynamic a = 42;
   // ignore: unused_local_variable
@@ -46,7 +46,7 @@
   return a;
 }
 
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
 returnInt3() {
   var a = 42;
   if (a /*invoke: [exact=JSUInt31]*/ == 53) {
@@ -58,7 +58,7 @@
   return a;
 }
 
-/*element: returnDyn3:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: returnDyn3:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 returnDyn3() {
   dynamic a = 42;
   if (a /*invoke: Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/ == 53) {
@@ -70,7 +70,7 @@
   return a;
 }
 
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
 returnInt4() {
   var a = 42;
   /*[exact=JSUInt31]*/ g() {
@@ -80,7 +80,7 @@
   return g();
 }
 
-/*element: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
 returnNum1() {
   dynamic a = 42.5;
   try {
@@ -95,7 +95,7 @@
   return a;
 }
 
-/*element: returnIntOrNull:[null|exact=JSUInt31]*/
+/*member: returnIntOrNull:[null|exact=JSUInt31]*/
 returnIntOrNull() {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
   /*current: [exact=ArrayIterator]*/
@@ -111,16 +111,16 @@
   return 42;
 }
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
-  /*element: A.foo:[exact=A]*/
+  /*member: A.foo:[exact=A]*/
   foo() {
     /*[exact=A]*/ f() => this;
     return f();
   }
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt1();
   returnDyn1();
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer.dart b/tests/compiler/dart2js/inference/data/closure_tracer.dart
index d419c89..82aab01 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: testFunctionStatement:[null|exact=JSUInt31]*/
+/*member: testFunctionStatement:[null|exact=JSUInt31]*/
 testFunctionStatement() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -10,7 +10,7 @@
   return res;
 }
 
-/*element: testFunctionExpression:[null|exact=JSUInt31]*/
+/*member: testFunctionExpression:[null|exact=JSUInt31]*/
 testFunctionExpression() {
   var res;
   var closure = /*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ a) => res = a;
@@ -18,10 +18,10 @@
   return res;
 }
 
-/*element: staticField:[null|subclass=Closure]*/
+/*member: staticField:[null|subclass=Closure]*/
 var staticField;
 
-/*element: testStoredInStatic:[null|exact=JSUInt31]*/
+/*member: testStoredInStatic:[null|exact=JSUInt31]*/
 testStoredInStatic() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -31,16 +31,16 @@
 }
 
 class A {
-  /*element: A.field:[subclass=Closure]*/
+  /*member: A.field:[subclass=Closure]*/
   var field;
-  /*element: A.:[exact=A]*/
+  /*member: A.:[exact=A]*/
   A(this. /*[subclass=Closure]*/ field);
 
-  /*element: A.foo:[exact=JSUInt31]*/
+  /*member: A.foo:[exact=JSUInt31]*/
   static foo(/*[exact=JSUInt31]*/ a) => topLevel3 = a;
 }
 
-/*element: testStoredInInstance:[null|exact=JSUInt31]*/
+/*member: testStoredInInstance:[null|exact=JSUInt31]*/
 testStoredInInstance() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -49,7 +49,7 @@
   return res;
 }
 
-/*element: testStoredInMapOfList:[null|subclass=Object]*/
+/*member: testStoredInMapOfList:[null|subclass=Object]*/
 testStoredInMapOfList() {
   var res;
   /*[null|subclass=Object]*/ closure(/*[null|subclass=Object]*/ a) => res = a;
@@ -69,7 +69,7 @@
   return res;
 }
 
-/*element: testStoredInListOfList:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfList:[null|exact=JSUInt31]*/
 testStoredInListOfList() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -88,7 +88,7 @@
   return res;
 }
 
-/*element: testStoredInListOfListUsingInsert:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfListUsingInsert:[null|exact=JSUInt31]*/
 testStoredInListOfListUsingInsert() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -107,7 +107,7 @@
   return res;
 }
 
-/*element: testStoredInListOfListUsingAdd:[null|exact=JSUInt31]*/
+/*member: testStoredInListOfListUsingAdd:[null|exact=JSUInt31]*/
 testStoredInListOfListUsingAdd() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -127,12 +127,12 @@
   return res;
 }
 
-/*element: foo:[null]*/
+/*member: foo:[null]*/
 foo(/*[subclass=Closure]*/ closure) {
   closure(42);
 }
 
-/*element: testPassedInParameter:[null|exact=JSUInt31]*/
+/*member: testPassedInParameter:[null|exact=JSUInt31]*/
 testPassedInParameter() {
   var res;
   /*[exact=JSUInt31]*/ closure(/*[exact=JSUInt31]*/ a) => res = a;
@@ -140,25 +140,25 @@
   return res;
 }
 
-/*element: topLevel1:[null|exact=JSUInt31]*/
+/*member: topLevel1:[null|exact=JSUInt31]*/
 var topLevel1;
-/*element: foo2:[exact=JSUInt31]*/
+/*member: foo2:[exact=JSUInt31]*/
 foo2(/*[exact=JSUInt31]*/ a) => topLevel1 = a;
 
-/*element: testStaticClosure1:[null|exact=JSUInt31]*/
+/*member: testStaticClosure1:[null|exact=JSUInt31]*/
 testStaticClosure1() {
   var a = foo2;
   a(42);
   return topLevel1;
 }
 
-/*element: topLevel2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: topLevel2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
 var topLevel2;
 
-/*element: bar:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: bar:Union([exact=JSDouble], [exact=JSUInt31])*/
 bar(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) => topLevel2 = a;
 
-/*element: testStaticClosure2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testStaticClosure2:Union([exact=JSUInt31], [null|exact=JSDouble])*/
 testStaticClosure2() {
   var a = bar;
   a(42);
@@ -167,23 +167,23 @@
   return topLevel2;
 }
 
-/*element: topLevel3:[null|exact=JSUInt31]*/
+/*member: topLevel3:[null|exact=JSUInt31]*/
 var topLevel3;
 
-/*element: testStaticClosure3:[null|exact=JSUInt31]*/ testStaticClosure3() {
+/*member: testStaticClosure3:[null|exact=JSUInt31]*/ testStaticClosure3() {
   var a = A.foo;
   a(42);
   return topLevel3;
 }
 
-/*element: topLevel4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: topLevel4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
 var topLevel4;
 
-/*element: testStaticClosure4Helper:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: testStaticClosure4Helper:Union([exact=JSDouble], [exact=JSUInt31])*/
 testStaticClosure4Helper(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) =>
     topLevel4 = a;
 
-/*element: testStaticClosure4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testStaticClosure4:Union([exact=JSUInt31], [null|exact=JSDouble])*/
 testStaticClosure4() {
   var a = testStaticClosure4Helper;
   // Test calling the static after tearing it off.
@@ -192,7 +192,7 @@
   return topLevel4;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   testFunctionStatement();
   testFunctionExpression();
diff --git a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
index 6bc222f..ba4ae4b 100644
--- a/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
+++ b/tests/compiler/dart2js/inference/data/closure_tracer_28919.dart
@@ -4,7 +4,7 @@
 
 // Regression test for issue 28919.
 
-/*element: foo1:[null]*/
+/*member: foo1:[null]*/
 foo1() {
   final methods = [];
   var res, sum;
@@ -25,18 +25,18 @@
   probe1methods(methods);
 }
 
-/*element: probe1res:[null|exact=JSUInt31]*/
+/*member: probe1res:[null|exact=JSUInt31]*/
 probe1res(/*[null|exact=JSUInt31]*/ x) => x;
 
-/*element: probe1sum:[null|subclass=JSPositiveInt]*/
+/*member: probe1sum:[null|subclass=JSPositiveInt]*/
 probe1sum(/*[null|subclass=JSPositiveInt]*/ x) => x;
 
-/*element: probe1methods:Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/
+/*member: probe1methods:Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/
 probe1methods(
         /*Container([exact=JSExtendableArray], element: [subclass=Closure], length: null)*/ x) =>
     x;
 
-/*element: nonContainer:[exact=JSExtendableArray]*/
+/*member: nonContainer:[exact=JSExtendableArray]*/
 nonContainer(/*[exact=JSUInt31]*/ choice) {
   var m = choice /*invoke: [exact=JSUInt31]*/ == 0 ? [] : "<String>";
   if (m is! List) throw 123;
@@ -44,7 +44,7 @@
   return m;
 }
 
-/*element: foo2:[null]*/
+/*member: foo2:[null]*/
 foo2(int /*[exact=JSUInt31]*/ choice) {
   final methods = nonContainer(choice);
 
@@ -69,17 +69,17 @@
   probe2methods(methods);
 }
 
-/*element: probe2res:[null|subclass=JSInt]*/
+/*member: probe2res:[null|subclass=JSInt]*/
 probe2res(
 
         /*[null|subclass=JSInt]*/
         x) =>
     x;
 
-/*element: probe2methods:[exact=JSExtendableArray]*/
+/*member: probe2methods:[exact=JSExtendableArray]*/
 probe2methods(/*[exact=JSExtendableArray]*/ x) => x;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   foo1();
   foo2(0);
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance.dart b/tests/compiler/dart2js/inference/data/closurization_instance.dart
index a4b1c5f..810e71f 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closurizedCallToString();
 }
@@ -11,13 +11,13 @@
 // Implicit/explicit .call on instance method tear-off.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.method:[exact=JSUInt31]*/
+  /*member: Class.method:[exact=JSUInt31]*/
   method() => 42;
 }
 
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   var local = c. /*[exact=Class]*/ method;
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
index f46b1a5..4f785bf 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closurizedCallToString();
 }
@@ -12,16 +12,16 @@
 // '.call' method in the closed world.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.call:Value([exact=JSBool], value: true)*/
+  /*member: Class.call:Value([exact=JSBool], value: true)*/
   call() => true;
 
-  /*element: Class.method:[exact=JSUInt31]*/
+  /*member: Class.method:[exact=JSUInt31]*/
   method() => 42;
 }
 
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/closurization_local_call.dart b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
index 65dd652..65439e1 100644
--- a/tests/compiler/dart2js/inference/data/closurization_local_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closurizedCallToString();
 }
@@ -12,13 +12,13 @@
 // method in the closed world.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.call:Value([exact=JSBool], value: true)*/
+  /*member: Class.call:Value([exact=JSBool], value: true)*/
   call() => true;
 }
 
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/closurization_static.dart b/tests/compiler/dart2js/inference/data/closurization_static.dart
index 0da0999..deea1db 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closurizedCallToString();
 }
@@ -11,10 +11,10 @@
 // Implicit/explicit .call on static method tear-off.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
 method() => 42;
 
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var local = method;
   local. /*invoke: [subclass=Closure]*/ toString();
diff --git a/tests/compiler/dart2js/inference/data/closurization_static_call.dart b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
index c45fd9f..a29e594 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closurizedCallToString();
 }
@@ -12,16 +12,16 @@
 // '.call' method in the closed world.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
 method() => 42;
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.call:Value([exact=JSBool], value: true)*/
+  /*member: Class.call:Value([exact=JSBool], value: true)*/
   call() => true;
 }
 
-/*element: closurizedCallToString:[exact=JSString]*/
+/*member: closurizedCallToString:[exact=JSString]*/
 closurizedCallToString() {
   var c = new Class();
   c.call(); // Make `Class.call` live.
diff --git a/tests/compiler/dart2js/inference/data/conditional.dart b/tests/compiler/dart2js/inference/data/conditional.dart
index d7f799c..e8af4fe 100644
--- a/tests/compiler/dart2js/inference/data/conditional.dart
+++ b/tests/compiler/dart2js/inference/data/conditional.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleConditional();
   simpleConditionalTrue();
@@ -19,10 +19,10 @@
 /// Simple conditional with unknown condition value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _simpleConditional:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditional:Union([exact=JSString], [exact=JSUInt31])*/
 _simpleConditional(/*[exact=JSBool]*/ c) => c ? '' : 0;
 
-/*element: simpleConditional:[null]*/
+/*member: simpleConditional:[null]*/
 simpleConditional() {
   _simpleConditional(true);
   _simpleConditional(false);
@@ -32,10 +32,10 @@
 /// Simple conditional with unknown condition value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _simpleConditionalTrue:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditionalTrue:Union([exact=JSString], [exact=JSUInt31])*/
 _simpleConditionalTrue(/*Value([exact=JSBool], value: true)*/ c) => c ? '' : 0;
 
-/*element: simpleConditionalTrue:[null]*/
+/*member: simpleConditionalTrue:[null]*/
 simpleConditionalTrue() {
   _simpleConditionalTrue(true);
 }
@@ -44,11 +44,11 @@
 /// Simple conditional with unknown condition value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _simpleConditionalFalse:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _simpleConditionalFalse:Union([exact=JSString], [exact=JSUInt31])*/
 _simpleConditionalFalse(/*Value([exact=JSBool], value: false)*/ c) =>
     c ? '' : 0;
 
-/*element: simpleConditionalFalse:[null]*/
+/*member: simpleConditionalFalse:[null]*/
 simpleConditionalFalse() {
   _simpleConditionalFalse(false);
 }
@@ -56,11 +56,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is test.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIs:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIs:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalIs(/*[null|exact=JSUInt31]*/ o) =>
     o is int ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
 
-/*element: conditionalIs:[null]*/
+/*member: conditionalIs:[null]*/
 conditionalIs() {
   _conditionalIs(null);
   _conditionalIs(1);
@@ -69,11 +69,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is `int` test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalIsInt(/*[exact=JSUInt31]*/ o) =>
     o is int ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
 
-/*element: conditionalIsInt:[null]*/
+/*member: conditionalIsInt:[null]*/
 conditionalIsInt() {
   _conditionalIsInt(1);
 }
@@ -81,11 +81,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is-not test.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsNot:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsNot:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalIsNot(/*[null|exact=JSUInt31]*/ o) =>
     o is! int ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
 
-/*element: conditionalIsNot:[null]*/
+/*member: conditionalIsNot:[null]*/
 conditionalIsNot() {
   _conditionalIsNot(null);
   _conditionalIsNot(1);
@@ -94,11 +94,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is-not `int` test known to be false.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalIsNotInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalIsNotInt:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalIsNotInt(/*[exact=JSUInt31]*/ o) =>
     o is! int ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
 
-/*element: conditionalIsNotInt:[null]*/
+/*member: conditionalIsNotInt:[null]*/
 conditionalIsNotInt() {
   _conditionalIsNotInt(1);
 }
@@ -106,11 +106,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is test.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalNull(/*[null|exact=JSUInt31]*/ o) =>
     o == null ? '' : o. /*invoke: [exact=JSUInt31]*/ abs();
 
-/*element: conditionalNull:[null]*/
+/*member: conditionalNull:[null]*/
 conditionalNull() {
   _conditionalNull(null);
   _conditionalNull(1);
@@ -119,11 +119,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Conditional with an is `int` test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _conditionalNotNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
+/*member: _conditionalNotNull:Union([exact=JSString], [subclass=JSPositiveInt])*/
 _conditionalNotNull(/*[null|exact=JSUInt31]*/ o) =>
     o != null ? o. /*invoke: [exact=JSUInt31]*/ abs() : '';
 
-/*element: conditionalNotNull:[null]*/
+/*member: conditionalNotNull:[null]*/
 conditionalNotNull() {
   _conditionalNotNull(null);
   _conditionalNotNull(1);
diff --git a/tests/compiler/dart2js/inference/data/const_closure.dart b/tests/compiler/dart2js/inference/data/const_closure.dart
index 8425f4d..551def4 100644
--- a/tests/compiler/dart2js/inference/data/const_closure.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure.dart
@@ -2,36 +2,36 @@
 // 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.
 
-/*element: method1:[exact=JSUInt31]*/
+/*member: method1:[exact=JSUInt31]*/
 method1() {
   return 42;
 }
 
-/*element: method2:[exact=JSUInt31]*/
+/*member: method2:[exact=JSUInt31]*/
 method2(/*[exact=JSUInt31]*/ a) {
   // Called only via [foo2] with a small integer.
   return a;
 }
 
-/*strong.element: foo1:[subclass=Closure]*/
-/*omit.element: foo1:[subclass=Closure]*/
+/*strong.member: foo1:[subclass=Closure]*/
+/*omit.member: foo1:[subclass=Closure]*/
 const foo1 = method1;
 
-/*strong.element: foo2:[subclass=Closure]*/
-/*omit.element: foo2:[subclass=Closure]*/
+/*strong.member: foo2:[subclass=Closure]*/
+/*omit.member: foo2:[subclass=Closure]*/
 const foo2 = method2;
 
-/*element: returnInt1:[null|subclass=Object]*/
+/*member: returnInt1:[null|subclass=Object]*/
 returnInt1() {
   return foo1();
 }
 
-/*element: returnInt2:[null|subclass=Object]*/
+/*member: returnInt2:[null|subclass=Object]*/
 returnInt2() {
   return foo2(54);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt1();
   returnInt2();
diff --git a/tests/compiler/dart2js/inference/data/const_closure2.dart b/tests/compiler/dart2js/inference/data/const_closure2.dart
index 207a431..2dc19f6 100644
--- a/tests/compiler/dart2js/inference/data/const_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure2.dart
@@ -2,22 +2,22 @@
 // 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.
 
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
 // Called via [foo] with integer then double.
 method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
   return a;
 }
 
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
-/*element: returnNum:[null|subclass=Object]*/
+/*member: returnNum:[null|subclass=Object]*/
 returnNum(/*Union([exact=JSDouble], [exact=JSUInt31])*/ x) {
   return foo(x);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnNum(10);
   returnNum(10.5);
diff --git a/tests/compiler/dart2js/inference/data/const_closure3.dart b/tests/compiler/dart2js/inference/data/const_closure3.dart
index 79a36f0..eb19bcb 100644
--- a/tests/compiler/dart2js/inference/data/const_closure3.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure3.dart
@@ -2,22 +2,22 @@
 // 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.
 
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
 // Called only via [foo2] with a small integer.
 method(/*[exact=JSUInt31]*/ a) {
   return a;
 }
 
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
 returnInt() {
   return foo(54);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt();
 }
diff --git a/tests/compiler/dart2js/inference/data/const_closure4.dart b/tests/compiler/dart2js/inference/data/const_closure4.dart
index 207a431..2dc19f6 100644
--- a/tests/compiler/dart2js/inference/data/const_closure4.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure4.dart
@@ -2,22 +2,22 @@
 // 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.
 
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
 // Called via [foo] with integer then double.
 method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
   return a;
 }
 
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
-/*element: returnNum:[null|subclass=Object]*/
+/*member: returnNum:[null|subclass=Object]*/
 returnNum(/*Union([exact=JSDouble], [exact=JSUInt31])*/ x) {
   return foo(x);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnNum(10);
   returnNum(10.5);
diff --git a/tests/compiler/dart2js/inference/data/const_closure5.dart b/tests/compiler/dart2js/inference/data/const_closure5.dart
index 89a3abf..57e976e 100644
--- a/tests/compiler/dart2js/inference/data/const_closure5.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure5.dart
@@ -2,22 +2,22 @@
 // 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.
 
-/*element: method:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: method:Union([exact=JSDouble], [exact=JSUInt31])*/
 // Called only via [foo2] with a small integer.
 method(/*Union([exact=JSDouble], [exact=JSUInt31])*/ a) {
   return a;
 }
 
-/*strong.element: foo:[subclass=Closure]*/
-/*omit.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[subclass=Closure]*/
+/*omit.member: foo:[subclass=Closure]*/
 const foo = method;
 
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
 returnInt() {
   return foo(54);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt();
   method(55.2);
diff --git a/tests/compiler/dart2js/inference/data/const_closure_default.dart b/tests/compiler/dart2js/inference/data/const_closure_default.dart
index 3217dcb..135ed2a 100644
--- a/tests/compiler/dart2js/inference/data/const_closure_default.dart
+++ b/tests/compiler/dart2js/inference/data/const_closure_default.dart
@@ -4,43 +4,43 @@
 
 // [defaultFn_i] is called only via [foo_i]'s default value with a small integer.
 
-/*element: defaultFn1:[exact=JSUInt31]*/
+/*member: defaultFn1:[exact=JSUInt31]*/
 defaultFn1(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: defaultFn2:[exact=JSUInt31]*/
+/*member: defaultFn2:[exact=JSUInt31]*/
 defaultFn2(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: defaultFn3:[exact=JSUInt31]*/
+/*member: defaultFn3:[exact=JSUInt31]*/
 defaultFn3(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: defaultFn4:[exact=JSUInt31]*/
+/*member: defaultFn4:[exact=JSUInt31]*/
 defaultFn4(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: defaultFn5:[exact=JSUInt31]*/
+/*member: defaultFn5:[exact=JSUInt31]*/
 defaultFn5(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: defaultFn6:[exact=JSUInt31]*/
+/*member: defaultFn6:[exact=JSUInt31]*/
 defaultFn6(/*[exact=JSUInt31]*/ a) => a;
 
-/*element: foo1:[null|subclass=Object]*/
+/*member: foo1:[null|subclass=Object]*/
 foo1([/*[subclass=Closure]*/ fn = defaultFn1]) => fn(54);
 
-/*element: foo2:[null|subclass=Object]*/
+/*member: foo2:[null|subclass=Object]*/
 foo2({/*[subclass=Closure]*/ fn: defaultFn2}) => fn(54);
 
-/*element: foo3:[null|subclass=Object]*/
+/*member: foo3:[null|subclass=Object]*/
 foo3([/*[subclass=Closure]*/ fn = defaultFn3]) => fn(54);
 
-/*element: foo4:[null|subclass=Object]*/
+/*member: foo4:[null|subclass=Object]*/
 foo4({/*[subclass=Closure]*/ fn: defaultFn4}) => fn(54);
 
-/*element: foo5:[null|subclass=Object]*/
+/*member: foo5:[null|subclass=Object]*/
 foo5([/*[null|subclass=Object]*/ fn = defaultFn5]) => fn(54);
 
-/*element: foo6:[null|subclass=Object]*/
+/*member: foo6:[null|subclass=Object]*/
 foo6({/*[null|subclass=Object]*/ fn: defaultFn6}) => fn(54);
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   // Direct calls.
   foo1();
diff --git a/tests/compiler/dart2js/inference/data/container_mask_equal.dart b/tests/compiler/dart2js/inference/data/container_mask_equal.dart
index be6deee..c4830df 100644
--- a/tests/compiler/dart2js/inference/data/container_mask_equal.dart
+++ b/tests/compiler/dart2js/inference/data/container_mask_equal.dart
@@ -7,25 +7,25 @@
 
 import 'dart:typed_data';
 
-/*element: method1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: method1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 method1() => [0];
 
-/*element: method2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
+/*member: method2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/
 method2() => [1, 2];
 
-/*element: method3:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 1)*/
+/*member: method3:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 1)*/
 method3() => new Uint8List(1);
 
-/*element: method4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 2)*/
+/*member: method4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 2)*/
 method4() => new Uint8List(2);
 
-/*element: method1or2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
+/*member: method1or2:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
 method1or2(/*[exact=JSBool]*/ c) => c ? method1() : method2();
 
-/*element: method3or4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: null)*/
+/*member: method3or4:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: null)*/
 method3or4(/*[exact=JSBool]*/ c) => c ? method3() : method4();
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   method1or2(true);
   method1or2(false);
diff --git a/tests/compiler/dart2js/inference/data/default_value.dart b/tests/compiler/dart2js/inference/data/default_value.dart
index e9d1b0c..b08d14f 100644
--- a/tests/compiler/dart2js/inference/data/default_value.dart
+++ b/tests/compiler/dart2js/inference/data/default_value.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   positionalWithoutDefaultOnLocal();
   positionalWithNullDefaultOnLocal();
@@ -12,35 +12,35 @@
   positionalWithOneDefaultOnStatic();
 }
 
-/*element: positionalWithoutDefaultOnLocal:[null]*/
+/*member: positionalWithoutDefaultOnLocal:[null]*/
 positionalWithoutDefaultOnLocal() {
   /*[null]*/ local([/*[null]*/ parameter]) => parameter;
   return local();
 }
 
-/*element: positionalWithNullDefaultOnLocal:[null]*/
+/*member: positionalWithNullDefaultOnLocal:[null]*/
 positionalWithNullDefaultOnLocal() {
   /*[null]*/ local([/*[null]*/ parameter = null]) => parameter;
   return local();
 }
 
-/*element: positionalWithOneDefaultOnLocal:[exact=JSUInt31]*/
+/*member: positionalWithOneDefaultOnLocal:[exact=JSUInt31]*/
 positionalWithOneDefaultOnLocal() {
   /*[exact=JSUInt31]*/ local([/*[exact=JSUInt31]*/ parameter = 1]) => parameter;
   return local();
 }
 
-/*element: positionalWithoutDefaultOnStatic:[null]*/
+/*member: positionalWithoutDefaultOnStatic:[null]*/
 positionalWithoutDefaultOnStatic([/*[null]*/ parameter]) {
   return parameter;
 }
 
-/*element: positionalWithNullDefaultOnStatic:[null]*/
+/*member: positionalWithNullDefaultOnStatic:[null]*/
 positionalWithNullDefaultOnStatic([/*[null]*/ parameter = null]) {
   return parameter;
 }
 
-/*element: positionalWithOneDefaultOnStatic:[exact=JSUInt31]*/
+/*member: positionalWithOneDefaultOnStatic:[exact=JSUInt31]*/
 positionalWithOneDefaultOnStatic([/*[exact=JSUInt31]*/ parameter = 1]) {
   return parameter;
 }
diff --git a/tests/compiler/dart2js/inference/data/deferred_load.dart b/tests/compiler/dart2js/inference/data/deferred_load.dart
index af34b6e..41ee085 100644
--- a/tests/compiler/dart2js/inference/data/deferred_load.dart
+++ b/tests/compiler/dart2js/inference/data/deferred_load.dart
@@ -4,10 +4,10 @@
 
 import 'package:expect/expect.dart' deferred as expect;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   callLoadLibrary();
 }
 
-/*element: callLoadLibrary:[null|subclass=Object]*/
+/*member: callLoadLibrary:[null|subclass=Object]*/
 callLoadLibrary() => expect.loadLibrary();
diff --git a/tests/compiler/dart2js/inference/data/deferred_load_get.dart b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
index e27bf13..1226ef8 100644
--- a/tests/compiler/dart2js/inference/data/deferred_load_get.dart
+++ b/tests/compiler/dart2js/inference/data/deferred_load_get.dart
@@ -6,12 +6,12 @@
 
 // Synthetic getter added by kernel.
 
-/*element: __loadLibrary_expect:[null|exact=_Future]*/
+/*member: __loadLibrary_expect:[null|exact=_Future]*/
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   tearOffLoadLibrary();
 }
 
-/*element: tearOffLoadLibrary:[subclass=Closure]*/
+/*member: tearOffLoadLibrary:[subclass=Closure]*/
 tearOffLoadLibrary() => expect.loadLibrary;
diff --git a/tests/compiler/dart2js/inference/data/dictionary_types.dart b/tests/compiler/dart2js/inference/data/dictionary_types.dart
index 84dc58c..c2ac48b 100644
--- a/tests/compiler/dart2js/inference/data/dictionary_types.dart
+++ b/tests/compiler/dart2js/inference/data/dictionary_types.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
@@ -11,7 +11,7 @@
   test5();
 }
 
-/*element: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dictionaryA1:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 dynamic dictionaryA1 = {
   'string': "aString",
   'int': 42,
@@ -19,7 +19,7 @@
   'list': []
 };
 
-/*element: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
+/*member: dictionaryB1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null), stringTwo: Value([null|exact=JSString], value: "anotherString"), intTwo: [null|exact=JSUInt31]})*/
 dynamic dictionaryB1 = {
   'string': "aString",
   'int': 42,
@@ -27,22 +27,22 @@
   'list': []
 };
 
-/*element: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
+/*member: otherDict1:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {stringTwo: Value([exact=JSString], value: "anotherString"), intTwo: [exact=JSUInt31]})*/
 dynamic otherDict1 = {'stringTwo': "anotherString", 'intTwo': 84};
 
-/*element: int1:[exact=JSUInt31]*/
+/*member: int1:[exact=JSUInt31]*/
 dynamic int1 = 0;
 
-/*element: anotherInt1:[exact=JSUInt31]*/
+/*member: anotherInt1:[exact=JSUInt31]*/
 dynamic anotherInt1 = 0;
 
-/*element: nullOrInt1:[null|exact=JSUInt31]*/
+/*member: nullOrInt1:[null|exact=JSUInt31]*/
 dynamic nullOrInt1 = 0;
 
-/*element: dynamic1:[null|subclass=Object]*/
+/*member: dynamic1:[null|subclass=Object]*/
 dynamic dynamic1 = 0;
 
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1() {
   dictionaryA1
       . /*invoke: Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
@@ -64,7 +64,7 @@
       ['intTwo'];
 }
 
-/*element: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryA2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionaryA2 = {
   'string': "aString",
   'int': 42,
@@ -72,19 +72,19 @@
   'list': []
 };
 
-/*element: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionaryB2:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), intTwo: [exact=JSUInt31], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionaryB2 = {'string': "aString", 'intTwo': 42, 'list': []};
 
-/*element: nullOrInt2:[null|exact=JSUInt31]*/
+/*member: nullOrInt2:[null|exact=JSUInt31]*/
 dynamic nullOrInt2 = 0;
 
-/*element: aString2:[exact=JSString]*/
+/*member: aString2:[exact=JSString]*/
 dynamic aString2 = "";
 
-/*element: doubleOrNull2:[null|exact=JSDouble]*/
+/*member: doubleOrNull2:[null|exact=JSDouble]*/
 dynamic doubleOrNull2 = 22.2;
 
-/*element: test2:[null]*/
+/*member: test2:[null]*/
 test2() {
   var union = dictionaryA2
           /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
@@ -102,36 +102,36 @@
       ['double'];
 }
 
-/*element: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
+/*member: dictionary3:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
 dynamic dictionary3 = {
   'string': "aString",
   'int': 42,
   'double': 21.5,
   'list': []
 };
-/*element: keyD3:Value([exact=JSString], value: "double")*/
+/*member: keyD3:Value([exact=JSString], value: "double")*/
 dynamic keyD3 = 'double';
 
-/*element: keyI3:Value([exact=JSString], value: "int")*/
+/*member: keyI3:Value([exact=JSString], value: "int")*/
 dynamic keyI3 = 'int';
 
-/*element: keyN3:Value([exact=JSString], value: "notFoundInMap")*/
+/*member: keyN3:Value([exact=JSString], value: "notFoundInMap")*/
 dynamic keyN3 = 'notFoundInMap';
 
-/*element: knownDouble3:[exact=JSDouble]*/
+/*member: knownDouble3:[exact=JSDouble]*/
 dynamic knownDouble3 = 42.2;
 
-/*element: intOrNull3:[null|exact=JSUInt31]*/
+/*member: intOrNull3:[null|exact=JSUInt31]*/
 dynamic intOrNull3 = dictionary3
     /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
     [keyI3];
 
-/*element: justNull3:[null]*/
+/*member: justNull3:[null]*/
 dynamic justNull3 = dictionary3
     /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
     [keyN3];
 
-/*element: test3:[null]*/
+/*member: test3:[null]*/
 test3() {
   knownDouble3 = dictionary3
       /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSDouble], [exact=JSExtendableArray], [exact=JSUInt31], [null|exact=JSString]), map: {string: Value([exact=JSString], value: "aString"), int: [exact=JSUInt31], double: [exact=JSDouble], list: Container([exact=JSExtendableArray], element: [empty], length: 0)})*/
@@ -141,9 +141,9 @@
 }
 
 class A4 {
-/*element: A4.:[exact=A4]*/
+/*member: A4.:[exact=A4]*/
   A4();
-/*element: A4.foo4:[exact=JSUInt31]*/
+/*member: A4.foo4:[exact=JSUInt31]*/
   foo4(
       /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
     return value /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ [
@@ -152,17 +152,17 @@
 }
 
 class B4 {
-/*element: B4.:[exact=B4]*/
+/*member: B4.:[exact=B4]*/
   B4();
 
-/*element: B4.foo4:[exact=JSUInt31]*/
+/*member: B4.foo4:[exact=JSUInt31]*/
   foo4(
       /*Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: Union([exact=JSUInt31], [null|exact=JSString]), map: {anInt: [exact=JSUInt31], aString: Value([exact=JSString], value: "theString")})*/ value) {
     return 0;
   }
 }
 
-/*element: test4:[null]*/
+/*member: test4:[null]*/
 test4() {
   var dictionary = {'anInt': 42, 'aString': "theString"};
   var it;
@@ -178,16 +178,16 @@
       2);
 }
 
-/*element: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: dict5:Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 dynamic dict5 = makeMap5([1, 2]);
 
-/*element: notInt5:[null|subclass=Object]*/
+/*member: notInt5:[null|subclass=Object]*/
 dynamic notInt5 = 0;
 
-/*element: alsoNotInt5:[null|subclass=Object]*/
+/*member: alsoNotInt5:[null|subclass=Object]*/
 dynamic alsoNotInt5 = 0;
 
-/*element: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
+/*member: makeMap5:Map([subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
 makeMap5(
     /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 2)*/ values) {
   return {
@@ -200,7 +200,7 @@
   };
 }
 
-/*element: test5:[null]*/
+/*member: test5:[null]*/
 test5() {
   dict5
       /*update: Map([null|subclass=JsLinkedHashMap], key: [null|subclass=Object], value: [null|subclass=Object])*/
diff --git a/tests/compiler/dart2js/inference/data/do.dart b/tests/compiler/dart2js/inference/data/do.dart
index 2c7da87..549d826 100644
--- a/tests/compiler/dart2js/inference/data/do.dart
+++ b/tests/compiler/dart2js/inference/data/do.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleDo();
   doNull();
@@ -16,7 +16,7 @@
 /// Simple int based do-while loop.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleDo:[null]*/
+/*member: simpleDo:[null]*/
 simpleDo() {
   var i = 0;
   do {
@@ -29,7 +29,7 @@
 /// Do-while loop with null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: doNull:[exact=JSString]*/
+/*member: doNull:[exact=JSString]*/
 doNull() {
   var o;
   do {
@@ -42,7 +42,7 @@
 /// Do-while loop with not-null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: doNotNull:[exact=JSString]*/
+/*member: doNotNull:[exact=JSString]*/
 doNotNull() {
   var o = '';
   do {
@@ -55,7 +55,7 @@
 /// Do-while loop with null test known to be false.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: doNullFalse:[exact=JSString]*/
+/*member: doNullFalse:[exact=JSString]*/
 doNullFalse() {
   var o = '';
   do {
@@ -68,7 +68,7 @@
 /// Do-while loop with not-null test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: doNotNullTrue:[exact=JSString]*/
+/*member: doNotNullTrue:[exact=JSString]*/
 doNotNullTrue() {
   var o = null;
   do {
@@ -81,19 +81,19 @@
 /// Do-while loop with not-null test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[null|exact=Class2]*/
+  /*member: Class1.field:[null|exact=Class2]*/
   var field;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[null|exact=Class1]*/
+  /*member: Class2.field:[null|exact=Class1]*/
   var field;
 }
 
-/*element: _doUnion:Union([null|exact=Class1], [null|exact=Class2])*/
+/*member: _doUnion:Union([null|exact=Class1], [null|exact=Class2])*/
 _doUnion(/*[exact=Class1]*/ o) {
   do {
     o = o. /*Union([exact=Class1], [null|exact=Class2])*/ field;
@@ -101,7 +101,7 @@
   return o;
 }
 
-/*element: doUnion:[null]*/
+/*member: doUnion:[null]*/
 doUnion() {
   var c1 = new Class1();
   var c2 = new Class2();
diff --git a/tests/compiler/dart2js/inference/data/enum.dart b/tests/compiler/dart2js/inference/data/enum.dart
index 79b6d84..5e93aea 100644
--- a/tests/compiler/dart2js/inference/data/enum.dart
+++ b/tests/compiler/dart2js/inference/data/enum.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   enumValue();
   enumIndex();
@@ -16,12 +16,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum1 {
-  /*strong.element: Enum1.a:[exact=Enum1]*/
-  /*omit.element: Enum1.a:[exact=Enum1]*/
+  /*strong.member: Enum1.a:[exact=Enum1]*/
+  /*omit.member: Enum1.a:[exact=Enum1]*/
   a,
 }
 
-/*element: enumValue:[exact=Enum1]*/
+/*member: enumValue:[exact=Enum1]*/
 enumValue() => Enum1.a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -29,12 +29,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum2 {
-  /*strong.element: Enum2.a:[exact=Enum2]*/
-  /*omit.element: Enum2.a:[exact=Enum2]*/
+  /*strong.member: Enum2.a:[exact=Enum2]*/
+  /*omit.member: Enum2.a:[exact=Enum2]*/
   a,
 }
 
-/*element: enumIndex:[exact=JSUInt31]*/
+/*member: enumIndex:[exact=JSUInt31]*/
 enumIndex() => Enum2.a. /*[exact=Enum2]*/ index;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -42,15 +42,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum3 {
-  /*strong.element: Enum3.a:[exact=Enum3]*/
-  /*omit.element: Enum3.a:[exact=Enum3]*/
+  /*strong.member: Enum3.a:[exact=Enum3]*/
+  /*omit.member: Enum3.a:[exact=Enum3]*/
   a,
-  /*strong.element: Enum3.b:[exact=Enum3]*/
-  /*omit.element: Enum3.b:[exact=Enum3]*/
+  /*strong.member: Enum3.b:[exact=Enum3]*/
+  /*omit.member: Enum3.b:[exact=Enum3]*/
   b,
 }
 
-/*element: enumValues:Container([exact=JSUnmodifiableArray], element: [exact=Enum3], length: 2)*/
+/*member: enumValues:Container([exact=JSUnmodifiableArray], element: [exact=Enum3], length: 2)*/
 enumValues() => Enum3.values;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -58,12 +58,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum4 {
-  /*strong.element: Enum4.a:[exact=Enum4]*/
-  /*omit.element: Enum4.a:[exact=Enum4]*/
+  /*strong.member: Enum4.a:[exact=Enum4]*/
+  /*omit.member: Enum4.a:[exact=Enum4]*/
   a,
 }
 
-/*element: enumToString1:Value([exact=JSString], value: "Enum4.a")*/
+/*member: enumToString1:Value([exact=JSString], value: "Enum4.a")*/
 enumToString1() {
   return Enum4.a. /*invoke: [exact=Enum4]*/ toString();
 }
@@ -73,15 +73,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 enum Enum5 {
-  /*strong.element: Enum5.a:[exact=Enum5]*/
-  /*omit.element: Enum5.a:[exact=Enum5]*/
+  /*strong.member: Enum5.a:[exact=Enum5]*/
+  /*omit.member: Enum5.a:[exact=Enum5]*/
   a,
-  /*strong.element: Enum5.b:[exact=Enum5]*/
-  /*omit.element: Enum5.b:[exact=Enum5]*/
+  /*strong.member: Enum5.b:[exact=Enum5]*/
+  /*omit.member: Enum5.b:[exact=Enum5]*/
   b,
 }
 
-/*element: enumToString2:[exact=JSString]*/
+/*member: enumToString2:[exact=JSString]*/
 enumToString2() {
   Enum5.b. /*invoke: [exact=Enum5]*/ toString();
   return Enum5.a. /*invoke: [exact=Enum5]*/ toString();
diff --git a/tests/compiler/dart2js/inference/data/expose_this.dart b/tests/compiler/dart2js/inference/data/expose_this.dart
index e888229..26a5d7a 100644
--- a/tests/compiler/dart2js/inference/data/expose_this.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   exposeThis1();
   exposeThis2();
@@ -17,23 +17,23 @@
 // Expose this through a top level method invocation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[null]*/
+/*member: _method1:[null]*/
 _method1(/*[exact=Class1]*/ o) {}
 
 class Class1 {
   // The inferred type of the field includes `null` because `this` has been
   // exposed before its initialization.
-  /*element: Class1.field:[null|exact=JSUInt31]*/
+  /*member: Class1.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1() {
     _method1(this);
     /*update: [exact=Class1]*/ field = 42;
   }
 }
 
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
 exposeThis1() => new Class1();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -41,20 +41,20 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field:[null|exact=JSUInt31]*/
+  /*member: Class2.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2() {
     /*invoke: [exact=Class2]*/ method();
     /*update: [exact=Class2]*/ field = 42;
   }
 
-  /*element: Class2.method:[null]*/
+  /*member: Class2.method:[null]*/
   method() {}
 }
 
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
 exposeThis2() => new Class2();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -62,38 +62,38 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.field:[exact=JSUInt31]*/
+  /*member: Class3.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   Class3() {
     this;
     /*update: [exact=Class3]*/ field = 42;
   }
 }
 
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
 exposeThis3() => new Class3();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Expose this through a static field assignment.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: field1:[null|exact=Class4]*/
+/*member: field1:[null|exact=Class4]*/
 var field1;
 
 class Class4 {
-  /*element: Class4.field:[null|exact=JSUInt31]*/
+  /*member: Class4.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4() {
     field1 = this;
     /*update: [exact=Class4]*/ field = 42;
   }
 }
 
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
 exposeThis4() => new Class4();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -101,17 +101,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class5 {
-  /*element: Class5.field:[null|exact=JSUInt31]*/
+  /*member: Class5.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class5.:[exact=Class5]*/
+  /*member: Class5.:[exact=Class5]*/
   Class5(/*[null]*/ o) {
     o. /*update: [null]*/ field5 = this;
     /*update: [exact=Class5]*/ field = 42;
   }
 }
 
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
 exposeThis5() => new Class5(null);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -119,10 +119,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class6 {
-  /*element: Class6.field:[null|exact=JSUInt31]*/
+  /*member: Class6.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class6.:[exact=Class6]*/
+  /*member: Class6.:[exact=Class6]*/
   Class6() {
     // ignore: UNUSED_LOCAL_VARIABLE
     var o;
@@ -131,7 +131,7 @@
   }
 }
 
-/*element: exposeThis6:[exact=Class6]*/
+/*member: exposeThis6:[exact=Class6]*/
 exposeThis6() => new Class6();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -139,10 +139,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class7 {
-  /*element: Class7.field:[null|exact=JSUInt31]*/
+  /*member: Class7.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class7.:[exact=Class7]*/
+  /*member: Class7.:[exact=Class7]*/
   Class7() {
     // ignore: UNUSED_LOCAL_VARIABLE
     var o = this;
@@ -150,5 +150,5 @@
   }
 }
 
-/*element: exposeThis7:[exact=Class7]*/
+/*member: exposeThis7:[exact=Class7]*/
 exposeThis7() => new Class7();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_closure.dart b/tests/compiler/dart2js/inference/data/expose_this_closure.dart
index 6619281..da43183 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_closure.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_closure.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   exposeThis1();
   exposeThis2();
@@ -17,18 +17,18 @@
 class Class1 {
   // The inferred type of the field does _not_ include `null` because `this`
   // is _not_ been exposed.
-  /*element: Class1.field1:[exact=JSUInt31]*/
+  /*member: Class1.field1:[exact=JSUInt31]*/
   var field1;
-  /*element: Class1.field2:[exact=JSUInt31]*/
+  /*member: Class1.field2:[exact=JSUInt31]*/
   var field2;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1()
       : field1 = 42,
         field2 = 87;
 }
 
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
 exposeThis1() => new Class1();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -36,19 +36,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field1:[exact=JSUInt31]*/
+  /*member: Class2.field1:[exact=JSUInt31]*/
   var field1;
-  /*element: Class2.field2:[exact=JSUInt31]*/
+  /*member: Class2.field2:[exact=JSUInt31]*/
   var field2;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2() {
     /*update: [exact=Class2]*/ field1 = 42;
     /*update: [exact=Class2]*/ field2 = 87;
   }
 }
 
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
 exposeThis2() => new Class2();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,12 +56,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4 {
-  /*element: Class4.field1:[exact=JSUInt31]*/
+  /*member: Class4.field1:[exact=JSUInt31]*/
   var field1;
-  /*element: Class4.field2:[exact=JSUInt31]*/
+  /*member: Class4.field2:[exact=JSUInt31]*/
   var field2;
 
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4()
       : field1 = 42,
         field2 = 87 {
@@ -71,7 +71,7 @@
   }
 }
 
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
 exposeThis4() => new Class4();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -79,12 +79,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class5 {
-  /*element: Class5.field1:[exact=JSUInt31]*/
+  /*member: Class5.field1:[exact=JSUInt31]*/
   var field1;
-  /*element: Class5.field2:[null|exact=JSUInt31]*/
+  /*member: Class5.field2:[null|exact=JSUInt31]*/
   var field2;
 
-  /*element: Class5.:[exact=Class5]*/
+  /*member: Class5.:[exact=Class5]*/
   Class5() {
     /*update: [exact=Class5]*/ field1 = 42;
     /*[exact=JSUInt31]*/ () {
@@ -94,5 +94,5 @@
   }
 }
 
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
 exposeThis5() => new Class5();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_field.dart b/tests/compiler/dart2js/inference/data/expose_this_field.dart
index 77b4c79..aa3b384 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_field.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_field.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   exposeThis1();
   exposeThis2();
@@ -20,16 +20,16 @@
 class Class1 {
   // The inferred type of the field does _not_ include `null` because it has
   // _not_ been read before its initialization.
-  /*element: Class1.field:[exact=JSUInt31]*/
+  /*member: Class1.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1() {
     /*update: [exact=Class1]*/ field = 42;
   }
 }
 
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
 exposeThis1() => new Class1();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -39,16 +39,16 @@
 class Class2 {
   // The inferred type of the field includes `null` because it has been read
   // before its initialization.
-  /*element: Class2.field:[null]*/
+  /*member: Class2.field:[null]*/
   var field;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2() {
     /*update: [exact=Class2]*/ field = /*[exact=Class2]*/ field;
   }
 }
 
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
 exposeThis2() => new Class2();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -56,17 +56,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.field:[null|exact=JSUInt31]*/
+  /*member: Class3.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   Class3() {
     /*update: [exact=Class3]*/ field = /*[exact=Class3]*/ field;
     /*update: [exact=Class3]*/ field = 42;
   }
 }
 
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
 exposeThis3() => new Class3();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -74,10 +74,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4 {
-  /*element: Class4.field:[null|exact=JSUInt31]*/
+  /*member: Class4.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4() {
     // ignore: UNUSED_LOCAL_VARIABLE
     var o = /*[exact=Class4]*/ field;
@@ -85,7 +85,7 @@
   }
 }
 
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
 exposeThis4() => new Class4();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -93,17 +93,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class5 {
-  /*element: Class5.field:[null|subclass=JSPositiveInt]*/
+  /*member: Class5.field:[null|subclass=JSPositiveInt]*/
   var field;
 
-  /*element: Class5.:[exact=Class5]*/
+  /*member: Class5.:[exact=Class5]*/
   Class5() {
     /*[exact=Class5]*/ /*update: [exact=Class5]*/ field /*invoke: [null|subclass=JSPositiveInt]*/ ++;
     /*update: [exact=Class5]*/ field = 42;
   }
 }
 
-/*element: exposeThis5:[exact=Class5]*/
+/*member: exposeThis5:[exact=Class5]*/
 exposeThis5() => new Class5();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -111,17 +111,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class6 {
-  /*element: Class6.field:[subclass=JSPositiveInt]*/
+  /*member: Class6.field:[subclass=JSPositiveInt]*/
   var field;
 
-  /*element: Class6.:[exact=Class6]*/
+  /*member: Class6.:[exact=Class6]*/
   Class6() {
     /*update: [exact=Class6]*/ field = 42;
     /*[exact=Class6]*/ /*update: [exact=Class6]*/ field /*invoke: [subclass=JSPositiveInt]*/ ++;
   }
 }
 
-/*element: exposeThis6:[exact=Class6]*/
+/*member: exposeThis6:[exact=Class6]*/
 exposeThis6() => new Class6();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -129,13 +129,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class7 {
-  /*element: Class7.field1:[null|exact=JSUInt31]*/
+  /*member: Class7.field1:[null|exact=JSUInt31]*/
   var field1;
 
-  /*element: Class7.field2:[null|exact=JSUInt31]*/
+  /*member: Class7.field2:[null|exact=JSUInt31]*/
   var field2;
 
-  /*element: Class7.:[exact=Class7]*/
+  /*member: Class7.:[exact=Class7]*/
   Class7() {
     // ignore: UNUSED_LOCAL_VARIABLE
     var o1 = /*[exact=Class7]*/ field1;
@@ -146,5 +146,5 @@
   }
 }
 
-/*element: exposeThis7:[exact=Class7]*/
+/*member: exposeThis7:[exact=Class7]*/
 exposeThis7() => new Class7();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_mask.dart b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
index 84feb4a..7dd84bb 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_mask.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
@@ -5,7 +5,7 @@
 /// Check that exposure of this is correctly restricted through the receiver
 /// mask.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   otherGetter();
   otherMethod();
@@ -23,24 +23,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.field1a:[exact=JSUInt31]*/
+  /*member: Class1.field1a:[exact=JSUInt31]*/
   var field1a;
-  /*element: Class1.field1b:[exact=JSUInt31]*/
+  /*member: Class1.field1b:[exact=JSUInt31]*/
   var field1b;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1() : field1a = 42 {
     /*update: [exact=Class1]*/ field1b = /*[exact=Class1]*/ field1a;
   }
 }
 
-/*element: OtherClass1.:[exact=OtherClass1]*/
+/*member: OtherClass1.:[exact=OtherClass1]*/
 class OtherClass1 {
-  /*element: OtherClass1.field1a:[null]*/
+  /*member: OtherClass1.field1a:[null]*/
   get field1a => null;
 }
 
-/*element: otherGetter:[null]*/
+/*member: otherGetter:[null]*/
 otherGetter() {
   new OtherClass1(). /*[exact=OtherClass1]*/ field1a;
   new Class1();
@@ -51,24 +51,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field2a:[exact=JSUInt31]*/
+  /*member: Class2.field2a:[exact=JSUInt31]*/
   var field2a;
-  /*element: Class2.field2b:[exact=JSUInt31]*/
+  /*member: Class2.field2b:[exact=JSUInt31]*/
   var field2b;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2() : field2a = 42 {
     /*update: [exact=Class2]*/ field2b = /*[exact=Class2]*/ field2a;
   }
 }
 
-/*element: OtherClass2.:[exact=OtherClass2]*/
+/*member: OtherClass2.:[exact=OtherClass2]*/
 class OtherClass2 {
-  /*element: OtherClass2.field2a:[null]*/
+  /*member: OtherClass2.field2a:[null]*/
   field2a() {}
 }
 
-/*element: otherMethod:[null]*/
+/*member: otherMethod:[null]*/
 otherMethod() {
   new OtherClass2(). /*[exact=OtherClass2]*/ field2a;
   new Class2();
@@ -79,24 +79,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.field3a:[exact=JSUInt31]*/
+  /*member: Class3.field3a:[exact=JSUInt31]*/
   var field3a;
-  /*element: Class3.field3b:[exact=JSUInt31]*/
+  /*member: Class3.field3b:[exact=JSUInt31]*/
   var field3b;
 
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   Class3() : field3a = 42 {
     /*update: [exact=Class3]*/ field3b = /*[exact=Class3]*/ field3a;
   }
 }
 
-/*element: OtherClass3.:[exact=OtherClass3]*/
+/*member: OtherClass3.:[exact=OtherClass3]*/
 class OtherClass3 {
-  /*element: OtherClass3.field3a:[null]*/
+  /*member: OtherClass3.field3a:[null]*/
   var field3a;
 }
 
-/*element: otherField:[null]*/
+/*member: otherField:[null]*/
 otherField() {
   new OtherClass3();
   new Class3();
@@ -106,25 +106,25 @@
 // Read a field when a field in the superclass has the same name.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: SuperClass5.:[exact=SuperClass5]*/
+/*member: SuperClass5.:[exact=SuperClass5]*/
 class SuperClass5 {
-  /*element: SuperClass5.field5a:[null]*/
+  /*member: SuperClass5.field5a:[null]*/
   var field5a;
 }
 
 class Class5 extends SuperClass5 {
-  /*element: Class5.field5a:[exact=JSUInt31]*/
+  /*member: Class5.field5a:[exact=JSUInt31]*/
   var field5a;
-  /*element: Class5.field5b:[exact=JSUInt31]*/
+  /*member: Class5.field5b:[exact=JSUInt31]*/
   var field5b;
 
-  /*element: Class5.:[exact=Class5]*/
+  /*member: Class5.:[exact=Class5]*/
   Class5() : field5a = 42 {
     /*update: [exact=Class5]*/ field5b = /*[exact=Class5]*/ field5a;
   }
 }
 
-/*element: superclassField:[null]*/
+/*member: superclassField:[null]*/
 superclassField() {
   new SuperClass5();
   new Class5();
@@ -135,26 +135,26 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4 {
-  /*element: Class4.field4a:[exact=JSUInt31]*/
+  /*member: Class4.field4a:[exact=JSUInt31]*/
   var field4a;
-  /*element: Class4.field4b:[null|exact=JSUInt31]*/
+  /*member: Class4.field4b:[null|exact=JSUInt31]*/
   var field4b;
 
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4() : field4a = 42 {
     /*update: [subclass=Class4]*/ field4b = /*[subclass=Class4]*/ field4a;
   }
 }
 
 class SubClass4 extends Class4 {
-  /*element: SubClass4.field4a:[null|exact=JSUInt31]*/
+  /*member: SubClass4.field4a:[null|exact=JSUInt31]*/
   var field4a;
 
-  /*element: SubClass4.:[exact=SubClass4]*/
+  /*member: SubClass4.:[exact=SubClass4]*/
   SubClass4() : field4a = 42;
 }
 
-/*element: subclassFieldRead:[null]*/
+/*member: subclassFieldRead:[null]*/
 subclassFieldRead() {
   new Class4();
   new SubClass4();
@@ -165,29 +165,29 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class6 {
-  /*element: Class6.field6a:[exact=JSUInt31]*/
+  /*member: Class6.field6a:[exact=JSUInt31]*/
   var field6a;
-  /*element: Class6.field6b:[null|exact=JSUInt31]*/
+  /*member: Class6.field6b:[null|exact=JSUInt31]*/
   var field6b;
 
-  /*element: Class6.:[exact=Class6]*/
+  /*member: Class6.:[exact=Class6]*/
   Class6() : field6a = 42 {
     /*update: [subclass=Class6]*/ field6b = /*[subclass=Class6]*/ field6a;
   }
 }
 
 class SubClass6 extends Class6 {
-  /*element: SubClass6.field6b:[exact=JSUInt31]*/
+  /*member: SubClass6.field6b:[exact=JSUInt31]*/
   var field6b;
 
-  /*element: SubClass6.:[exact=SubClass6]*/
+  /*member: SubClass6.:[exact=SubClass6]*/
   SubClass6() : field6b = 42;
 
-  /*element: SubClass6.access:[null|exact=JSUInt31]*/
+  /*member: SubClass6.access:[null|exact=JSUInt31]*/
   get access => super.field6b;
 }
 
-/*element: subclassFieldWrite:[null|exact=JSUInt31]*/
+/*member: subclassFieldWrite:[null|exact=JSUInt31]*/
 subclassFieldWrite() {
   new Class6();
   return new SubClass6(). /*[exact=SubClass6]*/ access;
@@ -199,32 +199,32 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class9 {
-  /*element: Class9.field9a:[exact=JSUInt31]*/
+  /*member: Class9.field9a:[exact=JSUInt31]*/
   var field9a;
-  /*element: Class9.field9b:[null|exact=JSUInt31]*/
+  /*member: Class9.field9b:[null|exact=JSUInt31]*/
   var field9b;
 
-  /*element: Class9.:[exact=Class9]*/
+  /*member: Class9.:[exact=Class9]*/
   Class9() : field9a = 42 {
     /*update: [subclass=Class9]*/ field9b = /*[subclass=Class9]*/ field9a;
   }
 }
 
 class SubClass9a extends Class9 {
-  /*element: SubClass9a.field9b:[exact=JSUInt31]*/
+  /*member: SubClass9a.field9b:[exact=JSUInt31]*/
   var field9b;
 
-  /*element: SubClass9a.:[exact=SubClass9a]*/
+  /*member: SubClass9a.:[exact=SubClass9a]*/
   SubClass9a() : field9b = 42;
 
-  /*element: SubClass9a.access:[null|exact=JSUInt31]*/
+  /*member: SubClass9a.access:[null|exact=JSUInt31]*/
   get access => super.field9b;
 }
 
-/*element: SubClass9b.:[exact=SubClass9b]*/
+/*member: SubClass9b.:[exact=SubClass9b]*/
 class SubClass9b extends Class9 {}
 
-/*element: subclassesFieldWrite:[null|exact=JSUInt31]*/
+/*member: subclassesFieldWrite:[null|exact=JSUInt31]*/
 subclassesFieldWrite() {
   new Class9();
   new SubClass9b();
@@ -236,26 +236,26 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class7 {
-  /*element: Class7.field7a:[exact=JSUInt31]*/
+  /*member: Class7.field7a:[exact=JSUInt31]*/
   var field7a;
-  /*element: Class7.field7b:[null]*/
+  /*member: Class7.field7b:[null]*/
   var field7b;
 
-  /*element: Class7.:[exact=Class7]*/
+  /*member: Class7.:[exact=Class7]*/
   Class7() : field7a = 42 {
     /*invoke: [subclass=Class7]*/ field7b(/*[subclass=Class7]*/ field7a);
   }
 }
 
 class SubClass7 extends Class7 {
-  /*element: SubClass7.field7b:[null|exact=JSUInt31]*/
+  /*member: SubClass7.field7b:[null|exact=JSUInt31]*/
   var field7b;
 
-  /*element: SubClass7.:[exact=SubClass7]*/
+  /*member: SubClass7.:[exact=SubClass7]*/
   SubClass7() : field7b = 42;
 }
 
-/*element: subclassFieldInvoke:[null]*/
+/*member: subclassFieldInvoke:[null]*/
 subclassFieldInvoke() {
   new Class7();
   new SubClass7();
@@ -266,10 +266,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class Class8 {
-  /*element: Class8.field8:[null|exact=JSUInt31]*/
+  /*member: Class8.field8:[null|exact=JSUInt31]*/
   var field8;
 
-  /*element: Class8.:[subclass=Class8]*/
+  /*member: Class8.:[subclass=Class8]*/
   Class8() {
     /*invoke: [subclass=Class8]*/ method8();
   }
@@ -277,21 +277,21 @@
   method8();
 }
 
-/*element: SubClass8a.:[exact=SubClass8a]*/
+/*member: SubClass8a.:[exact=SubClass8a]*/
 class SubClass8a extends Class8 {
-  /*element: SubClass8a.method8:[null]*/
+  /*member: SubClass8a.method8:[null]*/
   method8() {
     /*update: [exact=SubClass8a]*/ field8 = 42;
   }
 }
 
-/*element: SubClass8b.:[exact=SubClass8b]*/
+/*member: SubClass8b.:[exact=SubClass8b]*/
 class SubClass8b extends Class8 {
-  /*element: SubClass8b.method8:[null]*/
+  /*member: SubClass8b.method8:[null]*/
   method8() {}
 }
 
-/*element: subclassFieldSet:[null]*/
+/*member: subclassFieldSet:[null]*/
 subclassFieldSet() {
   new SubClass8a();
   new SubClass8b();
diff --git a/tests/compiler/dart2js/inference/data/expose_this_super.dart b/tests/compiler/dart2js/inference/data/expose_this_super.dart
index 85d3630..cb7b1cc 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_super.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_super.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   exposeThis1();
   exposeThis2();
@@ -14,98 +14,98 @@
 // Expose this through super invocation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super1.:[exact=Class1]*/
+/*member: Super1.:[exact=Class1]*/
 abstract class Super1 {
-  /*element: Super1.method:[null]*/
+  /*member: Super1.method:[null]*/
   method() {}
 }
 
 class Class1 extends Super1 {
   // The inferred type of the field includes `null` because `this` has been
   // exposed before its initialization.
-  /*element: Class1.field:[null|exact=JSUInt31]*/
+  /*member: Class1.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1() {
     super.method();
     /*update: [exact=Class1]*/ field = 42;
   }
 }
 
-/*element: exposeThis1:[exact=Class1]*/
+/*member: exposeThis1:[exact=Class1]*/
 exposeThis1() => new Class1();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Expose this through super access.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super2.:[exact=Class2]*/
+/*member: Super2.:[exact=Class2]*/
 abstract class Super2 {
-  /*element: Super2.getter:[null]*/
+  /*member: Super2.getter:[null]*/
   get getter => null;
 }
 
 class Class2 extends Super2 {
-  /*element: Class2.field:[null|exact=JSUInt31]*/
+  /*member: Class2.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2() {
     super.getter;
     /*update: [exact=Class2]*/ field = 42;
   }
 }
 
-/*element: exposeThis2:[exact=Class2]*/
+/*member: exposeThis2:[exact=Class2]*/
 exposeThis2() => new Class2();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Expose this through super access.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super3.:[exact=Class3]*/
+/*member: Super3.:[exact=Class3]*/
 abstract class Super3 {
   set setter(/*[null]*/ o) {}
 }
 
 class Class3 extends Super3 {
-  /*element: Class3.field:[null|exact=JSUInt31]*/
+  /*member: Class3.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   Class3() {
     super.setter = null;
     /*update: [exact=Class3]*/ field = 42;
   }
 }
 
-/*element: exposeThis3:[exact=Class3]*/
+/*member: exposeThis3:[exact=Class3]*/
 exposeThis3() => new Class3();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Expose this in the constructor of a super class.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: field4:[null|exact=Class4]*/
+/*member: field4:[null|exact=Class4]*/
 var field4;
 
 abstract class Super4 {
-  /*element: Super4.:[exact=Class4]*/
+  /*member: Super4.:[exact=Class4]*/
   Super4() {
     field4 = this;
   }
 }
 
 class Class4 extends Super4 {
-  /*element: Class4.field:[null|exact=JSUInt31]*/
+  /*member: Class4.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4() {
     /*update: [exact=Class4]*/ field = 42;
   }
 }
 
-/*element: exposeThis4:[exact=Class4]*/
+/*member: exposeThis4:[exact=Class4]*/
 exposeThis4() => new Class4();
diff --git a/tests/compiler/dart2js/inference/data/factory.dart b/tests/compiler/dart2js/inference/data/factory.dart
index 624a334..60a789c 100644
--- a/tests/compiler/dart2js/inference/data/factory.dart
+++ b/tests/compiler/dart2js/inference/data/factory.dart
@@ -3,33 +3,33 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.generative:[exact=A]*/
+  /*member: A.generative:[exact=A]*/
   A.generative();
 
   factory A.redirect() = B;
 
-  /*element: A.fact:[exact=C]*/
+  /*member: A.fact:[exact=C]*/
   factory A.fact() => new C();
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B implements A {}
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C implements A {}
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   createGenerative();
   createRedirecting();
   createFactory();
 }
 
-/*element: createGenerative:[exact=A]*/
+/*member: createGenerative:[exact=A]*/
 createGenerative() => new A.generative();
 
-/*element: createRedirecting:[exact=B]*/
+/*member: createRedirecting:[exact=B]*/
 createRedirecting() => new A.redirect();
 
-/*element: createFactory:[exact=C]*/
+/*member: createFactory:[exact=C]*/
 createFactory() => new A.fact();
diff --git a/tests/compiler/dart2js/inference/data/field_type.dart b/tests/compiler/dart2js/inference/data/field_type.dart
index d97d431..8e2800b 100644
--- a/tests/compiler/dart2js/inference/data/field_type.dart
+++ b/tests/compiler/dart2js/inference/data/field_type.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
@@ -38,59 +38,59 @@
   test30();
 }
 
-/*element: A1.:[exact=A1]*/
+/*member: A1.:[exact=A1]*/
 class A1 {
-  /*element: A1.f1:[null]*/
+  /*member: A1.f1:[null]*/
   int f1;
 }
 
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1() {
   new A1();
 }
 
-/*element: A2.:[exact=A2]*/
+/*member: A2.:[exact=A2]*/
 class A2 {
-  /*element: A2.f2a:[null]*/
+  /*member: A2.f2a:[null]*/
   int f2a;
 
-  /*element: A2.f2b:[exact=JSUInt31]*/
+  /*member: A2.f2b:[exact=JSUInt31]*/
   int f2b = 1;
 }
 
-/*element: test2:[null]*/
+/*member: test2:[null]*/
 test2() {
   new A2();
 }
 
 class A3 {
-  /*element: A3.f3a:[exact=JSUInt31]*/
+  /*member: A3.f3a:[exact=JSUInt31]*/
   int f3a;
 
-  /*element: A3.f3b:[null|exact=JSUInt31]*/
+  /*member: A3.f3b:[null|exact=JSUInt31]*/
   int f3b;
 
-  /*element: A3.:[exact=A3]*/
+  /*member: A3.:[exact=A3]*/
   A3() : f3a = 1;
 }
 
-/*element: test3:[null]*/
+/*member: test3:[null]*/
 test3() {
   new A3(). /*update: [exact=A3]*/ f3b = 2;
 }
 
 class A4 {
-  /*element: A4.f4a:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A4.f4a:Union([exact=JSString], [exact=JSUInt31])*/
   dynamic f4a;
 
-  /*element: A4.f4b:Value([null|exact=JSString], value: "a")*/
+  /*member: A4.f4b:Value([null|exact=JSString], value: "a")*/
   dynamic f4b;
 
-  /*element: A4.:[exact=A4]*/
+  /*member: A4.:[exact=A4]*/
   A4() : f4a = 1;
 }
 
-/*element: test4:[null]*/
+/*member: test4:[null]*/
 test4() {
   A4 a = new A4();
   a. /*update: [exact=A4]*/ f4a = "a";
@@ -98,13 +98,13 @@
 }
 
 class A5 {
-  /*element: A5.f5a:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A5.f5a:Union([exact=JSString], [exact=JSUInt31])*/
   dynamic f5a = 1;
 
-  /*element: A5.f5b:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A5.f5b:Union([exact=JSString], [exact=JSUInt31])*/
   dynamic f5b = 1;
 
-  /*element: A5.:[exact=A5]*/
+  /*member: A5.:[exact=A5]*/
   A5(/*[exact=JSBool]*/ x) {
     /*update: [exact=A5]*/ f5a = "1";
     if (x) {
@@ -115,20 +115,20 @@
   }
 }
 
-/*element: test5:[null]*/
+/*member: test5:[null]*/
 test5() {
   new A5(true);
   new A5(false);
 }
 
 class A6 {
-  /*element: A6.f6a:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A6.f6a:Union([exact=JSString], [exact=JSUInt31])*/
   dynamic f6a = 1;
 
-  /*element: A6.f6b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+  /*member: A6.f6b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
   dynamic f6b = 1;
 
-  /*element: A6.:[exact=A6]*/
+  /*member: A6.:[exact=A6]*/
   A6(/*[exact=JSBool]*/ x) {
     /*update: [exact=A6]*/ f6a = "1";
     if (x) {
@@ -144,20 +144,20 @@
   }
 }
 
-/*element: test6:[null]*/
+/*member: test6:[null]*/
 test6() {
   new A6(true);
   new A6(false);
 }
 
 class A7 {
-  /*element: A7.f7a:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+  /*member: A7.f7a:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
   dynamic f7a = 1;
 
-  /*element: A7.f7b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
+  /*member: A7.f7b:Union([exact=JSExtendableArray], [exact=JSString], [exact=JSUInt31])*/
   dynamic f7b = 1;
 
-  /*element: A7.:[exact=A7]*/
+  /*member: A7.:[exact=A7]*/
   A7(/*[exact=JSBool]*/ x) {
     /*update: [exact=A7]*/ f7a = "1";
     if (x) {
@@ -174,17 +174,17 @@
   }
 }
 
-/*element: test7:[null]*/
+/*member: test7:[null]*/
 test7() {
   new A7(true);
   new A7(false);
 }
 
 class A8 {
-  /*element: A8.f8:Value([null|exact=JSString], value: "1")*/
+  /*member: A8.f8:Value([null|exact=JSString], value: "1")*/
   dynamic f8;
 
-  /*element: A8.:[exact=A8]*/
+  /*member: A8.:[exact=A8]*/
   A8(/*[exact=JSBool]*/ x) {
     if (x) {
       /*update: [exact=A8]*/ f8 = "1";
@@ -192,17 +192,17 @@
   }
 }
 
-/*element: test8:[null]*/
+/*member: test8:[null]*/
 test8() {
   new A8(true);
   new A8(false);
 }
 
 class A9 {
-  /*element: A9.f9:Value([null|exact=JSString], value: "1")*/
+  /*member: A9.f9:Value([null|exact=JSString], value: "1")*/
   dynamic f9;
 
-  /*element: A9.:[exact=A9]*/
+  /*member: A9.:[exact=A9]*/
   A9(/*[exact=JSBool]*/ x) {
     if (x) {
     } else {
@@ -211,30 +211,30 @@
   }
 }
 
-/*element: test9:[null]*/
+/*member: test9:[null]*/
 test9() {
   new A9(true);
   new A9(false);
 }
 
 class A10 {
-  /*element: A10.f10:[exact=JSUInt31]*/
+  /*member: A10.f10:[exact=JSUInt31]*/
   int f10;
 
-  /*element: A10.:[exact=A10]*/
+  /*member: A10.:[exact=A10]*/
   A10() {
     /*update: [exact=A10]*/ f10 = 1;
   }
-  /*element: A10.m10:[subclass=JSUInt32]*/
+  /*member: A10.m10:[subclass=JSUInt32]*/
   m10() => /*[exact=A10]*/ f10 /*invoke: [exact=JSUInt31]*/ + 1;
 }
 
-/*element: f10:[null]*/
+/*member: f10:[null]*/
 void f10(/*[null]*/ x) {
   x. /*update: [null]*/ f10 = "2";
 }
 
-/*element: test10:[null]*/
+/*member: test10:[null]*/
 test10() {
   A10 a;
   f10(a);
@@ -242,86 +242,86 @@
   a. /*invoke: [exact=A10]*/ m10();
 }
 
-/*element: S11.:[exact=S11]*/
+/*member: S11.:[exact=S11]*/
 class S11 {
-  /*element: S11.fs11:[exact=JSUInt31]*/
+  /*member: S11.fs11:[exact=JSUInt31]*/
   int fs11 = 1;
 
-  /*element: S11.ms11:[null]*/
+  /*member: S11.ms11:[null]*/
   ms11() {
     /*update: [exact=A11]*/ fs11 = 1;
   }
 }
 
-/*element: A11.:[exact=A11]*/
+/*member: A11.:[exact=A11]*/
 class A11 extends S11 {
-  /*element: A11.m11:[null]*/
+  /*member: A11.m11:[null]*/
   m11() {
     /*invoke: [exact=A11]*/ ms11();
   }
 }
 
-/*element: test11:[null]*/
+/*member: test11:[null]*/
 test11() {
   A11 a = new A11();
   a. /*invoke: [exact=A11]*/ m11();
 }
 
 class S12 {
-  /*element: S12.fs12:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: S12.fs12:Union([exact=JSString], [exact=JSUInt31])*/
   dynamic fs12 = 1;
 
-  /*element: S12.:[exact=S12]*/
+  /*member: S12.:[exact=S12]*/
   S12() {
     /*update: [exact=A12]*/ fs12 = "2";
   }
 }
 
-/*element: A12.:[exact=A12]*/
+/*member: A12.:[exact=A12]*/
 class A12 extends S12 {}
 
-/*element: test12:[null]*/
+/*member: test12:[null]*/
 test12() {
   new A12();
 }
 
 class S13 {
-/*element: S13.fs13:[exact=JSUInt31]*/
+/*member: S13.fs13:[exact=JSUInt31]*/
   int fs13;
 
-  /*element: S13.:[exact=S13]*/
+  /*member: S13.:[exact=S13]*/
   S13() {
     /*update: [exact=A13]*/ fs13 = 1;
   }
 }
 
 class A13 extends S13 {
-  /*element: A13.:[exact=A13]*/
+  /*member: A13.:[exact=A13]*/
   A13() {
     /*update: [exact=A13]*/ fs13 = 1;
   }
 }
 
-/*element: test13:[null]*/
+/*member: test13:[null]*/
 test13() {
   new A13();
 }
 
 class A14 {
-  /*element: A14.f14:[exact=JSUInt31]*/
+  /*member: A14.f14:[exact=JSUInt31]*/
   var f14;
 
-  /*element: A14.:[exact=A14]*/
+  /*member: A14.:[exact=A14]*/
   A14() {
     /*update: [exact=A14]*/ f14 = 1;
   }
-  /*element: A14.other:[exact=A14]*/
+  /*member: A14.other:[exact=A14]*/
   A14.other() {
     /*update: [exact=A14]*/ f14 = 2;
   }
 }
 
-/*element: test14:[null]*/
+/*member: test14:[null]*/
 test14() {
   // ignore: unused_local_variable
   A14 a = new A14();
@@ -329,21 +329,21 @@
 }
 
 class A15 {
-  /*element: A15.f15:Union([exact=JSExtendableArray], [exact=JSString])*/
+  /*member: A15.f15:Union([exact=JSExtendableArray], [exact=JSString])*/
   var f15;
 
-  /*element: A15.:[exact=A15]*/
+  /*member: A15.:[exact=A15]*/
   A15() {
     /*update: [exact=A15]*/ f15 = "1";
   }
 
-  /*element: A15.other:[exact=A15]*/
+  /*member: A15.other:[exact=A15]*/
   A15.other() {
     /*update: [exact=A15]*/ f15 = new List();
   }
 }
 
-/*element: test15:[null]*/
+/*member: test15:[null]*/
 test15() {
   // ignore: unused_local_variable
   A15 a = new A15();
@@ -354,33 +354,33 @@
   // TODO(johnniwinther): Investigate why these include `null`. The ast version
   // didn't.
 
-  /*element: A16.f16:Union([exact=JSUInt31], [null|exact=JSString])*/
+  /*member: A16.f16:Union([exact=JSUInt31], [null|exact=JSString])*/
   var f16;
 
-  /*element: A16.:[exact=A16]*/
+  /*member: A16.:[exact=A16]*/
   A16() {
     /*update: [exact=A16]*/ f16 = "1";
   }
 
-  /*element: A16.other:[exact=A16]*/
+  /*member: A16.other:[exact=A16]*/
   A16.other() : f16 = 1 {}
 }
 
-/*element: test16:[null]*/
+/*member: test16:[null]*/
 test16() {
   // ignore: unused_local_variable
   A16 a = new A16();
   a = new A16.other();
 }
 
-/*element: g17:[exact=JSUInt31]*/
+/*member: g17:[exact=JSUInt31]*/
 g17([/*[exact=A17]*/ p]) => p. /*update: [exact=A17]*/ f17 = 1;
 
 class A17 {
-/*element: A17.f17:[null|exact=JSUInt31]*/
+/*member: A17.f17:[null|exact=JSUInt31]*/
   var f17;
 
-  /*element: A17.:[exact=A17]*/
+  /*member: A17.:[exact=A17]*/
   A17(/*[exact=JSBool]*/ x) {
     var a;
     if (x) {
@@ -392,23 +392,23 @@
   }
 }
 
-/*element: test17:[null]*/
+/*member: test17:[null]*/
 test17() {
   new A17(true);
   new A17(false);
 }
 
 class A18 {
-  /*element: A18.f18a:[exact=JSUInt31]*/
+  /*member: A18.f18a:[exact=JSUInt31]*/
   var f18a;
 
-  /*element: A18.f18b:Value([exact=JSString], value: "1")*/
+  /*member: A18.f18b:Value([exact=JSString], value: "1")*/
   var f18b;
 
-  /*element: A18.f18c:Union([exact=JSUInt31], [null|exact=A18])*/
+  /*member: A18.f18c:Union([exact=JSUInt31], [null|exact=A18])*/
   var f18c;
 
-  /*element: A18.:[exact=A18]*/
+  /*member: A18.:[exact=A18]*/
   A18(/*[exact=JSBool]*/ x) {
     /*update: [exact=A18]*/ f18a = 1;
     var a;
@@ -423,23 +423,23 @@
   }
 }
 
-/*element: test18:[null]*/
+/*member: test18:[null]*/
 test18() {
   new A18(true);
   new A18(false);
 }
 
 class A19 {
-  /*element: A19.f19a:[exact=JSUInt31]*/
+  /*member: A19.f19a:[exact=JSUInt31]*/
   var f19a;
 
-  /*element: A19.f19b:Value([exact=JSString], value: "1")*/
+  /*member: A19.f19b:Value([exact=JSString], value: "1")*/
   var f19b;
 
-  /*element: A19.f19c:Union([exact=JSUInt31], [null|exact=A19])*/
+  /*member: A19.f19c:Union([exact=JSUInt31], [null|exact=A19])*/
   var f19c;
 
-  /*element: A19.:[exact=A19]*/
+  /*member: A19.:[exact=A19]*/
   A19(/*[exact=JSBool]*/ x) {
     /*update: [exact=A19]*/ f19a = 1;
     var a;
@@ -455,17 +455,17 @@
   }
 }
 
-/*element: test19:[null]*/
+/*member: test19:[null]*/
 test19() {
   new A19(true);
   new A19(false);
 }
 
 class A20 {
-  /*element: A20.f20:[null]*/
+  /*member: A20.f20:[null]*/
   var f20;
 
-  /*element: A20.:[exact=A20]*/
+  /*member: A20.:[exact=A20]*/
   A20() {
     dynamic a = this;
     /*iterator: [exact=A20]*/
@@ -481,16 +481,16 @@
   bool moveNext() => false;
 }
 
-/*element: test20:[null]*/
+/*member: test20:[null]*/
 test20() {
   new A20();
 }
 
 class A20b extends Iterable implements Iterator {
-  /*element: A20b.f20b:[null|exact=JSUInt31]*/
+  /*member: A20b.f20b:[null|exact=JSUInt31]*/
   var f20b;
 
-  /*element: A20b.:[exact=A20b]*/
+  /*member: A20b.:[exact=A20b]*/
   A20b() {
     dynamic a = this;
     /*iterator: [exact=A20b]*/
@@ -499,29 +499,29 @@
     for (/*update: [exact=A20b]*/ f20b in a) {}
   }
 
-  /*element: A20b.iterator:[exact=A20b]*/
+  /*member: A20b.iterator:[exact=A20b]*/
   @override
   get iterator => this;
 
-  /*element: A20b.current:[exact=JSUInt31]*/
+  /*member: A20b.current:[exact=JSUInt31]*/
   @override
   get current => 42;
 
-  /*element: A20b.moveNext:Value([exact=JSBool], value: false)*/
+  /*member: A20b.moveNext:Value([exact=JSBool], value: false)*/
   @override
   bool moveNext() => false;
 }
 
-/*element: test20b:[null]*/
+/*member: test20b:[null]*/
 test20b() {
   new A20b();
 }
 
 class A21 {
-  /*element: A21.f21:[null|exact=JSUInt31]*/
+  /*member: A21.f21:[null|exact=JSUInt31]*/
   var f21;
 
-  /*element: A21.:[exact=A21]*/
+  /*member: A21.:[exact=A21]*/
   A21() {
     dynamic a = this;
     /*iterator: [exact=A21]*/
@@ -536,16 +536,16 @@
   get iterator => null;
 }
 
-/*element: test21:[null]*/
+/*member: test21:[null]*/
 test21() {
   new A21();
 }
 
 class A21b extends Iterable {
-  /*element: A21b.f21:[null|exact=JSUInt31]*/
+  /*member: A21b.f21:[null|exact=JSUInt31]*/
   var f21;
 
-  /*element: A21b.:[exact=A21b]*/
+  /*member: A21b.:[exact=A21b]*/
   A21b() {
     dynamic a = this;
     /*iterator: [exact=A21b]*/
@@ -557,27 +557,27 @@
     /*update: [exact=A21b]*/ f21 = 42;
   }
 
-  /*element: A21b.iterator:[null]*/
+  /*member: A21b.iterator:[null]*/
   @override
   get iterator => null;
 }
 
-/*element: test21b:[null]*/
+/*member: test21b:[null]*/
 test21b() {
   new A21b();
 }
 
 class A22 {
-  /*element: A22.f22a:[exact=JSUInt31]*/
+  /*member: A22.f22a:[exact=JSUInt31]*/
   var f22a;
 
-  /*element: A22.f22b:[exact=JSUInt31]*/
+  /*member: A22.f22b:[exact=JSUInt31]*/
   var f22b;
 
-  /*element: A22.f22c:Value([null|exact=JSString], value: "foo")*/
+  /*member: A22.f22c:Value([null|exact=JSString], value: "foo")*/
   var f22c;
 
-  /*element: A22.:[exact=A22]*/
+  /*member: A22.:[exact=A22]*/
   A22() {
     /*update: [exact=A22]*/ f22a = 42;
     /*update: [exact=A22]*/ f22b = /*[exact=A22]*/ f22a == null
@@ -587,25 +587,25 @@
   }
 }
 
-/*element: test22:[null]*/
+/*member: test22:[null]*/
 test22() {
   new A22();
 }
 
 class A23 {
-  /*element: A23.f23a:[null|exact=JSUInt31]*/
+  /*member: A23.f23a:[null|exact=JSUInt31]*/
   var f23a = 42;
 
-  /*element: A23.f23b:[null|exact=JSUInt31]*/
+  /*member: A23.f23b:[null|exact=JSUInt31]*/
   var f23b = 42;
 
-  /*element: A23.f23c:[null|exact=JSUInt31]*/
+  /*member: A23.f23c:[null|exact=JSUInt31]*/
   var f23c = 42;
 
-  /*element: A23.f23d:[null|exact=JSUInt31]*/
+  /*member: A23.f23d:[null|exact=JSUInt31]*/
   var f23d = 42;
 
-  /*element: A23.:[exact=A23]*/
+  /*member: A23.:[exact=A23]*/
   A23() {
     // Test string interpolation.
     '${/*update: [exact=A23]*/ f23a = null}';
@@ -620,31 +620,31 @@
   }
 }
 
-/*element: test23:[null]*/
+/*member: test23:[null]*/
 test23() {
   new A23();
 }
 
 class A24 {
-  /*element: A24.f24a:[subclass=JSPositiveInt]*/
+  /*member: A24.f24a:[subclass=JSPositiveInt]*/
   var f24a = 42;
 
-  /*element: A24.f24b:[subclass=JSPositiveInt]*/
+  /*member: A24.f24b:[subclass=JSPositiveInt]*/
   var f24b = 42;
 
-  /*element: A24.f24c:[exact=JSUInt31]*/
+  /*member: A24.f24c:[exact=JSUInt31]*/
   var f24c = 42;
 
-  /*element: A24.f24d:[exact=JSUInt31]*/
+  /*member: A24.f24d:[exact=JSUInt31]*/
   final f24d;
 
-  /*element: A24.f24e:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+  /*member: A24.f24e:Union([exact=JSUInt31], [null|exact=JSDouble])*/
   var f24e;
 
-/*element: A24.f24f:Value([null|exact=JSString], value: "foo")*/
+/*member: A24.f24f:Value([null|exact=JSString], value: "foo")*/
   var f24f = null;
 
-  /*element: A24.:[exact=A24]*/
+  /*member: A24.:[exact=A24]*/
   A24() : f24d = 42 {
     /*[subclass=A24]*/ /*update: [subclass=A24]*/ f24a
         /*invoke: [subclass=JSPositiveInt]*/ ++;
@@ -654,7 +654,7 @@
     this. /*update: [subclass=A24]*/ f24f = f24f;
   }
 
-  /*element: A24.foo:[exact=A24]*/
+  /*member: A24.foo:[exact=A24]*/
   A24.foo(/*[subclass=A24]*/ other)
       : f24c = other. /*[subclass=A24]*/ f24c,
         f24d = other. /*[subclass=A24]*/ f24d,
@@ -662,58 +662,58 @@
             . /*invoke: [subclass=A24]*/
             bar24();
 
-  /*element: A24.+:Value([exact=JSString], value: "foo")*/
+  /*member: A24.+:Value([exact=JSString], value: "foo")*/
   operator +(/*[empty]*/ other) => 'foo';
 
-  /*element: A24.bar24:[exact=JSDouble]*/
+  /*member: A24.bar24:[exact=JSDouble]*/
   bar24() => 42.5;
 }
 
-/*element: B24.:[exact=B24]*/
+/*member: B24.:[exact=B24]*/
 class B24 extends A24 {
-  /*element: B24.bar24:[exact=JSUInt31]*/
+  /*member: B24.bar24:[exact=JSUInt31]*/
   @override
   bar24() => 42;
 }
 
-/*element: test24:[null]*/
+/*member: test24:[null]*/
 test24() {
   new A24();
   new A24.foo(new A24());
   new A24.foo(new B24());
 }
 
-/*element: A25.:[exact=A25]*/
+/*member: A25.:[exact=A25]*/
 class A25 {
-  /*element: A25.f25:[exact=JSUInt31]*/
+  /*member: A25.f25:[exact=JSUInt31]*/
   var f25 = 42;
 }
 
-/*element: B25.:[exact=B25]*/
+/*member: B25.:[exact=B25]*/
 class B25 {
-  /*element: B25.f25:Value([exact=JSString], value: "42")*/
+  /*member: B25.f25:Value([exact=JSString], value: "42")*/
   var f25 = '42';
 }
 
-/*element: test25:[null]*/
+/*member: test25:[null]*/
 test25() {
   new B25();
   new A25(). /*update: [exact=A25]*/ f25 = new A25(). /*[exact=A25]*/ f25;
 }
 
-/*element: A26.:[exact=A26]*/
+/*member: A26.:[exact=A26]*/
 class A26 {
-  /*element: A26.f26:[subclass=JSPositiveInt]*/
+  /*member: A26.f26:[subclass=JSPositiveInt]*/
   var f26 = 42;
 }
 
-/*element: B26.:[exact=B26]*/
+/*member: B26.:[exact=B26]*/
 class B26 {
-  /*element: B26.f26:[exact=JSUInt31]*/
+  /*member: B26.f26:[exact=JSUInt31]*/
   var f26 = 54;
 }
 
-/*element: test26:[null]*/
+/*member: test26:[null]*/
 test26() {
   new A26(). /*update: [exact=A26]*/ f26 = <dynamic>[new B26(), new A26()]
               /*Container([exact=JSExtendableArray], element: Union([exact=A26], [exact=B26]), length: 2)*/
@@ -724,39 +724,39 @@
 }
 
 class A27 {
-  /*element: A27.f27a:[exact=JSUInt31]*/
+  /*member: A27.f27a:[exact=JSUInt31]*/
   var f27a;
 
-  /*element: A27.f27b:[null|exact=JSUInt31]*/
+  /*member: A27.f27b:[null|exact=JSUInt31]*/
   var f27b;
 
-  /*element: A27.:[exact=A27]*/
+  /*member: A27.:[exact=A27]*/
   A27() {
     this. /*update: [subclass=A27]*/ f27a = 42;
     this. /*update: [subclass=A27]*/ f27b = 42;
   }
 }
 
-/*element: B27.:[exact=B27]*/
+/*member: B27.:[exact=B27]*/
 class B27 extends A27 {
   @override
   set f27b(/*[exact=JSUInt31]*/ value) {}
 }
 
-/*element: test27:[null]*/
+/*member: test27:[null]*/
 test27() {
   new A27();
   new B27();
 }
 
 class A28 {
-  /*element: A28.f28a:[exact=JSUInt31]*/
+  /*member: A28.f28a:[exact=JSUInt31]*/
   var f28a;
 
-  /*element: A28.f28b:[null|exact=JSUInt31]*/
+  /*member: A28.f28b:[null|exact=JSUInt31]*/
   var f28b;
 
-  /*element: A28.:[exact=A28]*/
+  /*member: A28.:[exact=A28]*/
   A28(/*[exact=JSUInt31]*/ x) {
     this. /*update: [exact=A28]*/ f28a = x;
     if (x /*invoke: [exact=JSUInt31]*/ == 0) return;
@@ -764,20 +764,20 @@
   }
 }
 
-/*element: test28:[null]*/
+/*member: test28:[null]*/
 test28() {
   new A28(0);
   new A28(1);
 }
 
 class A29 {
-  /*element: A29.f29a:[exact=JSUInt31]*/
+  /*member: A29.f29a:[exact=JSUInt31]*/
   var f29a;
 
-  /*element: A29.f29b:[null|exact=JSUInt31]*/
+  /*member: A29.f29b:[null|exact=JSUInt31]*/
   var f29b;
 
-  /*element: A29.:[exact=A29]*/
+  /*member: A29.:[exact=A29]*/
   A29(/*[exact=JSUInt31]*/ x) {
     this. /*update: [exact=A29]*/ f29a = x;
     if (x /*invoke: [exact=JSUInt31]*/ == 0) {
@@ -788,23 +788,23 @@
   }
 }
 
-/*element: test29:[null]*/
+/*member: test29:[null]*/
 test29() {
   new A29(0);
   new A29(1);
 }
 
 class A30 {
-  /*element: A30.f30a:[exact=JSUInt31]*/
+  /*member: A30.f30a:[exact=JSUInt31]*/
   var f30a;
 
-  /*element: A30.f30b:[exact=JSUInt31]*/
+  /*member: A30.f30b:[exact=JSUInt31]*/
   var f30b;
 
-  /*element: A30.f30c:[null|exact=JSUInt31]*/
+  /*member: A30.f30c:[null|exact=JSUInt31]*/
   var f30c;
 
-  /*element: A30.:[exact=A30]*/
+  /*member: A30.:[exact=A30]*/
   A30(/*[exact=JSUInt31]*/ x) {
     this. /*update: [exact=A30]*/ f30a = x;
     if (x /*invoke: [exact=JSUInt31]*/ == 0) {
@@ -817,7 +817,7 @@
   }
 }
 
-/*element: test30:[null]*/
+/*member: test30:[null]*/
 test30() {
   new A30(0);
   new A30(1);
diff --git a/tests/compiler/dart2js/inference/data/fields.dart b/tests/compiler/dart2js/inference/data/fields.dart
index a5ee8d8..3fbf03a 100644
--- a/tests/compiler/dart2js/inference/data/fields.dart
+++ b/tests/compiler/dart2js/inference/data/fields.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   fieldGetUnset();
   fieldGetUnsetInitialized();
@@ -14,36 +14,36 @@
 /// Get an uninitialized field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  var /*element: Class1.field:[null]*/ field;
+  var /*member: Class1.field:[null]*/ field;
 }
 
-/*element: fieldGetUnset:[null]*/
+/*member: fieldGetUnset:[null]*/
 fieldGetUnset() => new Class1(). /*[exact=Class1]*/ field;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Get a field initialized to `null`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  var /*element: Class4.field:[null]*/ field = null;
+  var /*member: Class4.field:[null]*/ field = null;
 }
 
-/*element: fieldGetUnsetInitialized:[null]*/
+/*member: fieldGetUnsetInitialized:[null]*/
 fieldGetUnsetInitialized() => new Class4(). /*[exact=Class4]*/ field;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Set an uninitialized field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  var /*element: Class2.field:[null|exact=JSUInt31]*/ field;
+  var /*member: Class2.field:[null|exact=JSUInt31]*/ field;
 }
 
-/*element: fieldSet:[null]*/
+/*member: fieldSet:[null]*/
 fieldSet() {
   new Class2(). /*update: [exact=Class2]*/ field = 0;
 }
@@ -52,12 +52,12 @@
 /// Return the setting of an uninitialized field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  var /*element: Class3.field:[null|exact=JSUInt31]*/ field;
+  var /*member: Class3.field:[null|exact=JSUInt31]*/ field;
 }
 
-/*element: fieldSetReturn:[exact=JSUInt31]*/
+/*member: fieldSetReturn:[exact=JSUInt31]*/
 fieldSetReturn() {
   return new Class3(). /*update: [exact=Class3]*/ field = 0;
 }
diff --git a/tests/compiler/dart2js/inference/data/final_field.dart b/tests/compiler/dart2js/inference/data/final_field.dart
index 0a1c13e..c0558d0 100644
--- a/tests/compiler/dart2js/inference/data/final_field.dart
+++ b/tests/compiler/dart2js/inference/data/final_field.dart
@@ -3,40 +3,40 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.intField:[exact=JSUInt31]*/
+  /*member: A.intField:[exact=JSUInt31]*/
   final intField;
 
-  /*element: A.giveUpField1:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A.giveUpField1:Union([exact=JSString], [exact=JSUInt31])*/
   final giveUpField1;
 
-  /*element: A.giveUpField2:Union([exact=A], [exact=JSString])*/
+  /*member: A.giveUpField2:Union([exact=A], [exact=JSString])*/
   final giveUpField2;
 
-  /*element: A.fieldParameter:[exact=JSUInt31]*/
+  /*member: A.fieldParameter:[exact=JSUInt31]*/
   final fieldParameter;
 
-  /*element: A.:[exact=A]*/
+  /*member: A.:[exact=A]*/
   A()
       : intField = 42,
         giveUpField1 = 'foo',
         giveUpField2 = 'foo',
         fieldParameter = 54;
 
-  /*element: A.bar:[exact=A]*/
+  /*member: A.bar:[exact=A]*/
   A.bar()
       : intField = 54,
         giveUpField1 = 42,
         giveUpField2 = new A(),
         fieldParameter = 87;
 
-  /*element: A.foo:[exact=A]*/
+  /*member: A.foo:[exact=A]*/
   A.foo(this. /*[exact=JSUInt31]*/ fieldParameter)
       : intField = 87,
         giveUpField1 = 42,
         giveUpField2 = 'foo';
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new A();
   new A.bar();
diff --git a/tests/compiler/dart2js/inference/data/final_field2.dart b/tests/compiler/dart2js/inference/data/final_field2.dart
index 7b7a9aff..d4ee03f 100644
--- a/tests/compiler/dart2js/inference/data/final_field2.dart
+++ b/tests/compiler/dart2js/inference/data/final_field2.dart
@@ -6,13 +6,13 @@
 // inferring types for fields.
 
 class A {
-  /*element: A.intField:[exact=JSUInt31]*/
+  /*member: A.intField:[exact=JSUInt31]*/
   final intField;
 
-  /*element: A.stringField:Value([exact=JSString], value: "foo")*/
+  /*member: A.stringField:Value([exact=JSString], value: "foo")*/
   final stringField;
 
-  /*element: A.:[exact=A]*/
+  /*member: A.:[exact=A]*/
   A()
       : intField = 42,
         stringField = 'foo';
@@ -22,7 +22,7 @@
         stringField = 42;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new A();
 }
diff --git a/tests/compiler/dart2js/inference/data/final_field3.dart b/tests/compiler/dart2js/inference/data/final_field3.dart
index f39e555..87925cb 100644
--- a/tests/compiler/dart2js/inference/data/final_field3.dart
+++ b/tests/compiler/dart2js/inference/data/final_field3.dart
@@ -5,17 +5,17 @@
 // Test that we are analyzing field parameters correctly.
 
 class A {
-  /*element: A.dynamicField:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A.dynamicField:Union([exact=JSString], [exact=JSUInt31])*/
   final dynamicField;
 
-  /*element: A.:[exact=A]*/
+  /*member: A.:[exact=A]*/
   A() : dynamicField = 42;
 
-  /*element: A.bar:[exact=A]*/
+  /*member: A.bar:[exact=A]*/
   A.bar(this. /*Value([exact=JSString], value: "foo")*/ dynamicField);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new A();
   new A.bar('foo');
diff --git a/tests/compiler/dart2js/inference/data/finalized_type_variable.dart b/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
index 197852a..663a7fb 100644
--- a/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/inference/data/finalized_type_variable.dart
@@ -2,21 +2,21 @@
 // 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.
 
-/*element: AppView.:[subclass=AppView]*/
+/*member: AppView.:[subclass=AppView]*/
 abstract class AppView<T> {
-  /*element: AppView.ctx:Union([exact=CardComponent2], [null|exact=CardComponent])*/
+  /*member: AppView.ctx:Union([exact=CardComponent2], [null|exact=CardComponent])*/
   T ctx;
 }
 
-/*element: CardComponent.:[exact=CardComponent]*/
+/*member: CardComponent.:[exact=CardComponent]*/
 class CardComponent {
-  /*element: CardComponent.title:Value([null|exact=JSString], value: "foo")*/
+  /*member: CardComponent.title:Value([null|exact=JSString], value: "foo")*/
   String title;
 }
 
-/*element: ViewCardComponent.:[exact=ViewCardComponent]*/
+/*member: ViewCardComponent.:[exact=ViewCardComponent]*/
 class ViewCardComponent extends AppView<CardComponent> {
-  /*element: ViewCardComponent._title:Value([null|exact=JSString], value: "foo")*/
+  /*member: ViewCardComponent._title:Value([null|exact=JSString], value: "foo")*/
   var _title;
 
   @pragma('dart2js:noInline')
@@ -30,22 +30,22 @@
     }
   }
 
-  /*element: ViewCardComponent.checkBinding:Value([exact=JSBool], value: true)*/
+  /*member: ViewCardComponent.checkBinding:Value([exact=JSBool], value: true)*/
   checkBinding(
           /*Value([null|exact=JSString], value: "foo")*/ a,
           /*Value([exact=JSString], value: "foo")*/ b) =>
       true;
 }
 
-/*element: CardComponent2.:[exact=CardComponent2]*/
+/*member: CardComponent2.:[exact=CardComponent2]*/
 class CardComponent2 {
-  /*element: CardComponent2.title:Value([null|exact=JSString], value: "bar")*/
+  /*member: CardComponent2.title:Value([null|exact=JSString], value: "bar")*/
   String title;
 }
 
-/*element: ViewCardComponent2.:[exact=ViewCardComponent2]*/
+/*member: ViewCardComponent2.:[exact=ViewCardComponent2]*/
 class ViewCardComponent2 extends AppView<CardComponent2> {
-  /*element: ViewCardComponent2._title:Value([null|exact=JSString], value: "bar")*/
+  /*member: ViewCardComponent2._title:Value([null|exact=JSString], value: "bar")*/
   var _title;
 
   @pragma('dart2js:noInline')
@@ -59,14 +59,14 @@
     }
   }
 
-  /*element: ViewCardComponent2.checkBinding:Value([exact=JSBool], value: true)*/
+  /*member: ViewCardComponent2.checkBinding:Value([exact=JSBool], value: true)*/
   checkBinding(
           /*Value([null|exact=JSString], value: "bar")*/ a,
           /*Value([exact=JSString], value: "bar")*/ b) =>
       true;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   var c1 = new ViewCardComponent();
   c1. /*update: [exact=ViewCardComponent]*/ ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/inference/data/for.dart b/tests/compiler/dart2js/inference/data/for.dart
index c1f31a4..b3829b7 100644
--- a/tests/compiler/dart2js/inference/data/for.dart
+++ b/tests/compiler/dart2js/inference/data/for.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleFor();
   forNull();
@@ -18,7 +18,7 @@
 /// Simple int based for loop.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleFor:[null]*/
+/*member: simpleFor:[null]*/
 simpleFor() {
   for (var i = 0;
       i /*invoke: [subclass=JSPositiveInt]*/ < 10;
@@ -31,7 +31,7 @@
 /// For loop with null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forNull:[null]*/
+/*member: forNull:[null]*/
 forNull() {
   var local;
   for (var o; o == null; o = o. /*invoke: [null]*/ toString()) {
@@ -44,7 +44,7 @@
 /// For loop with not-null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forNotNull:[null|exact=JSString]*/
+/*member: forNotNull:[null|exact=JSString]*/
 forNotNull() {
   var local;
   for (var o = ''; o != null; o = o. /*invoke: [exact=JSString]*/ toString()) {
@@ -57,7 +57,7 @@
 /// For loop with null test known to be false.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forNullFalse:[null]*/
+/*member: forNullFalse:[null]*/
 forNullFalse() {
   var local;
   for (var o = ''; o == null; o = o. /*invoke: [null]*/ toString()) {
@@ -70,7 +70,7 @@
 /// For loop with not-null test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forNotNullTrue:[null]*/
+/*member: forNotNullTrue:[null]*/
 forNotNullTrue() {
   var local;
   for (var o = null; o != null; o = o. /*invoke: [empty]*/ toString()) {
@@ -83,19 +83,19 @@
 /// For loop with not-null test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[null|exact=Class2]*/
+  /*member: Class1.field:[null|exact=Class2]*/
   var field;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[null|exact=Class1]*/
+  /*member: Class2.field:[null|exact=Class1]*/
   var field;
 }
 
-/*element: _forUnion:Union([exact=Class1], [null|exact=Class2])*/
+/*member: _forUnion:Union([exact=Class1], [null|exact=Class2])*/
 _forUnion(/*[exact=Class1]*/ o) {
   for (;
       o = o. /*Union([exact=Class1], [null|exact=Class2])*/ field;
@@ -103,7 +103,7 @@
   return o;
 }
 
-/*element: forUnion:[null]*/
+/*member: forUnion:[null]*/
 forUnion() {
   var c1 = new Class1();
   var c2 = new Class2();
@@ -116,25 +116,25 @@
 /// For loop with is test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.field:[null|exact=Class4]*/
+  /*member: Class3.field:[null|exact=Class4]*/
   var field;
 }
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field:[null|exact=Class3]*/
+  /*member: Class4.field:[null|exact=Class3]*/
   var field;
 }
 
-/*element: _forIs:Union([exact=Class3], [null|exact=Class4])*/
+/*member: _forIs:Union([exact=Class3], [null|exact=Class4])*/
 _forIs(/*[exact=Class3]*/ o) {
   for (; o is Class3; o = o. /*[exact=Class3]*/ field) {}
   return o;
 }
 
-/*element: forIs:[null]*/
+/*member: forIs:[null]*/
 forIs() {
   var c1 = new Class3();
   var c2 = new Class4();
@@ -147,19 +147,19 @@
 /// For loop with is-not test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
 class Class5 {
-  /*element: Class5.field:[null|exact=Class6]*/
+  /*member: Class5.field:[null|exact=Class6]*/
   var field;
 }
 
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
 class Class6 {
-  /*element: Class6.field:[null|exact=Class5]*/
+  /*member: Class6.field:[null|exact=Class5]*/
   var field;
 }
 
-/*element: _forIsNot:Union([exact=Class5], [null|exact=Class6])*/
+/*member: _forIsNot:Union([exact=Class5], [null|exact=Class6])*/
 _forIsNot(/*[exact=Class5]*/ o) {
   for (;
       o is! Class6;
@@ -167,7 +167,7 @@
   return o;
 }
 
-/*element: forIsNot:[null]*/
+/*member: forIsNot:[null]*/
 forIsNot() {
   var c1 = new Class5();
   var c2 = new Class6();
diff --git a/tests/compiler/dart2js/inference/data/for_in.dart b/tests/compiler/dart2js/inference/data/for_in.dart
index c622275..301bcf7 100644
--- a/tests/compiler/dart2js/inference/data/for_in.dart
+++ b/tests/compiler/dart2js/inference/data/for_in.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   forInDirect();
   forInReturn();
@@ -14,7 +14,7 @@
 // For-in loop directly on a list literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forInDirect:[null]*/
+/*member: forInDirect:[null]*/
 forInDirect() {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
   /*current: [exact=ArrayIterator]*/
@@ -28,7 +28,7 @@
 // Return element from a for-in loop on a list literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forInReturn:[null|subclass=JSInt]*/
+/*member: forInReturn:[null|subclass=JSInt]*/
 forInReturn() {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
   /*current: [exact=ArrayIterator]*/
@@ -43,7 +43,7 @@
 // Return element from a for-in loop on known list type.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forInReturn:[null|subclass=Object]*/
+/*member: _forInReturn:[null|subclass=Object]*/
 _forInReturn(
     /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/ list) {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
@@ -55,7 +55,7 @@
   }
 }
 
-/*element: forInReturnMulti:[null]*/
+/*member: forInReturnMulti:[null]*/
 forInReturnMulti() {
   _forInReturn([1, 2]);
   _forInReturn([1, 2, 3]);
@@ -66,7 +66,7 @@
 // loop on known list type.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: forInReturnNonNull:[subclass=JSInt]*/
+/*member: forInReturnNonNull:[subclass=JSInt]*/
 forInReturnNonNull() {
   /*iterator: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
   /*current: [exact=ArrayIterator]*/
diff --git a/tests/compiler/dart2js/inference/data/foreign.dart b/tests/compiler/dart2js/inference/data/foreign.dart
index 525c027..8c07276 100644
--- a/tests/compiler/dart2js/inference/data/foreign.dart
+++ b/tests/compiler/dart2js/inference/data/foreign.dart
@@ -11,7 +11,7 @@
 /// ignore: IMPORT_INTERNAL_LIBRARY, UNUSED_IMPORT
 import 'dart:_interceptors';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   jsCallInt();
   jsCallEmpty();
@@ -28,35 +28,35 @@
   jsGetStaticState();
 }
 
-/*element: jsCallEmpty:[null|subclass=Object]*/
+/*member: jsCallEmpty:[null|subclass=Object]*/
 jsCallEmpty() => JS('', '#', 0);
 
-/*element: jsCallInt:[subclass=JSInt]*/
+/*member: jsCallInt:[subclass=JSInt]*/
 jsCallInt() => JS('int', '#', 0);
 
-/*element: jsCallVoid:[null|subclass=Object]*/
+/*member: jsCallVoid:[null|subclass=Object]*/
 jsCallVoid() => JS('void', '#', 0);
 
-/*element: jsCallUnion:Union([exact=JSString], [subclass=JSInt])*/
+/*member: jsCallUnion:Union([exact=JSString], [subclass=JSInt])*/
 jsCallUnion() => JS('int|String', '#', 0);
 
-/*element: jsBuiltin_rawRtiToJsConstructorName:[exact=JSString]*/
+/*member: jsBuiltin_rawRtiToJsConstructorName:[exact=JSString]*/
 jsBuiltin_rawRtiToJsConstructorName() {
   return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
 }
 
-/*element: jsEmbeddedGlobal_getTypeFromName:[null|subclass=Object]*/
+/*member: jsEmbeddedGlobal_getTypeFromName:[null|subclass=Object]*/
 jsEmbeddedGlobal_getTypeFromName() {
   return JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
 }
 
-/*element: jsEmbeddedGlobal_libraries:[null|exact=JSExtendableArray]*/
+/*member: jsEmbeddedGlobal_libraries:[null|exact=JSExtendableArray]*/
 jsEmbeddedGlobal_libraries() {
   return JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
 }
 
-/*element: jsStringConcat:[exact=JSString]*/
+/*member: jsStringConcat:[exact=JSString]*/
 jsStringConcat() => JS_STRING_CONCAT('a', 'b');
 
-/*element: jsGetStaticState:[null|subclass=Object]*/
+/*member: jsGetStaticState:[null|subclass=Object]*/
 jsGetStaticState() => JS_GET_STATIC_STATE();
diff --git a/tests/compiler/dart2js/inference/data/general.dart b/tests/compiler/dart2js/inference/data/general.dart
index a00c12b..678911c 100644
--- a/tests/compiler/dart2js/inference/data/general.dart
+++ b/tests/compiler/dart2js/inference/data/general.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum1:Union([exact=JSDouble], [exact=JSUInt31])*/
 returnNum1(/*Value([exact=JSBool], value: true)*/ a) {
   if (a)
     return 1;
@@ -10,7 +10,7 @@
     return 2.5;
 }
 
-/*element: returnNum2:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: returnNum2:Union([exact=JSDouble], [exact=JSUInt31])*/
 returnNum2(/*Value([exact=JSBool], value: true)*/ a) {
   if (a)
     return 1.4;
@@ -18,7 +18,7 @@
     return 2;
 }
 
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
 returnInt1(/*Value([exact=JSBool], value: true)*/ a) {
   if (a)
     return 1;
@@ -26,7 +26,7 @@
     return 2;
 }
 
-/*element: returnDouble:[exact=JSDouble]*/
+/*member: returnDouble:[exact=JSDouble]*/
 returnDouble(/*Value([exact=JSBool], value: true)*/ a) {
   if (a)
     return 1.5;
@@ -34,7 +34,7 @@
     return 2.5;
 }
 
-/*element: returnGiveUp:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnGiveUp:Union([exact=JSString], [exact=JSUInt31])*/
 returnGiveUp(/*Value([exact=JSBool], value: true)*/ a) {
   if (a)
     return 1;
@@ -42,66 +42,66 @@
     return 'foo';
 }
 
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
 returnInt2() {
   var a = 42;
   return a /*invoke: [exact=JSUInt31]*/ ++;
 }
 
-/*element: returnInt5:[subclass=JSUInt32]*/
+/*member: returnInt5:[subclass=JSUInt32]*/
 returnInt5() {
   var a = 42;
   return /*invoke: [exact=JSUInt31]*/ ++a;
 }
 
-/*element: returnInt6:[subclass=JSUInt32]*/
+/*member: returnInt6:[subclass=JSUInt32]*/
 returnInt6() {
   var a = 42;
   a /*invoke: [exact=JSUInt31]*/ ++;
   return a;
 }
 
-/*element: returnIntOrNull:[null|exact=JSUInt31]*/
+/*member: returnIntOrNull:[null|exact=JSUInt31]*/
 returnIntOrNull(/*Value([exact=JSBool], value: true)*/ a) {
   if (a) return 42;
 }
 
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
 returnInt3(/*Value([exact=JSBool], value: true)*/ a) {
   if (a) return 42;
   throw 42;
 }
 
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
 returnInt4() {
   return (42);
 }
 
-/*element: returnInt7:[subclass=JSPositiveInt]*/
+/*member: returnInt7:[subclass=JSPositiveInt]*/
 returnInt7() {
   return 42. /*invoke: [exact=JSUInt31]*/ abs();
 }
 
-/*element: returnInt8:[subclass=JSPositiveInt]*/
+/*member: returnInt8:[subclass=JSPositiveInt]*/
 returnInt8() {
   return 42. /*invoke: [exact=JSUInt31]*/ remainder(54);
 }
 
-/*element: returnEmpty1:[empty]*/
+/*member: returnEmpty1:[empty]*/
 returnEmpty1() {
   // Ensure that we don't intrisify a wrong call to [int.remainder].
   dynamic a = 42;
   return a. /*invoke: [exact=JSUInt31]*/ remainder();
 }
 
-/*element: returnEmpty2:[empty]*/
+/*member: returnEmpty2:[empty]*/
 returnEmpty2() {
   // Ensure that we don't intrisify a wrong call to [int.abs].
   dynamic a = 42;
   return a. /*invoke: [exact=JSUInt31]*/ abs(42);
 }
 
-/*element: testIsCheck1:[subclass=JSInt]*/
+/*member: testIsCheck1:[subclass=JSInt]*/
 testIsCheck1(/*[null|subclass=Object]*/ a) {
   if (a is int) {
     return a;
@@ -110,7 +110,7 @@
   }
 }
 
-/*element: testIsCheck2:[subclass=JSInt]*/
+/*member: testIsCheck2:[subclass=JSInt]*/
 testIsCheck2(/*[null|subclass=Object]*/ a) {
   if (a is! int) {
     return 0;
@@ -119,7 +119,7 @@
   }
 }
 
-/*element: testIsCheck3:[null|subclass=JSInt]*/
+/*member: testIsCheck3:[null|subclass=JSInt]*/
 testIsCheck3(/*[null|subclass=Object]*/ a) {
   if (a is! int) {
     print('hello');
@@ -128,7 +128,7 @@
   }
 }
 
-/*element: testIsCheck4:[subclass=JSInt]*/
+/*member: testIsCheck4:[subclass=JSInt]*/
 testIsCheck4(/*[null|subclass=Object]*/ a) {
   if (a is int) {
     return a;
@@ -137,7 +137,7 @@
   }
 }
 
-/*element: testIsCheck5:[subclass=JSInt]*/
+/*member: testIsCheck5:[subclass=JSInt]*/
 testIsCheck5(/*[null|subclass=Object]*/ a) {
   if (a is! int) {
     return 42;
@@ -146,7 +146,7 @@
   }
 }
 
-/*element: testIsCheck6:[null|subclass=Object]*/
+/*member: testIsCheck6:[null|subclass=Object]*/
 testIsCheck6(/*[null|subclass=Object]*/ a) {
   if (a is! int) {
     return a;
@@ -155,7 +155,7 @@
   }
 }
 
-/*element: testIsCheck7:[subclass=JSInt]*/
+/*member: testIsCheck7:[subclass=JSInt]*/
 testIsCheck7(/*[null|subclass=Object]*/ a) {
   if (a == 'foo' && a is int) {
     return a;
@@ -164,7 +164,7 @@
   }
 }
 
-/*element: testIsCheck8:[null|subclass=Object]*/
+/*member: testIsCheck8:[null|subclass=Object]*/
 testIsCheck8(/*[null|subclass=Object]*/ a) {
   if (a == 'foo' || a is int) {
     return a;
@@ -173,27 +173,27 @@
   }
 }
 
-/*element: testIsCheck9:[subclass=JSInt]*/
+/*member: testIsCheck9:[subclass=JSInt]*/
 testIsCheck9(/*[null|subclass=Object]*/ a) {
   return a is int ? a : 42;
 }
 
-/*element: testIsCheck10:[null|subclass=Object]*/
+/*member: testIsCheck10:[null|subclass=Object]*/
 testIsCheck10(/*[null|subclass=Object]*/ a) {
   return a is! int ? a : 42;
 }
 
-/*element: testIsCheck11:[subclass=JSInt]*/
+/*member: testIsCheck11:[subclass=JSInt]*/
 testIsCheck11(/*[null|subclass=Object]*/ a) {
   return a is! int ? 42 : a;
 }
 
-/*element: testIsCheck12:[null|subclass=Object]*/
+/*member: testIsCheck12:[null|subclass=Object]*/
 testIsCheck12(/*[null|subclass=Object]*/ a) {
   return a is int ? 42 : a;
 }
 
-/*element: testIsCheck13:[subclass=JSInt]*/
+/*member: testIsCheck13:[subclass=JSInt]*/
 testIsCheck13(/*[null|subclass=Object]*/ a) {
   while (a is int) {
     return a;
@@ -201,7 +201,7 @@
   return 42;
 }
 
-/*element: testIsCheck14:[null|subclass=Object]*/
+/*member: testIsCheck14:[null|subclass=Object]*/
 testIsCheck14(/*[null|subclass=Object]*/ a) {
   while (a is! int) {
     return 42;
@@ -210,7 +210,7 @@
 }
 
 // TODO(29309): Change to [subclass=JSInt] when 29309 is fixed.
-/*element: testIsCheck15:[null|subclass=Object]*/
+/*member: testIsCheck15:[null|subclass=Object]*/
 testIsCheck15(/*[null|subclass=Object]*/ a) {
   dynamic c = 42;
   do {
@@ -220,7 +220,7 @@
   return 42;
 }
 
-/*element: testIsCheck16:[null|subclass=Object]*/
+/*member: testIsCheck16:[null|subclass=Object]*/
 testIsCheck16(/*[null|subclass=Object]*/ a) {
   dynamic c = 42;
   do {
@@ -230,7 +230,7 @@
   return 42;
 }
 
-/*element: testIsCheck17:[subclass=JSInt]*/
+/*member: testIsCheck17:[subclass=JSInt]*/
 testIsCheck17(/*[null|subclass=Object]*/ a) {
   dynamic c = 42;
   for (; c is int;) {
@@ -240,7 +240,7 @@
   return 42;
 }
 
-/*element: testIsCheck18:[null|subclass=Object]*/
+/*member: testIsCheck18:[null|subclass=Object]*/
 testIsCheck18(/*[null|subclass=Object]*/ a) {
   dynamic c = 42;
   for (; c is int;) {
@@ -250,7 +250,7 @@
   return c;
 }
 
-/*element: testIsCheck19:[null|subclass=Object]*/
+/*member: testIsCheck19:[null|subclass=Object]*/
 testIsCheck19(/*[null|subclass=Object]*/ a) {
   dynamic c = 42;
   for (; c is! int;) {
@@ -260,7 +260,7 @@
   return 42;
 }
 
-/*element: testIsCheck20:[exact=JSUInt31]*/
+/*member: testIsCheck20:[exact=JSUInt31]*/
 testIsCheck20() {
   var c = topLevelGetter();
   if (c != null && c is! bool && c is! int) {
@@ -272,7 +272,7 @@
   }
 }
 
-/*element: testIsCheck21:Union([subclass=JSArray], [subclass=JSInt])*/
+/*member: testIsCheck21:Union([subclass=JSArray], [subclass=JSInt])*/
 testIsCheck21(/*[null|subclass=Object]*/ a) {
   if (a is int || a is List) {
     return a;
@@ -281,30 +281,30 @@
   }
 }
 
-/*element: testIsCheck22:Union([subclass=JSArray], [subclass=JSInt])*/
+/*member: testIsCheck22:Union([subclass=JSArray], [subclass=JSInt])*/
 testIsCheck22(/*[null|subclass=Object]*/ a) {
   return (a is int || a is List) ? a : 42;
 }
 
-/*element: testIsCheck23:[subclass=JSInt]*/
+/*member: testIsCheck23:[subclass=JSInt]*/
 testIsCheck23(/*[null|subclass=Object]*/ a) {
   if (a is! int) throw 'foo';
   return a;
 }
 
-/*element: testIsCheck24:[subclass=JSInt]*/
+/*member: testIsCheck24:[subclass=JSInt]*/
 testIsCheck24(/*[null|subclass=Object]*/ a) {
   if (a is! int) return 42;
   return a;
 }
 
-/*element: testIsCheck25:[null|subclass=Object]*/
+/*member: testIsCheck25:[null|subclass=Object]*/
 testIsCheck25(/*[null|subclass=Object]*/ a) {
   if (a is int) throw 'foo';
   return a;
 }
 
-/*element: testIsCheck26:[subclass=JSInt]*/
+/*member: testIsCheck26:[subclass=JSInt]*/
 testIsCheck26(/*[null|subclass=Object]*/ a) {
   if (a is int) {
   } else {
@@ -313,7 +313,7 @@
   return a;
 }
 
-/*element: testIsCheck27:[subclass=JSInt]*/
+/*member: testIsCheck27:[subclass=JSInt]*/
 testIsCheck27(/*[null|subclass=Object]*/ a) {
   if (a is int) {
   } else {
@@ -322,20 +322,20 @@
   return a;
 }
 
-/*element: testIsCheck28:[null|subclass=Object]*/
+/*member: testIsCheck28:[null|subclass=Object]*/
 testIsCheck28(/*[null|subclass=Object]*/ a) {
   if (a is int) {
   } else {}
   return a;
 }
 
-/*element: testIsCheck29:[null|subclass=Object]*/
+/*member: testIsCheck29:[null|subclass=Object]*/
 testIsCheck29(/*[null|subclass=Object]*/ a) {
   if (a is int) {}
   return a;
 }
 
-/*element: testIf1:[null|exact=JSUInt31]*/
+/*member: testIf1:[null|exact=JSUInt31]*/
 testIf1(/*[null|subclass=Object]*/ a) {
   var c = null;
   if (a) {
@@ -344,7 +344,7 @@
   return c;
 }
 
-/*element: testIf2:[null|exact=JSUInt31]*/
+/*member: testIf2:[null|exact=JSUInt31]*/
 testIf2(/*[null|subclass=Object]*/ a) {
   var c = null;
   if (a) {
@@ -354,12 +354,12 @@
   return c;
 }
 
-/*element: returnAsString:[null|exact=JSString]*/
+/*member: returnAsString:[null|exact=JSString]*/
 returnAsString() {
   return topLevelGetter() as String;
 }
 
-/*element: returnIntAsNum:[exact=JSUInt31]*/
+/*member: returnIntAsNum:[exact=JSUInt31]*/
 returnIntAsNum() {
   dynamic a = 0;
   return a as num;
@@ -367,19 +367,19 @@
 
 typedef int Foo();
 
-/*element: returnAsTypedef:[null|subclass=Closure]*/
+/*member: returnAsTypedef:[null|subclass=Closure]*/
 returnAsTypedef() {
   return topLevelGetter() as Foo;
 }
 
-/*element: testDeadCode:[exact=JSUInt31]*/
+/*member: testDeadCode:[exact=JSUInt31]*/
 testDeadCode() {
   return 42;
   // ignore: dead_code
   return 'foo';
 }
 
-/*element: testLabeledIf:[null|exact=JSUInt31]*/
+/*member: testLabeledIf:[null|exact=JSUInt31]*/
 testLabeledIf(/*Value([exact=JSBool], value: true)*/ a) {
   var c;
   L1:
@@ -394,7 +394,7 @@
   return c;
 }
 
-/*element: testSwitch1:Union([exact=JSUInt31], [null|exact=JSDouble])*/
+/*member: testSwitch1:Union([exact=JSUInt31], [null|exact=JSDouble])*/
 testSwitch1() {
   var a = null;
   switch (topLevelGetter) {
@@ -408,7 +408,7 @@
   return a;
 }
 
-/*element: testSwitch2:[exact=JSUInt31]*/
+/*member: testSwitch2:[exact=JSUInt31]*/
 testSwitch2() {
   var a = null;
   switch (topLevelGetter) {
@@ -424,7 +424,7 @@
   return a;
 }
 
-/*element: testSwitch3:Union([exact=JSString], [null|subclass=JSNumber])*/
+/*member: testSwitch3:Union([exact=JSString], [null|subclass=JSNumber])*/
 testSwitch3() {
   dynamic a = 42;
   var b;
@@ -440,7 +440,7 @@
   return b;
 }
 
-/*element: testSwitch4:[exact=JSUInt31]*/
+/*member: testSwitch4:[exact=JSUInt31]*/
 testSwitch4() {
   switch (topLevelGetter) {
     case 1:
@@ -451,7 +451,7 @@
   return 42;
 }
 
-/*element: testSwitch5:[exact=JSUInt31]*/
+/*member: testSwitch5:[exact=JSUInt31]*/
 testSwitch5() {
   switch (topLevelGetter) {
     case 1:
@@ -461,7 +461,7 @@
   }
 }
 
-/*element: testContinue1:Union([exact=JSString], [null|subclass=JSNumber])*/
+/*member: testContinue1:Union([exact=JSString], [null|subclass=JSNumber])*/
 testContinue1() {
   dynamic a = 42;
   var b;
@@ -475,7 +475,7 @@
   return b;
 }
 
-/*element: testBreak1:Union([null|exact=JSString], [subclass=JSUInt32])*/
+/*member: testBreak1:Union([null|exact=JSString], [subclass=JSUInt32])*/
 testBreak1() {
   var a = 42;
   var b;
@@ -487,7 +487,7 @@
   return b;
 }
 
-/*element: testContinue2:Union([exact=JSString], [null|subclass=JSUInt32])*/
+/*member: testContinue2:Union([exact=JSString], [null|subclass=JSUInt32])*/
 testContinue2() {
   var a = 42;
   var b;
@@ -502,7 +502,7 @@
   return b;
 }
 
-/*element: testBreak2:[null|subclass=JSUInt32]*/
+/*member: testBreak2:[null|subclass=JSUInt32]*/
 testBreak2() {
   dynamic a = 42;
   var b;
@@ -516,7 +516,7 @@
   return b;
 }
 
-/*element: testReturnElementOfConstList1:[exact=JSUInt31]*/
+/*member: testReturnElementOfConstList1:[exact=JSUInt31]*/
 testReturnElementOfConstList1() {
   return const [
     42
@@ -524,19 +524,19 @@
       0];
 }
 
-/*element: testReturnElementOfConstList2:[exact=JSUInt31]*/
+/*member: testReturnElementOfConstList2:[exact=JSUInt31]*/
 testReturnElementOfConstList2() {
   return topLevelConstList /*Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/ [
       0];
 }
 
-/*element: testReturnItselfOrInt:[exact=JSUInt31]*/
+/*member: testReturnItselfOrInt:[exact=JSUInt31]*/
 testReturnItselfOrInt(/*[null|subclass=Object]*/ a) {
   if (a) return 42;
   return testReturnItselfOrInt(a);
 }
 
-/*element: testDoWhile1:Value([exact=JSString], value: "foo")*/
+/*member: testDoWhile1:Value([exact=JSString], value: "foo")*/
 testDoWhile1() {
   dynamic a = 42;
   do {
@@ -546,7 +546,7 @@
   return a;
 }
 
-/*element: testDoWhile2:[null]*/
+/*member: testDoWhile2:[null]*/
 testDoWhile2() {
   dynamic a = 42;
   do {
@@ -558,7 +558,7 @@
   return a;
 }
 
-/*element: testDoWhile3:[exact=JSUInt31]*/
+/*member: testDoWhile3:[exact=JSUInt31]*/
 testDoWhile3() {
   dynamic a = 42;
   do {
@@ -570,7 +570,7 @@
   return a;
 }
 
-/*element: testDoWhile4:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: testDoWhile4:Union([exact=JSDouble], [exact=JSUInt31])*/
 testDoWhile4() {
   dynamic a = 'foo';
   do {
@@ -581,14 +581,14 @@
   return a;
 }
 
-/*element: testSpecialization1:[subclass=Object]*/
+/*member: testSpecialization1:[subclass=Object]*/
 testSpecialization1() {
   var a = topLevelGetter();
   a - 42;
   return a;
 }
 
-/*element: testSpecialization2:[null|subclass=Object]*/
+/*member: testSpecialization2:[null|subclass=Object]*/
 testSpecialization2() {
   var a = topLevelGetter();
   // Make [a] a captured variable. This should disable receiver
@@ -600,7 +600,7 @@
   return a;
 }
 
-/*element: testSpecialization3:[null|exact=JSUInt31]*/
+/*member: testSpecialization3:[null|exact=JSUInt31]*/
 testSpecialization3() {
   var a = returnDynamic() ? null : 42;
   a. /*invoke: [null|exact=JSUInt31]*/ toString();
@@ -609,191 +609,191 @@
   return a;
 }
 
-/*element: testReturnNull1:[null]*/
+/*member: testReturnNull1:[null]*/
 testReturnNull1(/*[null|subclass=Object]*/ a) {
   if (a == null) return a;
   return null;
 }
 
-/*element: testReturnNull2:[null]*/
+/*member: testReturnNull2:[null]*/
 testReturnNull2(/*[null|subclass=Object]*/ a) {
   if (a != null) return null;
   return a;
 }
 
-/*element: testReturnNull3:[subclass=Object]*/
+/*member: testReturnNull3:[subclass=Object]*/
 testReturnNull3(/*[null|subclass=Object]*/ a) {
   if (a == null) return 42;
   return a;
 }
 
-/*element: testReturnNull4:[null]*/
+/*member: testReturnNull4:[null]*/
 testReturnNull4() {
   var a = topLevelGetter();
   if (a == null) return a;
   return null;
 }
 
-/*element: testReturnNull5:[null]*/
+/*member: testReturnNull5:[null]*/
 testReturnNull5() {
   var a = topLevelGetter();
   if (a != null) return null;
   return a;
 }
 
-/*element: testReturnNull6:[subclass=Object]*/
+/*member: testReturnNull6:[subclass=Object]*/
 testReturnNull6() {
   var a = topLevelGetter();
   if (a == null) return 42;
   return a;
 }
 
-/*element: testReturnNotEquals:[exact=JSBool]*/
+/*member: testReturnNotEquals:[exact=JSBool]*/
 testReturnNotEquals() {
   return new A() /*invoke: [exact=A]*/ != 54;
 }
 
-/*element: testReturnInvokeDynamicGetter:[null|subclass=Object]*/
+/*member: testReturnInvokeDynamicGetter:[null|subclass=Object]*/
 testReturnInvokeDynamicGetter() => new A(). /*invoke: [exact=A]*/ myFactory();
 
-/*element: topLevelConstList:Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: topLevelConstList:Container([exact=JSUnmodifiableArray], element: [exact=JSUInt31], length: 1)*/
 var topLevelConstList = const [42];
 
-/*element: topLevelGetter:[exact=JSUInt31]*/
+/*member: topLevelGetter:[exact=JSUInt31]*/
 get topLevelGetter => 42;
 
-/*element: returnDynamic:[null|subclass=Object]*/
+/*member: returnDynamic:[null|subclass=Object]*/
 returnDynamic() => topLevelGetter(42);
 
-/*element: returnTopLevelGetter:[exact=JSUInt31]*/
+/*member: returnTopLevelGetter:[exact=JSUInt31]*/
 returnTopLevelGetter() => topLevelGetter;
 
 class A {
   factory A() = A.generative;
 
-  /*element: A.generative:[exact=A]*/
+  /*member: A.generative:[exact=A]*/
   A.generative();
 
-  /*element: A.==:[exact=JSBool]*/
+  /*member: A.==:[exact=JSBool]*/
   operator ==(/*Union([exact=JSString], [exact=JSUInt31])*/ other) =>
       42 as dynamic;
 
-  /*element: A.myField:[exact=JSUInt31]*/
+  /*member: A.myField:[exact=JSUInt31]*/
   get myField => 42;
 
   set myField(/*[subclass=JSUInt32]*/ a) {}
 
-  /*element: A.returnInt1:[subclass=JSUInt32]*/
+  /*member: A.returnInt1:[subclass=JSUInt32]*/
   returnInt1() => /*invoke: [exact=JSUInt31]*/ ++ /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
 
-  /*element: A.returnInt2:[subclass=JSUInt32]*/
+  /*member: A.returnInt2:[subclass=JSUInt32]*/
   returnInt2() => /*invoke: [exact=JSUInt31]*/ ++this
       . /*[subclass=A]*/ /*update: [subclass=A]*/ myField;
 
-  /*element: A.returnInt3:[subclass=JSUInt32]*/
+  /*member: A.returnInt3:[subclass=JSUInt32]*/
   returnInt3() =>
       this. /*[subclass=A]*/ /*update: [subclass=A]*/ myField /*invoke: [exact=JSUInt31]*/ +=
           42;
 
-  /*element: A.returnInt4:[subclass=JSUInt32]*/
+  /*member: A.returnInt4:[subclass=JSUInt32]*/
   returnInt4() => /*[subclass=A]*/ /*update: [subclass=A]*/ myField /*invoke: [exact=JSUInt31]*/ +=
       42;
 
-  /*element: A.[]:[exact=JSUInt31]*/
+  /*member: A.[]:[exact=JSUInt31]*/
   operator [](/*[exact=JSUInt31]*/ index) => 42;
 
-  /*element: A.[]=:[null]*/
+  /*member: A.[]=:[null]*/
   operator []=(/*[exact=JSUInt31]*/ index, /*[subclass=JSUInt32]*/ value) {}
 
-  /*element: A.returnInt5:[subclass=JSUInt32]*/
+  /*member: A.returnInt5:[subclass=JSUInt32]*/
   returnInt5() => /*invoke: [exact=JSUInt31]*/ ++this /*[subclass=A]*/ /*update: [subclass=A]*/ [
       0];
 
-  /*element: A.returnInt6:[subclass=JSUInt32]*/
+  /*member: A.returnInt6:[subclass=JSUInt32]*/
   returnInt6() => this /*[subclass=A]*/ /*update: [subclass=A]*/ [
       0] /*invoke: [exact=JSUInt31]*/ += 1;
 
-  /*element: A.myFactory:[subclass=Closure]*/
+  /*member: A.myFactory:[subclass=Closure]*/
   get myFactory => /*[exact=JSUInt31]*/ () => 42;
 }
 
 class B extends A {
-  /*element: B.:[exact=B]*/
+  /*member: B.:[exact=B]*/
   B() : super.generative();
 
-  /*element: B.returnInt1:[subclass=JSUInt32]*/
+  /*member: B.returnInt1:[subclass=JSUInt32]*/
   returnInt1() => /*invoke: [exact=JSUInt31]*/ ++new A()
       . /*[exact=A]*/ /*update: [exact=A]*/ myField;
 
-  /*element: B.returnInt2:[subclass=JSUInt32]*/
+  /*member: B.returnInt2:[subclass=JSUInt32]*/
   returnInt2() => new A()
       . /*[exact=A]*/ /*update: [exact=A]*/ myField /*invoke: [exact=JSUInt31]*/ += 4;
 
-  /*element: B.returnInt3:[subclass=JSUInt32]*/
+  /*member: B.returnInt3:[subclass=JSUInt32]*/
   returnInt3() => /*invoke: [exact=JSUInt31]*/ ++new A() /*[exact=A]*/ /*update: [exact=A]*/ [
       0];
 
-  /*element: B.returnInt4:[subclass=JSUInt32]*/
+  /*member: B.returnInt4:[subclass=JSUInt32]*/
   returnInt4() => new A() /*[exact=A]*/ /*update: [exact=A]*/ [
       0] /*invoke: [exact=JSUInt31]*/ += 42;
 
-  /*element: B.returnInt5:[subclass=JSUInt32]*/
+  /*member: B.returnInt5:[subclass=JSUInt32]*/
   returnInt5() => /*invoke: [exact=JSUInt31]*/ ++super.myField;
 
-  /*element: B.returnInt6:[subclass=JSUInt32]*/
+  /*member: B.returnInt6:[subclass=JSUInt32]*/
   returnInt6() => super.myField /*invoke: [exact=JSUInt31]*/ += 4;
 
-  /*element: B.returnInt7:[subclass=JSUInt32]*/
+  /*member: B.returnInt7:[subclass=JSUInt32]*/
   returnInt7() => /*invoke: [exact=JSUInt31]*/ ++super[0];
 
-  /*element: B.returnInt8:[subclass=JSUInt32]*/
+  /*member: B.returnInt8:[subclass=JSUInt32]*/
   returnInt8() => super[0] /*invoke: [exact=JSUInt31]*/ += 54;
 
-  /*element: B.returnInt9:[exact=JSUInt31]*/
+  /*member: B.returnInt9:[exact=JSUInt31]*/
   returnInt9() => super.myField;
 }
 
 class C {
-  /*element: C.myField:[subclass=JSPositiveInt]*/
+  /*member: C.myField:[subclass=JSPositiveInt]*/
   var myField = 42;
 
-  /*element: C.:[exact=C]*/
+  /*member: C.:[exact=C]*/
   C();
 
-  /*element: C.returnInt1:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt1:[subclass=JSPositiveInt]*/
   returnInt1() => /*invoke: [subclass=JSPositiveInt]*/ ++ /*[exact=C]*/ /*update: [exact=C]*/ myField;
 
-  /*element: C.returnInt2:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt2:[subclass=JSPositiveInt]*/
   returnInt2() => /*invoke: [subclass=JSPositiveInt]*/ ++this
       . /*[exact=C]*/ /*update: [exact=C]*/ myField;
 
-  /*element: C.returnInt3:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt3:[subclass=JSPositiveInt]*/
   returnInt3() =>
       this. /*[exact=C]*/ /*update: [exact=C]*/ myField /*invoke: [subclass=JSPositiveInt]*/ +=
           42;
 
-  /*element: C.returnInt4:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt4:[subclass=JSPositiveInt]*/
   returnInt4() => /*[exact=C]*/ /*update: [exact=C]*/ myField /*invoke: [subclass=JSPositiveInt]*/ +=
       42;
 
-  /*element: C.[]:[subclass=JSPositiveInt]*/
+  /*member: C.[]:[subclass=JSPositiveInt]*/
   operator [](/*[exact=JSUInt31]*/ index) => /*[exact=C]*/ myField;
 
-  /*element: C.[]=:[null]*/
+  /*member: C.[]=:[null]*/
   operator []=(
       /*[exact=JSUInt31]*/ index,
       /*[subclass=JSPositiveInt]*/ value) {}
 
-  /*element: C.returnInt5:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt5:[subclass=JSPositiveInt]*/
   returnInt5() => /*invoke: [subclass=JSPositiveInt]*/ ++this /*[exact=C]*/ /*update: [exact=C]*/ [
       0];
 
-  /*element: C.returnInt6:[subclass=JSPositiveInt]*/
+  /*member: C.returnInt6:[subclass=JSPositiveInt]*/
   returnInt6() => this /*[exact=C]*/ /*update: [exact=C]*/ [
       0] /*invoke: [subclass=JSPositiveInt]*/ += 1;
 }
 
-/*element: testCascade1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
+/*member: testCascade1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
 testCascade1() {
   return [1, 2, 3]
     .. /*invoke: Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: null)*/
@@ -802,7 +802,7 @@
         add(5);
 }
 
-/*element: testCascade2:[exact=CascadeHelper]*/
+/*member: testCascade2:[exact=CascadeHelper]*/
 testCascade2() {
   return new CascadeHelper()
     .. /*update: [exact=CascadeHelper]*/ a = "hello"
@@ -811,19 +811,19 @@
         /*invoke: [subclass=JSPositiveInt]*/ += 1;
 }
 
-/*element: CascadeHelper.:[exact=CascadeHelper]*/
+/*member: CascadeHelper.:[exact=CascadeHelper]*/
 class CascadeHelper {
-  /*element: CascadeHelper.a:Value([null|exact=JSString], value: "hello")*/
+  /*member: CascadeHelper.a:Value([null|exact=JSString], value: "hello")*/
   var a;
 
-  /*element: CascadeHelper.b:[null|exact=JSUInt31]*/
+  /*member: CascadeHelper.b:[null|exact=JSUInt31]*/
   var b;
 
-  /*element: CascadeHelper.i:[subclass=JSPositiveInt]*/
+  /*member: CascadeHelper.i:[subclass=JSPositiveInt]*/
   var i = 0;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   // Ensure a function class is being instantiated.
   /*[exact=JSUInt31]*/ () => 42;
diff --git a/tests/compiler/dart2js/inference/data/general6.dart b/tests/compiler/dart2js/inference/data/general6.dart
index f28acc0..fab306e 100644
--- a/tests/compiler/dart2js/inference/data/general6.dart
+++ b/tests/compiler/dart2js/inference/data/general6.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:[exact=JSUInt31]*/
+/*member: foo:[exact=JSUInt31]*/
 foo() {
   var a = [1, 2, 3];
   return a
@@ -10,7 +10,7 @@
       first;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   foo();
 }
diff --git a/tests/compiler/dart2js/inference/data/general7.dart b/tests/compiler/dart2js/inference/data/general7.dart
index 2fb6105..bd8da3f3 100644
--- a/tests/compiler/dart2js/inference/data/general7.dart
+++ b/tests/compiler/dart2js/inference/data/general7.dart
@@ -6,10 +6,10 @@
 /// file 'general7_ea.dart' contains similar tests for when assertions are
 /// _enabled_.
 
-/*element: foo:[null]*/
+/*member: foo:[null]*/
 foo(/*[exact=JSUInt31]*/ x, [/*[null]*/ y]) => y;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   assert(foo('Hi', true), foo(true));
   foo(1);
diff --git a/tests/compiler/dart2js/inference/data/general7_ea.dart b/tests/compiler/dart2js/inference/data/general7_ea.dart
index 50e5667..733c016 100644
--- a/tests/compiler/dart2js/inference/data/general7_ea.dart
+++ b/tests/compiler/dart2js/inference/data/general7_ea.dart
@@ -6,13 +6,13 @@
 /// file 'general7.dart' contains similar tests for when assertions are
 /// _disabled_.
 
-/*element: foo:Value([null|exact=JSBool], value: true)*/
+/*member: foo:Value([null|exact=JSBool], value: true)*/
 foo(
         /*Union([exact=JSBool], [exact=JSString], [exact=JSUInt31])*/ x,
         [/*Value([null|exact=JSBool], value: true)*/ y]) =>
     y;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   assert(foo('Hi', true), foo(true));
   foo(1);
diff --git a/tests/compiler/dart2js/inference/data/general8a.dart b/tests/compiler/dart2js/inference/data/general8a.dart
index d94138e..8f3815a 100644
--- a/tests/compiler/dart2js/inference/data/general8a.dart
+++ b/tests/compiler/dart2js/inference/data/general8a.dart
@@ -2,12 +2,12 @@
 // 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.
 
-/*element: foo:Value([exact=JSBool], value: false)*/
+/*member: foo:Value([exact=JSBool], value: false)*/
 foo(/*Value([exact=JSBool], value: false)*/ x) {
   return x;
 }
 
-/*element: bar:[null]*/
+/*member: bar:[null]*/
 bar(/*Value([exact=JSBool], value: false)*/ x) {
   if (x) {
     print("aaa");
@@ -16,7 +16,7 @@
   }
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   bar(foo(false));
   bar(foo(foo(false)));
diff --git a/tests/compiler/dart2js/inference/data/general8b.dart b/tests/compiler/dart2js/inference/data/general8b.dart
index 594a093..baed070 100644
--- a/tests/compiler/dart2js/inference/data/general8b.dart
+++ b/tests/compiler/dart2js/inference/data/general8b.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*element: foo:[exact=JSBool]*/
+/*member: foo:[exact=JSBool]*/
 foo(/*[exact=JSUInt31]*/ x) {
   if (x /*invoke: [exact=JSUInt31]*/ > 3) return true;
   return false;
 }
 
-/*element: bar:[null]*/
+/*member: bar:[null]*/
 bar(/*[exact=JSBool]*/ x) {
   if (x) {
     print("aaa");
@@ -17,7 +17,7 @@
   }
 }
 
-/*element: main:[null]*/ main() {
+/*member: main:[null]*/ main() {
   bar(foo(5));
   bar(foo(6));
 }
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure.dart b/tests/compiler/dart2js/inference/data/global_field_closure.dart
index d40bfaab..34f39b7 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure.dart
@@ -2,40 +2,40 @@
 // 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.
 
-/*element: method1:[exact=JSUInt31]*/
+/*member: method1:[exact=JSUInt31]*/
 method1() {
   return 42;
 }
 
-/*element: method2:[exact=JSUInt31]*/
+/*member: method2:[exact=JSUInt31]*/
 // Called only via [foo2] with a small integer.
 method2(/*[exact=JSUInt31]*/ a) {
   return a;
 }
 
-/*strong.element: foo1:[null|subclass=Closure]*/
-/*omit.element: foo1:[null|subclass=Closure]*/
-/*strongConst.element: foo1:[subclass=Closure]*/
-/*omitConst.element: foo1:[subclass=Closure]*/
+/*strong.member: foo1:[null|subclass=Closure]*/
+/*omit.member: foo1:[null|subclass=Closure]*/
+/*strongConst.member: foo1:[subclass=Closure]*/
+/*omitConst.member: foo1:[subclass=Closure]*/
 var foo1 = method1;
 
-/*strong.element: foo2:[null|subclass=Closure]*/
-/*omit.element: foo2:[null|subclass=Closure]*/
-/*strongConst.element: foo2:[subclass=Closure]*/
-/*omitConst.element: foo2:[subclass=Closure]*/
+/*strong.member: foo2:[null|subclass=Closure]*/
+/*omit.member: foo2:[null|subclass=Closure]*/
+/*strongConst.member: foo2:[subclass=Closure]*/
+/*omitConst.member: foo2:[subclass=Closure]*/
 var foo2 = method2;
 
-/*element: returnInt1:[null|subclass=Object]*/
+/*member: returnInt1:[null|subclass=Object]*/
 returnInt1() {
   return foo1();
 }
 
-/*element: returnInt2:[null|subclass=Object]*/
+/*member: returnInt2:[null|subclass=Object]*/
 returnInt2() {
   return foo2(54);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt1();
   returnInt2();
diff --git a/tests/compiler/dart2js/inference/data/global_field_closure2.dart b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
index f4199e9..3946304 100644
--- a/tests/compiler/dart2js/inference/data/global_field_closure2.dart
+++ b/tests/compiler/dart2js/inference/data/global_field_closure2.dart
@@ -2,24 +2,24 @@
 // 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.
 
-/*element: method:[exact=JSUInt31]*/
+/*member: method:[exact=JSUInt31]*/
 // Called only via [foo] with a small integer.
 method(/*[exact=JSUInt31]*/ a) {
   return a;
 }
 
-/*strong.element: foo:[null|subclass=Closure]*/
-/*omit.element: foo:[null|subclass=Closure]*/
-/*strongConst.element: foo:[subclass=Closure]*/
-/*omitConst.element: foo:[subclass=Closure]*/
+/*strong.member: foo:[null|subclass=Closure]*/
+/*omit.member: foo:[null|subclass=Closure]*/
+/*strongConst.member: foo:[subclass=Closure]*/
+/*omitConst.member: foo:[subclass=Closure]*/
 var foo = method;
 
-/*element: returnInt:[null|subclass=Object]*/
+/*member: returnInt:[null|subclass=Object]*/
 returnInt() {
   return foo(54);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt();
 }
diff --git a/tests/compiler/dart2js/inference/data/if.dart b/tests/compiler/dart2js/inference/data/if.dart
index abe28a0..ecb1a6f 100644
--- a/tests/compiler/dart2js/inference/data/if.dart
+++ b/tests/compiler/dart2js/inference/data/if.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleIfThen();
   simpleIfThenElse();
@@ -12,13 +12,13 @@
 // Test if-then statement
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _simpleIfThen:[null|exact=JSUInt31]*/
+/*member: _simpleIfThen:[null|exact=JSUInt31]*/
 _simpleIfThen(/*[exact=JSBool]*/ c) {
   if (c) return 1;
   return null;
 }
 
-/*element: simpleIfThen:[null]*/
+/*member: simpleIfThen:[null]*/
 simpleIfThen() {
   _simpleIfThen(true);
   _simpleIfThen(false);
@@ -28,7 +28,7 @@
 // Test if-then-else statement
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _simpleIfThenElse:[null|exact=JSUInt31]*/
+/*member: _simpleIfThenElse:[null|exact=JSUInt31]*/
 _simpleIfThenElse(/*[exact=JSBool]*/ c) {
   if (c)
     return 1;
@@ -36,7 +36,7 @@
     return null;
 }
 
-/*element: simpleIfThenElse:[null]*/
+/*member: simpleIfThenElse:[null]*/
 simpleIfThenElse() {
   _simpleIfThenElse(true);
   _simpleIfThenElse(false);
diff --git a/tests/compiler/dart2js/inference/data/if_null.dart b/tests/compiler/dart2js/inference/data/if_null.dart
index 640ef25..988f649 100644
--- a/tests/compiler/dart2js/inference/data/if_null.dart
+++ b/tests/compiler/dart2js/inference/data/if_null.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   ifNull();
   ifNotNullInvoke();
@@ -13,10 +13,10 @@
 // If-null on parameter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _ifNull:[exact=JSUInt31]*/
+/*member: _ifNull:[exact=JSUInt31]*/
 _ifNull(/*[null|exact=JSUInt31]*/ o) => o ?? 0;
 
-/*element: ifNull:[null]*/
+/*member: ifNull:[null]*/
 ifNull() {
   _ifNull(null);
   _ifNull(0);
@@ -26,14 +26,14 @@
 // If-not-null access on parameter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _ifNotNullInvoke:[null|exact=JSBool]*/
+/*member: _ifNotNullInvoke:[null|exact=JSBool]*/
 _ifNotNullInvoke(/*[null|exact=JSUInt31]*/ o) {
   return o?.
       /*[exact=JSUInt31]*/
       isEven;
 }
 
-/*element: ifNotNullInvoke:[null]*/
+/*member: ifNotNullInvoke:[null]*/
 ifNotNullInvoke() {
   _ifNotNullInvoke(null);
   _ifNotNullInvoke(0);
@@ -43,12 +43,12 @@
 // As above but unconditional access.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notIfNotNullInvoke:[exact=JSBool]*/
+/*member: _notIfNotNullInvoke:[exact=JSBool]*/
 _notIfNotNullInvoke(/*[null|exact=JSUInt31]*/ o) {
   return o. /*[null|exact=JSUInt31]*/ isEven;
 }
 
-/*element: notIfNotNullInvoke:[null]*/
+/*member: notIfNotNullInvoke:[null]*/
 notIfNotNullInvoke() {
   _notIfNotNullInvoke(null);
   _notIfNotNullInvoke(0);
diff --git a/tests/compiler/dart2js/inference/data/index.dart b/tests/compiler/dart2js/inference/data/index.dart
index 21a1d93..bfa90b5a 100644
--- a/tests/compiler/dart2js/inference/data/index.dart
+++ b/tests/compiler/dart2js/inference/data/index.dart
@@ -6,7 +6,7 @@
 // Lookup into a singleton list.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexSingle:[exact=JSUInt31]*/
+/*member: listIndexSingle:[exact=JSUInt31]*/
 listIndexSingle() {
   var list = [0];
   return list
@@ -18,7 +18,7 @@
 // Lookup into a list with multiple elements.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexMultiple:[exact=JSUInt31]*/
+/*member: listIndexMultiple:[exact=JSUInt31]*/
 listIndexMultiple() {
   var list = [0, 1, 2, 3];
   return list
@@ -30,7 +30,7 @@
 // Lookup into a list with an out-of-range index.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexBad:[exact=JSUInt31]*/
+/*member: listIndexBad:[exact=JSUInt31]*/
 listIndexBad() {
   var list = [0, 1];
   return list
@@ -42,7 +42,7 @@
 // Lookup into a list with mixed element types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexMixed:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: listIndexMixed:Union([exact=JSString], [exact=JSUInt31])*/
 listIndexMixed() {
   var list = [0, ''];
   return list
@@ -54,7 +54,7 @@
 // Lookup into a singleton map.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapLookupSingle:[null|exact=JSUInt31]*/
+/*member: mapLookupSingle:[null|exact=JSUInt31]*/
 mapLookupSingle() {
   var map = {0: 1};
   return map
@@ -66,7 +66,7 @@
 // Lookup into a map with multiple entries.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapLookupMultiple:[null|exact=JSUInt31]*/
+/*member: mapLookupMultiple:[null|exact=JSUInt31]*/
 mapLookupMultiple() {
   var map = {0: 1, 2: 3, 4: 5};
   return map
@@ -78,7 +78,7 @@
 // Lookup into a map with a missing key.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapLookupMissing:[null|exact=JSUInt31]*/
+/*member: mapLookupMissing:[null|exact=JSUInt31]*/
 mapLookupMissing() {
   var map = {0: 1};
   return map
@@ -90,7 +90,7 @@
 // Lookup into a map with mixed key types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapLookupMixedKeys:[null|exact=JSUInt31]*/
+/*member: mapLookupMixedKeys:[null|exact=JSUInt31]*/
 mapLookupMixedKeys() {
   var map = {0: 1, '': 2};
   return map
@@ -102,7 +102,7 @@
 // Lookup into a map with mixed value types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapLookupMixedValues:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: mapLookupMixedValues:Union([exact=JSUInt31], [null|exact=JSString])*/
 mapLookupMixedValues() {
   var map = {0: 1, 2: ''};
   return map
@@ -114,7 +114,7 @@
 // Lookup into a singleton map with String keys.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryLookupSingle:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryLookupSingle:Value([exact=JSString], value: "bar")*/
 dictionaryLookupSingle() {
   var map = {'foo': 'bar'};
   return map
@@ -126,7 +126,7 @@
 // Lookup into a map with String keys.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryLookupMultiple:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryLookupMultiple:Value([exact=JSString], value: "boz")*/
 dictionaryLookupMultiple() {
   var map = {'foo': 'bar', 'baz': 'boz'};
   return map
@@ -138,7 +138,7 @@
 // Lookup into a map with String keys with a missing key.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryLookupMissing:[null]*/
+/*member: dictionaryLookupMissing:[null]*/
 dictionaryLookupMissing() {
   var map = {'foo': 'bar', 'baz': 'boz'};
   return map
@@ -150,7 +150,7 @@
 // Lookup into a string-to-int map.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: intDictionaryLookupSingle:[exact=JSUInt31]*/
+/*member: intDictionaryLookupSingle:[exact=JSUInt31]*/
 intDictionaryLookupSingle() {
   var map = {'foo': 0};
   return map
@@ -162,32 +162,32 @@
 // Index access on custom class.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.[]:[exact=JSUInt31]*/
+  /*member: Class1.[]:[exact=JSUInt31]*/
   operator [](/*[exact=JSUInt31]*/ index) => index;
 }
 
-/*element: customIndex:[exact=JSUInt31]*/
+/*member: customIndex:[exact=JSUInt31]*/
 customIndex() => new Class1() /*[exact=Class1]*/ [42];
 
 ////////////////////////////////////////////////////////////////////////////////
 // Index access on custom class through `this`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.[]:[exact=JSUInt31]*/
+  /*member: Class2.[]:[exact=JSUInt31]*/
   operator [](/*[exact=JSUInt31]*/ index) => index;
 
-  /*element: Class2.method:[exact=JSUInt31]*/
+  /*member: Class2.method:[exact=JSUInt31]*/
   method() => this /*[exact=Class2]*/ [42];
 }
 
-/*element: customIndexThis:[exact=JSUInt31]*/
+/*member: customIndexThis:[exact=JSUInt31]*/
 customIndexThis() => new Class2(). /*invoke: [exact=Class2]*/ method();
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   listIndexSingle();
   listIndexMultiple();
diff --git a/tests/compiler/dart2js/inference/data/index_call.dart b/tests/compiler/dart2js/inference/data/index_call.dart
index 1bab3af..a2c6006 100644
--- a/tests/compiler/dart2js/inference/data/index_call.dart
+++ b/tests/compiler/dart2js/inference/data/index_call.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   listIndexCall();
   listIndexExplicitCall();
@@ -13,7 +13,7 @@
   multiMapListIndexCall();
 }
 
-/*element: listIndexCall:[null|subclass=Object]*/
+/*member: listIndexCall:[null|subclass=Object]*/
 listIndexCall() {
   var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ a}) => a;
   var a = [closure];
@@ -21,7 +21,7 @@
       [0](a: 0);
 }
 
-/*element: listIndexExplicitCall:[null|subclass=Object]*/
+/*member: listIndexExplicitCall:[null|subclass=Object]*/
 listIndexExplicitCall() {
   var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ b}) => b;
   var a = [closure];
@@ -30,7 +30,7 @@
       .call(b: 0);
 }
 
-/*element: multiListIndex:[subclass=JSPositiveInt]*/
+/*member: multiListIndex:[subclass=JSPositiveInt]*/
 multiListIndex() {
   var a = [
     [0]
@@ -43,7 +43,7 @@
       . /*invoke: [exact=JSUInt31]*/ abs();
 }
 
-/*element: multiListIndexCall:[null|subclass=Object]*/
+/*member: multiListIndexCall:[null|subclass=Object]*/
 multiListIndexCall() {
   var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ c}) => c;
   var a = [
@@ -56,7 +56,7 @@
       [0](c: 0);
 }
 
-/*element: multiMapIndex:[subclass=JSPositiveInt]*/
+/*member: multiMapIndex:[subclass=JSPositiveInt]*/
 multiMapIndex() {
   var a = {
     'a': {'b': 0}
@@ -69,7 +69,7 @@
       abs();
 }
 
-/*element: multiMapIndexCall:[null|subclass=Object]*/
+/*member: multiMapIndexCall:[null|subclass=Object]*/
 multiMapIndexCall() {
   var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ d}) => d;
   var a = {
@@ -81,7 +81,7 @@
       ['b'](d: 0);
 }
 
-/*element: multiMapListIndexCall:[null|subclass=Object]*/
+/*member: multiMapListIndexCall:[null|subclass=Object]*/
 multiMapListIndexCall() {
   var closure = /*[exact=JSUInt31]*/ ({/*[exact=JSUInt31]*/ d}) => d;
   var a = {
diff --git a/tests/compiler/dart2js/inference/data/index_postfix.dart b/tests/compiler/dart2js/inference/data/index_postfix.dart
index 5eefc77..a861cfb 100644
--- a/tests/compiler/dart2js/inference/data/index_postfix.dart
+++ b/tests/compiler/dart2js/inference/data/index_postfix.dart
@@ -2,14 +2,14 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   listIndexPostfixIncrement();
   listIndexPostfixDecrement();
   superIndexPostfixIncrement();
 }
 
-/*element: listIndexPostfixIncrement:[subclass=JSPositiveInt]*/
+/*member: listIndexPostfixIncrement:[subclass=JSPositiveInt]*/
 listIndexPostfixIncrement() {
   var list = [0];
   return list
@@ -19,7 +19,7 @@
       /*invoke: [subclass=JSPositiveInt]*/ ++;
 }
 
-/*element: listIndexPostfixDecrement:[subclass=JSInt]*/
+/*member: listIndexPostfixDecrement:[subclass=JSInt]*/
 listIndexPostfixDecrement() {
   var list = [0];
   return list
@@ -29,22 +29,22 @@
       /*invoke: [subclass=JSInt]*/ --;
 }
 
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
 class Super1 {
-  /*element: Super1.[]:[exact=JSUInt31]*/
+  /*member: Super1.[]:[exact=JSUInt31]*/
   operator [](/*[exact=JSUInt31]*/ index) => 42;
 
-  /*element: Super1.[]=:[null]*/
+  /*member: Super1.[]=:[null]*/
   operator []=(/*[exact=JSUInt31]*/ index, /*[subclass=JSUInt32]*/ value) {}
 }
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 extends Super1 {
-  /*element: Class1.method:[exact=JSUInt31]*/
+  /*member: Class1.method:[exact=JSUInt31]*/
   method() => super[0] /*invoke: [exact=JSUInt31]*/ ++;
 }
 
-/*element: superIndexPostfixIncrement:[null]*/
+/*member: superIndexPostfixIncrement:[null]*/
 superIndexPostfixIncrement() {
   new Class1(). /*invoke: [exact=Class1]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/index_set.dart b/tests/compiler/dart2js/inference/data/index_set.dart
index 2e18237..fe5ec45 100644
--- a/tests/compiler/dart2js/inference/data/index_set.dart
+++ b/tests/compiler/dart2js/inference/data/index_set.dart
@@ -6,7 +6,7 @@
 // Update to a singleton list.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexSetSingle:[exact=JSUInt31]*/
+/*member: listIndexSetSingle:[exact=JSUInt31]*/
 listIndexSetSingle() {
   var list = [0];
   return list
@@ -18,7 +18,7 @@
 // Update to a list with multiple elements.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexSetMultiple:[exact=JSUInt31]*/
+/*member: listIndexSetMultiple:[exact=JSUInt31]*/
 listIndexSetMultiple() {
   var list = [0, 1, 2, 3];
   return list
@@ -30,7 +30,7 @@
 // Update to a list with an out-of-range index.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexSetBad:[exact=JSUInt31]*/
+/*member: listIndexSetBad:[exact=JSUInt31]*/
 listIndexSetBad() {
   var list = [0, 1];
   return list
@@ -42,7 +42,7 @@
 // Update to a list with mixed element types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: listIndexSetMixed:[exact=JSUInt31]*/
+/*member: listIndexSetMixed:[exact=JSUInt31]*/
 listIndexSetMixed() {
   dynamic list = [''];
   return list
@@ -54,7 +54,7 @@
 // Update to a empty map.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateEmpty:[exact=JSUInt31]*/
+/*member: mapUpdateEmpty:[exact=JSUInt31]*/
 mapUpdateEmpty() {
   var map = {};
   return map
@@ -66,7 +66,7 @@
 // Update to a singleton map.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateSingle:[exact=JSUInt31]*/
+/*member: mapUpdateSingle:[exact=JSUInt31]*/
 mapUpdateSingle() {
   var map = {0: 1};
   return map
@@ -78,7 +78,7 @@
 // Update to a map with multiple entries.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateMultiple:[exact=JSUInt31]*/
+/*member: mapUpdateMultiple:[exact=JSUInt31]*/
 mapUpdateMultiple() {
   var map = {0: 1, 2: 3, 4: 5};
   return map
@@ -90,7 +90,7 @@
 // Update to a map with a missing key.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateMissing:[exact=JSUInt31]*/
+/*member: mapUpdateMissing:[exact=JSUInt31]*/
 mapUpdateMissing() {
   var map = {0: 1};
   return map
@@ -102,7 +102,7 @@
 // Update to a map with mixed key types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateMixedKeys:[exact=JSUInt31]*/
+/*member: mapUpdateMixedKeys:[exact=JSUInt31]*/
 mapUpdateMixedKeys() {
   dynamic map = {'': 2};
   return map
@@ -114,7 +114,7 @@
 // Update to a map with mixed value types.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: mapUpdateMixedValues:[exact=JSUInt31]*/
+/*member: mapUpdateMixedValues:[exact=JSUInt31]*/
 mapUpdateMixedValues() {
   dynamic map = {2: ''};
   return map
@@ -126,7 +126,7 @@
 // Update to an empty map with String keys.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryUpdateEmpty:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryUpdateEmpty:Value([exact=JSString], value: "bar")*/
 dictionaryUpdateEmpty() {
   var map = {};
   return map
@@ -138,7 +138,7 @@
 // Update to a singleton map with String keys with a new value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryUpdateSingle:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryUpdateSingle:Value([exact=JSString], value: "boz")*/
 dictionaryUpdateSingle() {
   var map = {'foo': 'bar'};
   return map
@@ -150,7 +150,7 @@
 // Update to a singleton map with String keys with the same value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryReUpdateSingle:Value([exact=JSString], value: "bar")*/
+/*member: dictionaryReUpdateSingle:Value([exact=JSString], value: "bar")*/
 dictionaryReUpdateSingle() {
   var map = {'foo': 'bar'};
   return map
@@ -162,7 +162,7 @@
 // Update to a map with String keys.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: dictionaryUpdateMultiple:Value([exact=JSString], value: "boz")*/
+/*member: dictionaryUpdateMultiple:Value([exact=JSString], value: "boz")*/
 dictionaryUpdateMultiple() {
   var map = {'foo': 'bar'};
   return map
@@ -174,7 +174,7 @@
 // Update to a string-to-int map.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: intDictionaryUpdateSingle:[exact=JSUInt31]*/
+/*member: intDictionaryUpdateSingle:[exact=JSUInt31]*/
 intDictionaryUpdateSingle() {
   var map = {};
   return map
@@ -182,7 +182,7 @@
       ['foo'] = 0;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   listIndexSetSingle();
   listIndexSetMultiple();
diff --git a/tests/compiler/dart2js/inference/data/init_get.dart b/tests/compiler/dart2js/inference/data/init_get.dart
index ec8e9a2..e940e1e 100644
--- a/tests/compiler/dart2js/inference/data/init_get.dart
+++ b/tests/compiler/dart2js/inference/data/init_get.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*element: getter:[exact=JSUInt31]*/
+/*member: getter:[exact=JSUInt31]*/
 get getter => 42;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   getGetter();
   getGetterInFinalField();
@@ -20,53 +20,53 @@
 // Access a top level getter directly.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: getGetter:[exact=JSUInt31]*/
+/*member: getGetter:[exact=JSUInt31]*/
 getGetter() => getter;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Access a top level getter in a final instance field initializer.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[exact=JSUInt31]*/
+  /*member: Class1.field:[exact=JSUInt31]*/
   final field = getter;
 }
 
-/*element: getGetterInFinalField:[exact=JSUInt31]*/
+/*member: getGetterInFinalField:[exact=JSUInt31]*/
 getGetterInFinalField() => new Class1(). /*[exact=Class1]*/ field;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Access a top level getter in a non-final instance field initializer.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[exact=JSUInt31]*/
+  /*member: Class2.field:[exact=JSUInt31]*/
   var field = getter;
 }
 
-/*element: getGetterInField:[exact=JSUInt31]*/
+/*member: getGetterInField:[exact=JSUInt31]*/
 getGetterInField() => new Class2(). /*[exact=Class2]*/ field;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Access a top level getter in a final top level field initializer.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field1:[null|exact=JSUInt31]*/
+/*member: _field1:[null|exact=JSUInt31]*/
 final _field1 = getter;
 
-/*element: getGetterInFinalTopLevelField:[null|exact=JSUInt31]*/
+/*member: getGetterInFinalTopLevelField:[null|exact=JSUInt31]*/
 getGetterInFinalTopLevelField() => _field1;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Access a top level getter in a non-final top level field initializer.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field2:[null|exact=JSUInt31]*/
+/*member: _field2:[null|exact=JSUInt31]*/
 var _field2 = getter;
 
-/*element: getGetterInTopLevelField:[null|exact=JSUInt31]*/
+/*member: getGetterInTopLevelField:[null|exact=JSUInt31]*/
 getGetterInTopLevelField() => _field2;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -74,11 +74,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class Class3 {
-  /*element: Class3.field:[null|exact=JSUInt31]*/
+  /*member: Class3.field:[null|exact=JSUInt31]*/
   static final field = getter;
 }
 
-/*element: getGetterInFinalStaticField:[null|exact=JSUInt31]*/
+/*member: getGetterInFinalStaticField:[null|exact=JSUInt31]*/
 getGetterInFinalStaticField() => Class3.field;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -86,9 +86,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class Class4 {
-  /*element: Class4.field:[null|exact=JSUInt31]*/
+  /*member: Class4.field:[null|exact=JSUInt31]*/
   static var field = getter;
 }
 
-/*element: getGetterInStaticField:[null|exact=JSUInt31]*/
+/*member: getGetterInStaticField:[null|exact=JSUInt31]*/
 getGetterInStaticField() => Class4.field;
diff --git a/tests/compiler/dart2js/inference/data/initializer.dart b/tests/compiler/dart2js/inference/data/initializer.dart
index 933f92e..b059fef 100644
--- a/tests/compiler/dart2js/inference/data/initializer.dart
+++ b/tests/compiler/dart2js/inference/data/initializer.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   initializingFormal();
   fieldInitializer();
@@ -15,14 +15,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.field:[exact=JSUInt31]*/
+  /*member: Class1.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: Class1.:[exact=Class1]*/
+  /*member: Class1.:[exact=Class1]*/
   Class1(this. /*[exact=JSUInt31]*/ field);
 }
 
-/*element: initializingFormal:[exact=Class1]*/
+/*member: initializingFormal:[exact=Class1]*/
 initializingFormal() => new Class1(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -30,14 +30,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field:[exact=JSUInt31]*/
+  /*member: Class2.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: Class2.:[exact=Class2]*/
+  /*member: Class2.:[exact=Class2]*/
   Class2(/*[exact=JSUInt31]*/ field) : this.field = field;
 }
 
-/*element: fieldInitializer:[exact=Class2]*/
+/*member: fieldInitializer:[exact=Class2]*/
 fieldInitializer() => new Class2(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -45,17 +45,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.field:[exact=JSUInt31]*/
+  /*member: Class3.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: Class3._:[exact=Class3]*/
+  /*member: Class3._:[exact=Class3]*/
   Class3._(this. /*[exact=JSUInt31]*/ field);
 
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   Class3(/*[exact=JSUInt31]*/ field) : this._(field);
 }
 
-/*element: thisInitializer:[exact=Class3]*/
+/*member: thisInitializer:[exact=Class3]*/
 thisInitializer() => new Class3(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -63,17 +63,17 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class SuperClass4 {
-  /*element: SuperClass4.field:[exact=JSUInt31]*/
+  /*member: SuperClass4.field:[exact=JSUInt31]*/
   var field;
 
-  /*element: SuperClass4.:[exact=Class4]*/
+  /*member: SuperClass4.:[exact=Class4]*/
   SuperClass4(this. /*[exact=JSUInt31]*/ field);
 }
 
 class Class4 extends SuperClass4 {
-  /*element: Class4.:[exact=Class4]*/
+  /*member: Class4.:[exact=Class4]*/
   Class4(/*[exact=JSUInt31]*/ field) : super(field);
 }
 
-/*element: superInitializer:[exact=Class4]*/
+/*member: superInitializer:[exact=Class4]*/
 superInitializer() => new Class4(0);
diff --git a/tests/compiler/dart2js/inference/data/instance.dart b/tests/compiler/dart2js/inference/data/instance.dart
index a38bd26..9559f1ba 100644
--- a/tests/compiler/dart2js/inference/data/instance.dart
+++ b/tests/compiler/dart2js/inference/data/instance.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   thisExact();
   thisSubclass();
@@ -17,29 +17,29 @@
 /// Return `this` of a class with no subclasses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.method:[exact=Class1]*/
+  /*member: Class1.method:[exact=Class1]*/
   method() => this;
 }
 
-/*element: thisExact:[exact=Class1]*/
+/*member: thisExact:[exact=Class1]*/
 thisExact() => new Class1(). /*invoke: [exact=Class1]*/ method();
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return `this` of a class with an instantiated subclass.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2a.:[exact=Class2a]*/
+/*member: Class2a.:[exact=Class2a]*/
 class Class2a {
-  /*element: Class2a.method:[subclass=Class2a]*/
+  /*member: Class2a.method:[subclass=Class2a]*/
   method() => this;
 }
 
-/*element: Class2b.:[exact=Class2b]*/
+/*member: Class2b.:[exact=Class2b]*/
 class Class2b extends Class2a {}
 
-/*element: thisSubclass:[subclass=Class2a]*/
+/*member: thisSubclass:[subclass=Class2a]*/
 thisSubclass() {
   new Class2b();
   return new Class2a(). /*invoke: [exact=Class2a]*/ method();
@@ -49,15 +49,15 @@
 /// Return `this` of a class with no instantiated subclasses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3a.:[exact=Class3a]*/
+/*member: Class3a.:[exact=Class3a]*/
 class Class3a {
-  /*element: Class3a.method:[exact=Class3a]*/
+  /*member: Class3a.method:[exact=Class3a]*/
   method() => this;
 }
 
 class Class3b extends Class3a {}
 
-/*element: thisSubclassExact:[exact=Class3a]*/
+/*member: thisSubclassExact:[exact=Class3a]*/
 thisSubclassExact() {
   return new Class3a(). /*invoke: [exact=Class3a]*/ method();
 }
@@ -66,16 +66,16 @@
 /// Return `this` of a class that is mixed into an instantiated class.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4a.:[exact=Class4a]*/
+/*member: Class4a.:[exact=Class4a]*/
 class Class4a {
-  /*element: Class4a.method:[subtype=Class4a]*/
+  /*member: Class4a.method:[subtype=Class4a]*/
   method() => this;
 }
 
-/*element: Class4b.:[exact=Class4b]*/
+/*member: Class4b.:[exact=Class4b]*/
 class Class4b extends Object with Class4a {}
 
-/*element: thisSubtype:[subtype=Class4a]*/
+/*member: thisSubtype:[subtype=Class4a]*/
 thisSubtype() {
   new Class4b();
   return new Class4a(). /*invoke: [exact=Class4a]*/ method();
@@ -85,15 +85,15 @@
 /// Return `this` of a class that is mixed into an uninstantiated class.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5a.:[exact=Class5a]*/
+/*member: Class5a.:[exact=Class5a]*/
 class Class5a {
-  /*element: Class5a.method:[exact=Class5a]*/
+  /*member: Class5a.method:[exact=Class5a]*/
   method() => this;
 }
 
 class Class5b extends Object with Class5a {}
 
-/*element: thisSubtypeExact:[exact=Class5a]*/
+/*member: thisSubtypeExact:[exact=Class5a]*/
 thisSubtypeExact() {
   return new Class5a(). /*invoke: [exact=Class5a]*/ method();
 }
@@ -102,16 +102,16 @@
 /// Return `this` of a mixed in class that is itself instantiated.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class6a.:[exact=Class6a]*/
+/*member: Class6a.:[exact=Class6a]*/
 class Class6a {
-  /*element: Class6a.method:[subtype=Class6a]*/
+  /*member: Class6a.method:[subtype=Class6a]*/
   method() => this;
 }
 
-/*element: Class6b.:[exact=Class6b]*/
+/*member: Class6b.:[exact=Class6b]*/
 class Class6b extends Object with Class6a {}
 
-/*element: thisSubtypeMixedIn:[subtype=Class6a]*/
+/*member: thisSubtypeMixedIn:[subtype=Class6a]*/
 thisSubtypeMixedIn() {
   new Class6a();
   return new Class6b(). /*invoke: [exact=Class6b]*/ method();
@@ -122,14 +122,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class7a {
-  /*element: Class7a.method:[exact=Class7b]*/
+  /*member: Class7a.method:[exact=Class7b]*/
   method() => this;
 }
 
-/*element: Class7b.:[exact=Class7b]*/
+/*member: Class7b.:[exact=Class7b]*/
 class Class7b extends Object with Class7a {}
 
-/*element: thisSubtypeExactMixedIn:[exact=Class7b]*/
+/*member: thisSubtypeExactMixedIn:[exact=Class7b]*/
 thisSubtypeExactMixedIn() {
   return new Class7b(). /*invoke: [exact=Class7b]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/issue13354.dart b/tests/compiler/dart2js/inference/data/issue13354.dart
index 24a47b0..a0c669e 100644
--- a/tests/compiler/dart2js/inference/data/issue13354.dart
+++ b/tests/compiler/dart2js/inference/data/issue13354.dart
@@ -4,25 +4,25 @@
 
 // Regression test for issue 13354.
 
-/*element: bar:[exact=JSUInt31]*/
+/*member: bar:[exact=JSUInt31]*/
 bar() => 42;
 
-/*element: baz:[subclass=Closure]*/
+/*member: baz:[subclass=Closure]*/
 baz() => bar;
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
-  /*element: A.foo:[exact=JSUInt31]*/
+  /*member: A.foo:[exact=JSUInt31]*/
   foo() => 42;
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:[subclass=Closure]*/
+  /*member: B.foo:[subclass=Closure]*/
   foo() => super.foo;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   baz();
   new B(). /*invoke: [exact=B]*/ foo();
diff --git a/tests/compiler/dart2js/inference/data/js_interop.dart b/tests/compiler/dart2js/inference/data/js_interop.dart
index e55c5dfe..2a0f3f9 100644
--- a/tests/compiler/dart2js/inference/data/js_interop.dart
+++ b/tests/compiler/dart2js/inference/data/js_interop.dart
@@ -7,7 +7,7 @@
 
 import 'package:js/js.dart';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   anonymousClass();
   jsInteropClass();
@@ -16,29 +16,29 @@
 @JS()
 @anonymous
 class Class1 {
-  /*element: Class1.:[null|subclass=Object]*/
+  /*member: Class1.:[null|subclass=Object]*/
   external factory Class1(
       {/*[exact=JSUInt31]*/ a, /*Value([exact=JSString], value: "")*/ b});
 }
 
-/*element: anonymousClass:[null|subclass=JavaScriptObject]*/
+/*member: anonymousClass:[null|subclass=JavaScriptObject]*/
 anonymousClass() => new Class1(a: 1, b: '');
 
 @JS()
 class JsInteropClass {
-  /*element: JsInteropClass.:[null|subclass=Object]*/
+  /*member: JsInteropClass.:[null|subclass=Object]*/
   external JsInteropClass();
 
-  /*element: JsInteropClass.getter:[null|subclass=Object]*/
+  /*member: JsInteropClass.getter:[null|subclass=Object]*/
   external int get getter;
 
   external void set setter(int /*[subclass=JSInt]*/ value);
 
-  /*element: JsInteropClass.method:[null|subclass=Object]*/
+  /*member: JsInteropClass.method:[null|subclass=Object]*/
   external int method(int /*[exact=JSUInt31]*/ a);
 }
 
-/*element: jsInteropClass:[subclass=JSInt]*/
+/*member: jsInteropClass:[subclass=JSInt]*/
 jsInteropClass() {
   JsInteropClass cls = new JsInteropClass();
   return cls. /*update: [null|subclass=JavaScriptObject]*/ setter =
diff --git a/tests/compiler/dart2js/inference/data/list.dart b/tests/compiler/dart2js/inference/data/list.dart
index 967ed10..2a650bd 100644
--- a/tests/compiler/dart2js/inference/data/list.dart
+++ b/tests/compiler/dart2js/inference/data/list.dart
@@ -4,7 +4,7 @@
 
 import 'dart:typed_data';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   emptyList();
   nullList();
@@ -29,66 +29,66 @@
   newUint8List();
 }
 
-/*element: emptyList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: emptyList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
 emptyList() => [];
 
-/*element: constList:Container([exact=JSUnmodifiableArray], element: [empty], length: 0)*/
+/*member: constList:Container([exact=JSUnmodifiableArray], element: [empty], length: 0)*/
 constList() => const [];
 
-/*element: nullList:Container([exact=JSExtendableArray], element: [null], length: 1)*/
+/*member: nullList:Container([exact=JSExtendableArray], element: [null], length: 1)*/
 nullList() => [null];
 
-/*element: constNullList:Container([exact=JSUnmodifiableArray], element: [null], length: 1)*/
+/*member: constNullList:Container([exact=JSUnmodifiableArray], element: [null], length: 1)*/
 constNullList() => const [null];
 
-/*element: intList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
+/*member: intList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
 intList() => [1, 2, 3];
 
-/*element: newList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+/*member: newList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
 newList() => new List();
 
-/*element: newFixedList:Container([exact=JSFixedArray], element: [null], length: 2)*/
+/*member: newFixedList:Container([exact=JSFixedArray], element: [null], length: 2)*/
 newFixedList() => new List(2);
 
-/*element: newFilledList:Container([exact=JSFixedArray], element: Value([exact=JSString], value: ""), length: 3)*/
+/*member: newFilledList:Container([exact=JSFixedArray], element: Value([exact=JSString], value: ""), length: 3)*/
 newFilledList() => new List.filled(3, '');
 
-/*element: newFloat32x4List:[exact=NativeFloat32x4List]*/
+/*member: newFloat32x4List:[exact=NativeFloat32x4List]*/
 newFloat32x4List() => new Float32x4List(4);
 
-/*element: newInt32x4List:[exact=NativeInt32x4List]*/
+/*member: newInt32x4List:[exact=NativeInt32x4List]*/
 newInt32x4List() => new Int32x4List(5);
 
-/*element: newFloat64x2List:[exact=NativeFloat64x2List]*/
+/*member: newFloat64x2List:[exact=NativeFloat64x2List]*/
 newFloat64x2List() => new Float64x2List(6);
 
-/*element: newFloat32List:Container([exact=NativeFloat32List], element: [subclass=JSNumber], length: 7)*/
+/*member: newFloat32List:Container([exact=NativeFloat32List], element: [subclass=JSNumber], length: 7)*/
 newFloat32List() => new Float32List(7);
 
-/*element: newFloat64List:Container([exact=NativeFloat64List], element: [subclass=JSNumber], length: 8)*/
+/*member: newFloat64List:Container([exact=NativeFloat64List], element: [subclass=JSNumber], length: 8)*/
 newFloat64List() => new Float64List(8);
 
-/*element: newInt16List:Container([exact=NativeInt16List], element: [subclass=JSInt], length: 9)*/
+/*member: newInt16List:Container([exact=NativeInt16List], element: [subclass=JSInt], length: 9)*/
 newInt16List() => new Int16List(9);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Create a Int32List using an unchanged non-final top-level field as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field1:[exact=JSUInt31]*/
+/*member: _field1:[exact=JSUInt31]*/
 var _field1 = 10;
 
-/*element: newInt32List:Container([exact=NativeInt32List], element: [subclass=JSInt], length: 10)*/
+/*member: newInt32List:Container([exact=NativeInt32List], element: [subclass=JSInt], length: 10)*/
 newInt32List() => new Int32List(_field1);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Create a Int32List using a changed non-final top-level field as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field1b:[subclass=JSPositiveInt]*/
+/*member: _field1b:[subclass=JSPositiveInt]*/
 var _field1b = 10;
 
-/*element: newInt32List2:Container([exact=NativeInt32List], element: [subclass=JSInt], length: null)*/
+/*member: newInt32List2:Container([exact=NativeInt32List], element: [subclass=JSInt], length: null)*/
 newInt32List2() {
   _field1b /*invoke: [subclass=JSPositiveInt]*/ ++;
   return new Int32List(_field1b);
@@ -98,35 +98,35 @@
 // Create a Int8List using a final top-level field as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field2:[exact=JSUInt31]*/
+/*member: _field2:[exact=JSUInt31]*/
 final _field2 = 11;
 
-/*element: newInt8List:Container([exact=NativeInt8List], element: [subclass=JSInt], length: 11)*/
+/*member: newInt8List:Container([exact=NativeInt8List], element: [subclass=JSInt], length: 11)*/
 newInt8List() => new Int8List(_field2);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Create a Uint16List using a const top-level field as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*strong.element: _field3:[exact=JSUInt31]*/
-/*omit.element: _field3:[exact=JSUInt31]*/
+/*strong.member: _field3:[exact=JSUInt31]*/
+/*omit.member: _field3:[exact=JSUInt31]*/
 const _field3 = 12;
 
-/*element: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
+/*member: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
 newUint16List() => new Uint16List(_field3);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Create a Uint32List using a parenthesized literal int as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: 13)*/
+/*member: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: 13)*/
 newUint32List() => new Uint32List((13));
 
 ////////////////////////////////////////////////////////////////////////////////
 // Create a Uint8ClampedList using a constant multiplication as length.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: newUint8ClampedList:Container([exact=NativeUint8ClampedList], element: [exact=JSUInt31], length: null)*/
+/*member: newUint8ClampedList:Container([exact=NativeUint8ClampedList], element: [exact=JSUInt31], length: null)*/
 newUint8ClampedList() =>
     new Uint8ClampedList(2 /*invoke: [exact=JSUInt31]*/ * 7);
 
@@ -135,10 +135,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 abstract class Class1 {
-  /*strong.element: Class1.field:[exact=JSUInt31]*/
-  /*omit.element: Class1.field:[exact=JSUInt31]*/
+  /*strong.member: Class1.field:[exact=JSUInt31]*/
+  /*omit.member: Class1.field:[exact=JSUInt31]*/
   static const field = 15;
 }
 
-/*element: newUint8List:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 15)*/
+/*member: newUint8List:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 15)*/
 newUint8List() => new Uint8List(Class1.field);
diff --git a/tests/compiler/dart2js/inference/data/list_huge.dart b/tests/compiler/dart2js/inference/data/list_huge.dart
new file mode 100644
index 0000000..3ef9fba
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/list_huge.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2019, 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.
+
+// Test for Container type for Lists with huge or negative sizes.
+
+/*member: main:[null]*/
+main() {
+  hugeList1();
+  hugeList2();
+  hugeList3();
+  hugeList4();
+}
+
+/*member: _huge1:[subclass=JSPositiveInt]*/
+final _huge1 = 5000000000;
+
+/*member: hugeList1:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList1() => List(_huge1);
+
+/*strong.member: _huge2a:[subclass=JSPositiveInt]*/
+/*omit.member: _huge2a:[subclass=JSPositiveInt]*/
+const _huge2a = 10000000000
+    /*strong.invoke: [subclass=JSPositiveInt]*/
+    /*omit.invoke: [subclass=JSPositiveInt]*/
+    *
+    10000000000;
+
+/*strong.member: _huge2b:[null|subclass=JSPositiveInt]*/
+/*omit.member: _huge2b:[null|subclass=JSPositiveInt]*/
+/*strongConst.member: _huge2b:[subclass=JSPositiveInt]*/
+/*omitConst.member: _huge2b:[subclass=JSPositiveInt]*/
+final _huge2b = _huge2a;
+
+/*member: hugeList2:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList2() => List(_huge2b);
+
+/*strong.member: _huge3a:[subclass=JSInt]*/
+/*omit.member: _huge3a:[subclass=JSInt]*/
+const _huge3a =
+    /*strong.invoke: [exact=JSUInt31]*/
+    /*omit.invoke: [exact=JSUInt31]*/
+    -10000000;
+
+/*strong.member: _huge3b:[null|subclass=JSInt]*/
+/*omit.member: _huge3b:[null|subclass=JSInt]*/
+/*strongConst.member: _huge3b:[subclass=JSInt]*/
+/*omitConst.member: _huge3b:[subclass=JSInt]*/
+final _huge3b = _huge3a;
+
+/*member: hugeList3:Container([exact=JSFixedArray], element: [null], length: null)*/
+hugeList3() => List(_huge3b);
+
+// 'Small' limits are still tracked.
+
+/*member: _huge4:[exact=JSUInt31]*/
+final _huge4 = 10000000;
+
+/*member: hugeList4:Container([exact=JSFixedArray], element: [null], length: 10000000)*/
+hugeList4() => List(_huge4);
diff --git a/tests/compiler/dart2js/inference/data/list_tracer2.dart b/tests/compiler/dart2js/inference/data/list_tracer2.dart
index 356c791..37e2e2c 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer2.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer2.dart
@@ -5,10 +5,10 @@
 // We used to always nullify the element type of a list we are tracing in
 // the presence of a fixed length list constructor call.
 
-/*element: myList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: myList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 var myList = [42];
 
-/*element: main:[exact=JSUInt31]*/
+/*member: main:[exact=JSUInt31]*/
 main() {
   /// ignore: unused_local_variable
   var a = new List(42);
diff --git a/tests/compiler/dart2js/inference/data/list_tracer3.dart b/tests/compiler/dart2js/inference/data/list_tracer3.dart
index 7782208..2c56101 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer3.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer3.dart
@@ -5,13 +5,13 @@
 // We used to always nullify the element type of a list we are tracing in
 // the presence of a fixed length list constructor call.
 
-/*element: myList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [subclass=JSNumber]), length: null)*/
+/*member: myList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [subclass=JSNumber]), length: null)*/
 var myList = [];
 
-/*element: otherList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
+/*member: otherList:Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
 var otherList = ['foo', 42];
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   dynamic a = otherList
       /*Container([exact=JSExtendableArray], element: Union([exact=JSString], [exact=JSUInt31]), length: 2)*/
diff --git a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
index c528722..460ca33 100644
--- a/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
+++ b/tests/compiler/dart2js/inference/data/list_tracer_typed_data_length.dart
@@ -7,13 +7,13 @@
 // TODO(johnniwinther): Fix inference for strong mode. List elements should not
 // be [empty].
 
-/*element: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
+/*member: myList:Container([null|exact=NativeFloat32List], element: [subclass=JSNumber], length: 42)*/
 var myList = new Float32List(42);
 
-/*element: myOtherList:Container([null|exact=NativeUint8List], element: [exact=JSUInt31], length: 32)*/
+/*member: myOtherList:Container([null|exact=NativeUint8List], element: [exact=JSUInt31], length: 32)*/
 var myOtherList = new Uint8List(32);
 
-/*element: main:[subclass=JSNumber]*/
+/*member: main:[subclass=JSNumber]*/
 main() {
   // ignore: unused_local_variable
   var a = new Float32List(9);
diff --git a/tests/compiler/dart2js/inference/data/local_functions.dart b/tests/compiler/dart2js/inference/data/local_functions.dart
index 6570789..6d08b0a 100644
--- a/tests/compiler/dart2js/inference/data/local_functions.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   namedLocalFunctionInvoke();
   unnamedLocalFunctionInvoke();
@@ -21,7 +21,7 @@
 // Invocation of a named local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: namedLocalFunctionInvoke:[exact=JSUInt31]*/
+/*member: namedLocalFunctionInvoke:[exact=JSUInt31]*/
 namedLocalFunctionInvoke() {
   /*[exact=JSUInt31]*/ local() => 0;
   return local();
@@ -31,7 +31,7 @@
 // Invocation of an unnamed local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: unnamedLocalFunctionInvoke:[null|subclass=JSInt]*/
+/*member: unnamedLocalFunctionInvoke:[null|subclass=JSInt]*/
 unnamedLocalFunctionInvoke() {
   var local = /*[exact=JSUInt31]*/ () => 0;
   return local();
@@ -41,7 +41,7 @@
 // Access of a named local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: namedLocalFunctionGet:[subclass=Closure]*/
+/*member: namedLocalFunctionGet:[subclass=Closure]*/
 namedLocalFunctionGet() {
   /*[exact=JSUInt31]*/ local() => 0;
   return local;
@@ -51,7 +51,7 @@
 // Call a named local function recursively.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: recursiveLocalFunction:[subclass=Closure]*/
+/*member: recursiveLocalFunction:[subclass=Closure]*/
 recursiveLocalFunction() {
   /*[subclass=Closure]*/ local() => local;
   return local();
@@ -61,7 +61,7 @@
 // Call a named local function with a missing argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: namedLocalFunctionInvokeMissingArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeMissingArgument:[null|subclass=Object]*/
 @pragma('dart2js:disableFinal')
 namedLocalFunctionInvokeMissingArgument() {
   /*[exact=JSUInt31]*/ local(/*[empty]*/ x) => 0;
@@ -73,7 +73,7 @@
 // Call a named local function with an extra argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: namedLocalFunctionInvokeExtraArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeExtraArgument:[null|subclass=Object]*/
 @pragma('dart2js:disableFinal')
 namedLocalFunctionInvokeExtraArgument() {
   /*[exact=JSUInt31]*/ local() => 0;
@@ -85,7 +85,7 @@
 // Call a named local function with an extra named argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: namedLocalFunctionInvokeExtraNamedArgument:[null|subclass=Object]*/
+/*member: namedLocalFunctionInvokeExtraNamedArgument:[null|subclass=Object]*/
 @pragma('dart2js:disableFinal')
 namedLocalFunctionInvokeExtraNamedArgument() {
   /*[exact=JSUInt31]*/ local() => 0;
@@ -97,7 +97,7 @@
 // Implicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: closureToString:[exact=JSString]*/
+/*member: closureToString:[exact=JSString]*/
 closureToString() {
   var local = /*[null]*/ () {};
   local();
@@ -108,7 +108,7 @@
 // Explicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: closureCallToString:[exact=JSString]*/
+/*member: closureCallToString:[exact=JSString]*/
 closureCallToString() {
   var local = /*[null]*/ () {};
   local.call();
@@ -119,13 +119,13 @@
 // Operator == on the result of a parameter invocation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _callCompare:[subclass=Closure]*/
+/*member: _callCompare:[subclass=Closure]*/
 _callCompare(int /*[subclass=Closure]*/ compare({a, b})) {
   compare(a: 0, b: 1) /*invoke: [null|subclass=JSInt]*/ == 0;
   return compare;
 }
 
-/*element: callCompare:[null]*/
+/*member: callCompare:[null]*/
 callCompare() {
   _callCompare(/*[subclass=JSInt]*/
       ({/*[exact=JSUInt31]*/ a, /*[exact=JSUInt31]*/ b}) =>
@@ -136,19 +136,19 @@
 // Invocation on the result of a parameter invocation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.method1:[null]*/
+  /*member: Class1.method1:[null]*/
   method1() {}
 }
 
-/*element: _callClosure:[subclass=Closure]*/
+/*member: _callClosure:[subclass=Closure]*/
 _callClosure(/*[subclass=Closure]*/ f({c})) {
   f(c: new Class1()).method1();
   return f;
 }
 
-/*element: callClosure:[null]*/
+/*member: callClosure:[null]*/
 callClosure() {
   _callClosure(/*[exact=Class1]*/ ({/*[exact=Class1]*/ c}) => c);
 }
diff --git a/tests/compiler/dart2js/inference/data/local_functions_call.dart b/tests/compiler/dart2js/inference/data/local_functions_call.dart
index 586bf73..42cc5b1 100644
--- a/tests/compiler/dart2js/inference/data/local_functions_call.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions_call.dart
@@ -6,7 +6,7 @@
 // with a different expectancy because the closed world contains less '.call'
 // methods.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closureCallToString();
 }
@@ -15,7 +15,7 @@
 // Explicit .call on a local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: closureCallToString:[exact=JSString]*/
+/*member: closureCallToString:[exact=JSString]*/
 closureCallToString() {
   var local = /*[null]*/ () {};
   local.call();
diff --git a/tests/compiler/dart2js/inference/data/locals.dart b/tests/compiler/dart2js/inference/data/locals.dart
index 1e0839f..bf0f271 100644
--- a/tests/compiler/dart2js/inference/data/locals.dart
+++ b/tests/compiler/dart2js/inference/data/locals.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   uninitializedLocal();
   initializedLocal();
@@ -15,33 +15,33 @@
   complexAssignmentLocal();
 }
 
-/*element: uninitializedLocal:[null]*/
+/*member: uninitializedLocal:[null]*/
 uninitializedLocal() {
   var local;
   return local;
 }
 
-/*element: initializedLocal:[exact=JSUInt31]*/
+/*member: initializedLocal:[exact=JSUInt31]*/
 initializedLocal() {
   var local = 0;
   return local;
 }
 
-/*element: updatedLocal:[exact=JSUInt31]*/
+/*member: updatedLocal:[exact=JSUInt31]*/
 updatedLocal() {
   var local2;
   local2 = 0;
   return local2;
 }
 
-/*element: invokeLocal:[null]*/
+/*member: invokeLocal:[null]*/
 invokeLocal() {
   var local2 = 0;
   local2. /*invoke: [exact=JSUInt31]*/ toString();
   return null;
 }
 
-/*element: postfixLocal:[null]*/
+/*member: postfixLocal:[null]*/
 postfixLocal() {
   // ignore: UNUSED_LOCAL_VARIABLE
   var local2 = 0;
@@ -49,13 +49,13 @@
   return null;
 }
 
-/*element: postfixLocalUsed:[exact=JSUInt31]*/
+/*member: postfixLocalUsed:[exact=JSUInt31]*/
 postfixLocalUsed() {
   var local2 = 0;
   return local2 /*invoke: [exact=JSUInt31]*/ ++;
 }
 
-/*element: prefixLocal:[null]*/
+/*member: prefixLocal:[null]*/
 prefixLocal() {
   // ignore: UNUSED_LOCAL_VARIABLE
   var local2 = 0;
@@ -63,13 +63,13 @@
   return null;
 }
 
-/*element: prefixLocalUsed:[subclass=JSUInt32]*/
+/*member: prefixLocalUsed:[subclass=JSUInt32]*/
 prefixLocalUsed() {
   var local2 = 0;
   return /*invoke: [exact=JSUInt31]*/ ++local2;
 }
 
-/*element: complexAssignmentLocal:[subclass=JSUInt32]*/
+/*member: complexAssignmentLocal:[subclass=JSUInt32]*/
 complexAssignmentLocal() {
   var local2 = 0;
   return local2 /*invoke: [exact=JSUInt31]*/ += 42;
diff --git a/tests/compiler/dart2js/inference/data/locals_trust.dart b/tests/compiler/dart2js/inference/data/locals_trust.dart
index e57e350..0580621 100644
--- a/tests/compiler/dart2js/inference/data/locals_trust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_trust.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   trustLocals();
   trustFunctions();
@@ -13,13 +13,13 @@
 // Test that we trust the explicit type of a local.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _trustLocals:[exact=JSBool]*/ _trustLocals(
+/*member: _trustLocals:[exact=JSBool]*/ _trustLocals(
     int Function(int) /*[null|subclass=Closure]*/ f) {
   int c = f(0);
   return c /*invoke: [null|subclass=JSInt]*/ == 0;
 }
 
-/*element: trustLocals:[null]*/
+/*member: trustLocals:[null]*/
 trustLocals() {
   _trustLocals(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
   _trustLocals(null);
@@ -29,14 +29,14 @@
 // Test that we infer the type of a dynamic local from the type of the function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _trustFunctions:[exact=JSBool]*/
+/*member: _trustFunctions:[exact=JSBool]*/
 _trustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
   dynamic c = f(0);
   c = f(0);
   return c /*invoke: [null|subclass=JSInt]*/ == 0;
 }
 
-/*element: trustFunctions:[null]*/
+/*member: trustFunctions:[null]*/
 trustFunctions() {
   _trustFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
   _trustFunctions(null);
@@ -46,13 +46,13 @@
 // Test that we infer the type of a 'var' local from the type of the function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _inferFromFunctions:[exact=JSBool]*/
+/*member: _inferFromFunctions:[exact=JSBool]*/
 _inferFromFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
   var c = f(0);
   return c /*invoke: [null|subclass=JSInt]*/ == 0;
 }
 
-/*element: inferFromFunctions:[null]*/
+/*member: inferFromFunctions:[null]*/
 inferFromFunctions() {
   _inferFromFunctions(/*[exact=JSUInt31]*/ (/*[exact=JSUInt31]*/ o) => o);
   _inferFromFunctions(null);
diff --git a/tests/compiler/dart2js/inference/data/logical.dart b/tests/compiler/dart2js/inference/data/logical.dart
index 6a60279..ed24935 100644
--- a/tests/compiler/dart2js/inference/data/logical.dart
+++ b/tests/compiler/dart2js/inference/data/logical.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnTrue();
   returnFalse();
@@ -43,24 +43,24 @@
 /// Return `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnTrue:Value([exact=JSBool], value: true)*/
+/*member: returnTrue:Value([exact=JSBool], value: true)*/
 returnTrue() => true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return `false`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnFalse:Value([exact=JSBool], value: false)*/
+/*member: returnFalse:Value([exact=JSBool], value: false)*/
 returnFalse() => false;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return negation of a boolean value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _returnNot:[exact=JSBool]*/
+/*member: _returnNot:[exact=JSBool]*/
 _returnNot(/*[exact=JSBool]*/ o) => !o;
 
-/*element: returnNot:[null]*/
+/*member: returnNot:[null]*/
 returnNot() {
   _returnNot(true);
   _returnNot(false);
@@ -70,30 +70,30 @@
 /// Return negation of `false`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnNotFalse:[exact=JSBool]*/
+/*member: returnNotFalse:[exact=JSBool]*/
 returnNotFalse() => !false;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return negation of `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnNotTrue:[exact=JSBool]*/
+/*member: returnNotTrue:[exact=JSBool]*/
 returnNotTrue() => !true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return negation of `null`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnNotOfNull:[exact=JSBool]*/
+/*member: returnNotOfNull:[exact=JSBool]*/
 returnNotOfNull() => !null;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of an is test.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _returnIs:[exact=JSBool]*/
+/*member: _returnIs:[exact=JSBool]*/
 _returnIs(/*[null|exact=JSUInt31]*/ o) => o is int;
 
-/*element: returnIs:[null]*/
+/*member: returnIs:[null]*/
 returnIs() {
   _returnIs(null);
   _returnIs(1);
@@ -102,22 +102,22 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of an is `int` test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: returnIsOneInt:[exact=JSBool]*/
+/*member: returnIsOneInt:[exact=JSBool]*/
 returnIsOneInt() => 1 is int;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of an is `int` test known to be false.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: returnIsNullInt:[exact=JSBool]*/
+/*member: returnIsNullInt:[exact=JSBool]*/
 returnIsNullInt() => null is int;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of a negated is test.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: _returnNotIs:[exact=JSBool]*/
+/*member: _returnNotIs:[exact=JSBool]*/
 _returnNotIs(/*[null|exact=JSUInt31]*/ o) => o is! int;
 
-/*element: returnNotIs:[null]*/
+/*member: returnNotIs:[null]*/
 returnNotIs() {
   _returnNotIs(null);
   _returnNotIs(1);
@@ -126,23 +126,23 @@
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of a negated is `int` test known to be false.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotIsOneInt:[exact=JSBool]*/
+/*member: returnNotIsOneInt:[exact=JSBool]*/
 returnNotIsOneInt() => 1 is! int;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return value of a negated is `int` test known to be true.
 ////////////////////////////////////////////////////////////////////////////////
-/*element: returnNotIsNullInt:[exact=JSBool]*/
+/*member: returnNotIsNullInt:[exact=JSBool]*/
 returnNotIsNullInt() => null is! int;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical and of booleans values.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _returnLogicalAnd:[exact=JSBool]*/
+/*member: _returnLogicalAnd:[exact=JSBool]*/
 _returnLogicalAnd(/*[exact=JSBool]*/ a, /*[exact=JSBool]*/ b) => a && b;
 
-/*element: returnLogicalAnd:[null]*/
+/*member: returnLogicalAnd:[null]*/
 returnLogicalAnd() {
   _returnLogicalAnd(true, true);
   _returnLogicalAnd(false, false);
@@ -152,14 +152,14 @@
 /// Return logical and of `true` && `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalAndTrueTrue:[exact=JSBool]*/
+/*member: returnLogicalAndTrueTrue:[exact=JSBool]*/
 returnLogicalAndTrueTrue() => true && true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical and of `false` && `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalAndFalseTrue:[exact=JSBool]*/
+/*member: returnLogicalAndFalseTrue:[exact=JSBool]*/
 /// ignore: dead_code
 returnLogicalAndFalseTrue() => false && true;
 
@@ -167,25 +167,25 @@
 /// Return logical and of `null` && `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalAndNullTrue:[exact=JSBool]*/
+/*member: returnLogicalAndNullTrue:[exact=JSBool]*/
 returnLogicalAndNullTrue() => null && true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical and of is test and use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:Value([exact=JSBool], value: true)*/
+  /*member: Class1.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalAndIs:[exact=JSBool]*/
+/*member: _returnLogicalAndIs:[exact=JSBool]*/
 _returnLogicalAndIs(/*[null|exact=Class1]*/ o) {
   return o is Class1 && o. /*[exact=Class1]*/ field;
 }
 
-/*element: returnLogicalAndIs:[null]*/
+/*member: returnLogicalAndIs:[null]*/
 returnLogicalAndIs() {
   _returnLogicalAndIs(new Class1());
   _returnLogicalAndIs(null);
@@ -195,20 +195,20 @@
 /// Return logical and of is-not test and use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:Value([exact=JSBool], value: true)*/
+  /*member: Class2.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalAndIsNot:[exact=JSBool]*/
+/*member: _returnLogicalAndIsNot:[exact=JSBool]*/
 _returnLogicalAndIsNot(/*[null|exact=Class2]*/ o) {
   // TODO(johnniwinther): Use negative type knowledge to show that the receiver
   // is [null].
   return o is! Class2 && o. /*[null|exact=Class2]*/ field;
 }
 
-/*element: returnLogicalAndIsNot:[null]*/
+/*member: returnLogicalAndIsNot:[null]*/
 returnLogicalAndIsNot() {
   _returnLogicalAndIsNot(new Class2());
   _returnLogicalAndIsNot(null);
@@ -218,18 +218,18 @@
 /// Return logical and of null test and use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.field:Value([exact=JSBool], value: true)*/
+  /*member: Class3.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalAndNull:[exact=JSBool]*/
+/*member: _returnLogicalAndNull:[exact=JSBool]*/
 _returnLogicalAndNull(/*[null|exact=Class3]*/ o) {
   return o == null && o. /*[null]*/ field;
 }
 
-/*element: returnLogicalAndNull:[null]*/
+/*member: returnLogicalAndNull:[null]*/
 returnLogicalAndNull() {
   _returnLogicalAndNull(new Class3());
   _returnLogicalAndNull(null);
@@ -239,18 +239,18 @@
 /// Return logical and of not null test and use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field:Value([exact=JSBool], value: true)*/
+  /*member: Class4.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalAndNotNull:[exact=JSBool]*/
+/*member: _returnLogicalAndNotNull:[exact=JSBool]*/
 _returnLogicalAndNotNull(/*[null|exact=Class4]*/ o) {
   return o != null && o. /*[exact=Class4]*/ field;
 }
 
-/*element: returnLogicalAndNotNull:[null]*/
+/*member: returnLogicalAndNotNull:[null]*/
 returnLogicalAndNotNull() {
   _returnLogicalAndNotNull(new Class4());
   _returnLogicalAndNotNull(null);
@@ -260,10 +260,10 @@
 /// Return logical or of booleans values.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _returnLogicalOr:[exact=JSBool]*/
+/*member: _returnLogicalOr:[exact=JSBool]*/
 _returnLogicalOr(/*[exact=JSBool]*/ a, /*[exact=JSBool]*/ b) => a || b;
 
-/*element: returnLogicalOr:[null]*/
+/*member: returnLogicalOr:[null]*/
 returnLogicalOr() {
   _returnLogicalOr(true, true);
   _returnLogicalOr(false, false);
@@ -273,41 +273,41 @@
 /// Return logical or of `false` || `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalOrFalseTrue:[exact=JSBool]*/
+/*member: returnLogicalOrFalseTrue:[exact=JSBool]*/
 returnLogicalOrFalseTrue() => false || true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical or of `false` || `false`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalOrFalseFalse:[exact=JSBool]*/
+/*member: returnLogicalOrFalseFalse:[exact=JSBool]*/
 returnLogicalOrFalseFalse() => false || false;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical or of `null` || `true`.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: returnLogicalOrNullTrue:[exact=JSBool]*/
+/*member: returnLogicalOrNullTrue:[exact=JSBool]*/
 returnLogicalOrNullTrue() => null || true;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return logical or of is test or use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
 class Class5 {
-  /*element: Class5.field:Value([exact=JSBool], value: true)*/
+  /*member: Class5.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalOrIs:[exact=JSBool]*/
+/*member: _returnLogicalOrIs:[exact=JSBool]*/
 _returnLogicalOrIs(/*[null|exact=Class5]*/ o) {
   // TODO(johnniwinther): Use negative type knowledge to show that the receiver
   // is [null].
   return o is Class5 || o. /*[null|exact=Class5]*/ field;
 }
 
-/*element: returnLogicalOrIs:[null]*/
+/*member: returnLogicalOrIs:[null]*/
 returnLogicalOrIs() {
   _returnLogicalOrIs(new Class5());
   _returnLogicalOrIs(null);
@@ -317,18 +317,18 @@
 /// Return logical or of is-not test or use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
 class Class6 {
-  /*element: Class6.field:Value([exact=JSBool], value: true)*/
+  /*member: Class6.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalOrIsNot:[exact=JSBool]*/
+/*member: _returnLogicalOrIsNot:[exact=JSBool]*/
 _returnLogicalOrIsNot(/*[null|exact=Class6]*/ o) {
   return o is! Class6 || o. /*[exact=Class6]*/ field;
 }
 
-/*element: returnLogicalOrIsNot:[null]*/
+/*member: returnLogicalOrIsNot:[null]*/
 returnLogicalOrIsNot() {
   _returnLogicalOrIsNot(new Class6());
   _returnLogicalOrIsNot(null);
@@ -338,18 +338,18 @@
 /// Return logical or of null test or use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
 class Class7 {
-  /*element: Class7.field:Value([exact=JSBool], value: true)*/
+  /*member: Class7.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalOrNull:[exact=JSBool]*/
+/*member: _returnLogicalOrNull:[exact=JSBool]*/
 _returnLogicalOrNull(/*[null|exact=Class7]*/ o) {
   return o == null || o. /*[exact=Class7]*/ field;
 }
 
-/*element: returnLogicalOrNull:[null]*/
+/*member: returnLogicalOrNull:[null]*/
 returnLogicalOrNull() {
   _returnLogicalOrNull(new Class7());
   _returnLogicalOrNull(null);
@@ -359,18 +359,18 @@
 /// Return logical or of not null test or use.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
 class Class8 {
-  /*element: Class8.field:Value([exact=JSBool], value: true)*/
+  /*member: Class8.field:Value([exact=JSBool], value: true)*/
   final bool field = true;
 }
 
-/*element: _returnLogicalOrNotNull:[exact=JSBool]*/
+/*member: _returnLogicalOrNotNull:[exact=JSBool]*/
 _returnLogicalOrNotNull(/*[null|exact=Class8]*/ o) {
   return o != null || o. /*[null]*/ field;
 }
 
-/*element: returnLogicalOrNotNull:[null]*/
+/*member: returnLogicalOrNotNull:[null]*/
 returnLogicalOrNotNull() {
   _returnLogicalOrNotNull(new Class8());
   _returnLogicalOrNotNull(null);
diff --git a/tests/compiler/dart2js/inference/data/logical_if.dart b/tests/compiler/dart2js/inference/data/logical_if.dart
index a950eb5..ba19f3a 100644
--- a/tests/compiler/dart2js/inference/data/logical_if.dart
+++ b/tests/compiler/dart2js/inference/data/logical_if.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   promotedIfThen();
   promotedIfThenElse();
@@ -30,17 +30,17 @@
 // Test if-then statement with is-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {}
 
-/*element: _promotedIfThen:[null]*/
+/*member: _promotedIfThen:[null]*/
 _promotedIfThen(/*Union([exact=Class1], [exact=JSUInt31])*/ o) {
   if (o is Class1) {
     o. /*invoke: [exact=Class1]*/ toString();
   }
 }
 
-/*element: promotedIfThen:[null]*/
+/*member: promotedIfThen:[null]*/
 promotedIfThen() {
   _promotedIfThen(0);
   _promotedIfThen(new Class1());
@@ -50,10 +50,10 @@
 // Test if-then-else statement with is-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {}
 
-/*element: _promotedIfThenElse:[null]*/
+/*member: _promotedIfThenElse:[null]*/
 _promotedIfThenElse(/*Union([exact=Class2], [exact=JSUInt31])*/ o) {
   if (o is Class2) {
     o. /*invoke: [exact=Class2]*/ toString();
@@ -64,7 +64,7 @@
   }
 }
 
-/*element: promotedIfThenElse:[null]*/
+/*member: promotedIfThenElse:[null]*/
 promotedIfThenElse() {
   _promotedIfThenElse(0);
   _promotedIfThenElse(new Class2());
@@ -74,10 +74,10 @@
 // Test if-then-else statement with negated is-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {}
 
-/*element: _promotedNotIfThenElse:[null]*/
+/*member: _promotedNotIfThenElse:[null]*/
 _promotedNotIfThenElse(/*Union([exact=Class3], [exact=JSUInt31])*/ o) {
   if (o is! Class3) {
     o. /*invoke: Union([exact=Class3], [exact=JSUInt31])*/ toString();
@@ -86,7 +86,7 @@
   }
 }
 
-/*element: promotedNotIfThenElse:[null]*/
+/*member: promotedNotIfThenElse:[null]*/
 promotedNotIfThenElse() {
   _promotedNotIfThenElse(0);
   _promotedNotIfThenElse(new Class3());
@@ -96,10 +96,10 @@
 // Test if-then statement with is-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {}
 
-/*element: _promotedAndIfThen:[null]*/
+/*member: _promotedAndIfThen:[null]*/
 _promotedAndIfThen(
     /*Union([exact=Class4], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -108,7 +108,7 @@
   }
 }
 
-/*element: promotedAndIfThen:[null]*/
+/*member: promotedAndIfThen:[null]*/
 promotedAndIfThen() {
   _promotedAndIfThen(0, true);
   _promotedAndIfThen(new Class4(), false);
@@ -118,10 +118,10 @@
 // Test if-then-else statement with is-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
 class Class5 {}
 
-/*element: _promotedAndIfThenElse:[null]*/
+/*member: _promotedAndIfThenElse:[null]*/
 _promotedAndIfThenElse(
     /*Union([exact=Class5], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -134,7 +134,7 @@
   }
 }
 
-/*element: promotedAndIfThenElse:[null]*/
+/*member: promotedAndIfThenElse:[null]*/
 promotedAndIfThenElse() {
   _promotedAndIfThenElse(0, true);
   _promotedAndIfThenElse(new Class5(), false);
@@ -144,10 +144,10 @@
 // Test if-then-else statement with negated is-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
 class Class6 {}
 
-/*element: _promotedNotAndIfThenElse:[null]*/
+/*member: _promotedNotAndIfThenElse:[null]*/
 _promotedNotAndIfThenElse(
     /*Union([exact=Class6], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -158,7 +158,7 @@
   }
 }
 
-/*element: promotedNotAndIfThenElse:[null]*/
+/*member: promotedNotAndIfThenElse:[null]*/
 promotedNotAndIfThenElse() {
   _promotedNotAndIfThenElse(0, true);
   _promotedNotAndIfThenElse(new Class6(), false);
@@ -168,10 +168,10 @@
 // Test if-then statement with is-test in ||
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
 class Class7 {}
 
-/*element: _promotedOrIfThen:[null]*/
+/*member: _promotedOrIfThen:[null]*/
 _promotedOrIfThen(
     /*Union([exact=Class7], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -180,7 +180,7 @@
   }
 }
 
-/*element: promotedOrIfThen:[null]*/
+/*member: promotedOrIfThen:[null]*/
 promotedOrIfThen() {
   _promotedOrIfThen(0, true);
   _promotedOrIfThen(new Class7(), false);
@@ -190,10 +190,10 @@
 // Test if-then-else statement with is-test in ||
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
 class Class8 {}
 
-/*element: _promotedOrIfThenElse:[null]*/
+/*member: _promotedOrIfThenElse:[null]*/
 _promotedOrIfThenElse(
     /*Union([exact=Class8], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -206,7 +206,7 @@
   }
 }
 
-/*element: promotedOrIfThenElse:[null]*/
+/*member: promotedOrIfThenElse:[null]*/
 promotedOrIfThenElse() {
   _promotedOrIfThenElse(0, true);
   _promotedOrIfThenElse(new Class8(), false);
@@ -216,10 +216,10 @@
 // Test if-then-else statement with negated is-test in ||
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class9.:[exact=Class9]*/
+/*member: Class9.:[exact=Class9]*/
 class Class9 {}
 
-/*element: _promotedNotOrIfThenElse:[null]*/
+/*member: _promotedNotOrIfThenElse:[null]*/
 _promotedNotOrIfThenElse(
     /*Union([exact=Class9], [exact=JSUInt31])*/ o,
     /*[exact=JSBool]*/ c) {
@@ -230,7 +230,7 @@
   }
 }
 
-/*element: promotedNotOrIfThenElse:[null]*/
+/*member: promotedNotOrIfThenElse:[null]*/
 promotedNotOrIfThenElse() {
   _promotedNotOrIfThenElse(0, true);
   _promotedNotOrIfThenElse(new Class9(), false);
@@ -240,10 +240,10 @@
 // Test if-then statement with doubly negated is-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class10.:[exact=Class10]*/
+/*member: Class10.:[exact=Class10]*/
 class Class10 {}
 
-/*element: _promotedNotNotIfThen:[null]*/
+/*member: _promotedNotNotIfThen:[null]*/
 _promotedNotNotIfThen(/*Union([exact=Class10], [exact=JSUInt31])*/ o) {
   if (!(o is! Class10)) {
     o
@@ -253,7 +253,7 @@
   }
 }
 
-/*element: promotedNotNotIfThen:[null]*/
+/*member: promotedNotNotIfThen:[null]*/
 promotedNotNotIfThen() {
   _promotedNotNotIfThen(0);
   _promotedNotNotIfThen(new Class10());
@@ -263,10 +263,10 @@
 // Test if-then-else statement with negated is-test in parentheses
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class11.:[exact=Class11]*/
+/*member: Class11.:[exact=Class11]*/
 class Class11 {}
 
-/*element: _promotedParenNotIfThenElse:[null]*/
+/*member: _promotedParenNotIfThenElse:[null]*/
 _promotedParenNotIfThenElse(
     /*Union([exact=Class11], [exact=JSUInt31])*/ o) {
   if (!(o is Class11)) {
@@ -281,7 +281,7 @@
   }
 }
 
-/*element: promotedParenNotIfThenElse:[null]*/
+/*member: promotedParenNotIfThenElse:[null]*/
 promotedParenNotIfThenElse() {
   _promotedParenNotIfThenElse(0);
   _promotedParenNotIfThenElse(new Class11());
@@ -291,14 +291,14 @@
 // Test if-then statement with null-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _nullIfThen:[null]*/
+/*member: _nullIfThen:[null]*/
 _nullIfThen(/*[null|exact=JSUInt31]*/ o) {
   if (o == null) {
     o. /*invoke: [null]*/ toString();
   }
 }
 
-/*element: nullIfThen:[null]*/
+/*member: nullIfThen:[null]*/
 nullIfThen() {
   _nullIfThen(0);
   _nullIfThen(null);
@@ -308,7 +308,7 @@
 // Test if-then-else statement null-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _nullIfThenElse:[null]*/
+/*member: _nullIfThenElse:[null]*/
 _nullIfThenElse(/*[null|exact=JSUInt31]*/ o) {
   if (o == null) {
     o. /*invoke: [null]*/ toString();
@@ -317,7 +317,7 @@
   }
 }
 
-/*element: nullIfThenElse:[null]*/
+/*member: nullIfThenElse:[null]*/
 nullIfThenElse() {
   _nullIfThenElse(0);
   _nullIfThenElse(null);
@@ -327,14 +327,14 @@
 // Test if-then statement with negated null-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notNullIfThen:[null]*/
+/*member: _notNullIfThen:[null]*/
 _notNullIfThen(/*[null|exact=JSUInt31]*/ o) {
   if (o != null) {
     o. /*invoke: [exact=JSUInt31]*/ toString();
   }
 }
 
-/*element: notNullIfThen:[null]*/
+/*member: notNullIfThen:[null]*/
 notNullIfThen() {
   _notNullIfThen(0);
   _notNullIfThen(null);
@@ -344,7 +344,7 @@
 // Test if-then-else statement with negated null-test
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notNullIfThenElse:[null]*/
+/*member: _notNullIfThenElse:[null]*/
 _notNullIfThenElse(/*[null|exact=JSUInt31]*/ o) {
   if (o != null) {
     o. /*invoke: [exact=JSUInt31]*/ toString();
@@ -353,7 +353,7 @@
   }
 }
 
-/*element: notNullIfThenElse:[null]*/
+/*member: notNullIfThenElse:[null]*/
 notNullIfThenElse() {
   _notNullIfThenElse(0);
   _notNullIfThenElse(null);
@@ -363,14 +363,14 @@
 // Test if-then statement with null-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _nullAndIfThen:[null]*/
+/*member: _nullAndIfThen:[null]*/
 _nullAndIfThen(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
   if (o == null && c) {
     o. /*invoke: [null]*/ toString();
   }
 }
 
-/*element: nullAndIfThen:[null]*/
+/*member: nullAndIfThen:[null]*/
 nullAndIfThen() {
   _nullAndIfThen(0, true);
   _nullAndIfThen(null, false);
@@ -380,7 +380,7 @@
 // Test if-then-else statement null-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _nullAndIfThenElse:[null]*/
+/*member: _nullAndIfThenElse:[null]*/
 _nullAndIfThenElse(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
   if (o == null && c) {
     o. /*invoke: [null]*/ toString();
@@ -389,7 +389,7 @@
   }
 }
 
-/*element: nullAndIfThenElse:[null]*/
+/*member: nullAndIfThenElse:[null]*/
 nullAndIfThenElse() {
   _nullAndIfThenElse(0, true);
   _nullAndIfThenElse(null, false);
@@ -399,14 +399,14 @@
 // Test if-then statement with negated null-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notNullAndIfThen:[null]*/
+/*member: _notNullAndIfThen:[null]*/
 _notNullAndIfThen(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
   if (o != null && c) {
     o. /*invoke: [exact=JSUInt31]*/ toString();
   }
 }
 
-/*element: notNullAndIfThen:[null]*/
+/*member: notNullAndIfThen:[null]*/
 notNullAndIfThen() {
   _notNullAndIfThen(0, true);
   _notNullAndIfThen(null, false);
@@ -416,7 +416,7 @@
 // Test if-then-else statement with negated null-test in &&
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notNullAndIfThenElse:[null]*/
+/*member: _notNullAndIfThenElse:[null]*/
 _notNullAndIfThenElse(/*[null|exact=JSUInt31]*/ o, /*[exact=JSBool]*/ c) {
   if (o != null && c) {
     o. /*invoke: [exact=JSUInt31]*/ toString();
@@ -425,7 +425,7 @@
   }
 }
 
-/*element: notNullAndIfThenElse:[null]*/
+/*member: notNullAndIfThenElse:[null]*/
 notNullAndIfThenElse() {
   _notNullAndIfThenElse(0, true);
   _notNullAndIfThenElse(null, false);
diff --git a/tests/compiler/dart2js/inference/data/map.dart b/tests/compiler/dart2js/inference/data/map.dart
index 52931ef..bef703b 100644
--- a/tests/compiler/dart2js/inference/data/map.dart
+++ b/tests/compiler/dart2js/inference/data/map.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   emptyMap();
   nullMap();
@@ -14,26 +14,26 @@
   constIntStringMap();
 }
 
-/*element: emptyMap:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: emptyMap:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 emptyMap() => {};
 
-/*element: constMap:Dictionary([subclass=ConstantMap], key: [empty], value: [null], map: {})*/
+/*member: constMap:Dictionary([subclass=ConstantMap], key: [empty], value: [null], map: {})*/
 constMap() => const {};
 
-/*element: nullMap:Map([subclass=JsLinkedHashMap], key: [null], value: [null])*/
+/*member: nullMap:Map([subclass=JsLinkedHashMap], key: [null], value: [null])*/
 nullMap() => {null: null};
 
-/*element: constNullMap:Map([subclass=ConstantMap], key: [null], value: [null])*/
+/*member: constNullMap:Map([subclass=ConstantMap], key: [null], value: [null])*/
 constNullMap() => const {null: null};
 
-/*element: stringIntMap:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
+/*member: stringIntMap:Dictionary([subclass=JsLinkedHashMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
 stringIntMap() => {'a': 1, 'b': 2, 'c': 3};
 
-/*element: intStringMap:Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
+/*member: intStringMap:Map([subclass=JsLinkedHashMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
 intStringMap() => {1: 'a', 2: 'b', 3: 'c'};
 
-/*element: constStringIntMap:Dictionary([subclass=ConstantMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
+/*member: constStringIntMap:Dictionary([subclass=ConstantMap], key: [exact=JSString], value: [null|exact=JSUInt31], map: {a: [exact=JSUInt31], b: [exact=JSUInt31], c: [exact=JSUInt31]})*/
 constStringIntMap() => const {'a': 1, 'b': 2, 'c': 3};
 
-/*element: constIntStringMap:Map([subclass=ConstantMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
+/*member: constIntStringMap:Map([subclass=ConstantMap], key: [exact=JSUInt31], value: [null|exact=JSString])*/
 constIntStringMap() => const {1: 'a', 2: 'b', 3: 'c'};
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_const.dart b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
index 3ee2393..42a1d9f 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_const.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_const.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: closure:[exact=JSUInt31]*/
+/*member: closure:[exact=JSUInt31]*/
 int closure(
     int
         /*strong.Union([exact=JSDouble], [exact=JSUInt31])*/
@@ -14,18 +14,18 @@
 }
 
 class A {
-  /*strong.element: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
-  /*omit.element: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+  /*strong.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+  /*omit.member: A.DEFAULT:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
   static const DEFAULT = const {'fun': closure};
 
-  /*element: A.map:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
+  /*member: A.map:Dictionary([subclass=ConstantMap], key: Value([exact=JSString], value: "fun"), value: [null|subclass=Closure], map: {fun: [subclass=Closure]})*/
   final map;
 
-  /*element: A.:[exact=A]*/
+  /*member: A.:[exact=A]*/
   A([/*[null]*/ maparg]) : map = maparg == null ? DEFAULT : maparg;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   var a = new A();
   a. /*[exact=A]*/ map
diff --git a/tests/compiler/dart2js/inference/data/map_tracer_keys.dart b/tests/compiler/dart2js/inference/data/map_tracer_keys.dart
index 576a02a..2798d02 100644
--- a/tests/compiler/dart2js/inference/data/map_tracer_keys.dart
+++ b/tests/compiler/dart2js/inference/data/map_tracer_keys.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
@@ -12,18 +12,18 @@
   test6();
 }
 
-/*element: aDouble1:[null|exact=JSDouble]*/
+/*member: aDouble1:[null|exact=JSDouble]*/
 dynamic aDouble1 = 42.5;
 
-/*element: aList1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 dynamic aList1 = [42];
 
-/*element: consume1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume1:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 consume1(
         /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
     x;
 
-/*element: test1:[null]*/
+/*member: test1:[null]*/
 test1() {
   var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
@@ -43,18 +43,18 @@
   consume1(aList1);
 }
 
-/*element: aDouble2:[null|exact=JSDouble]*/
+/*member: aDouble2:[null|exact=JSDouble]*/
 dynamic aDouble2 = 42.5;
 
-/*element: aList2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 dynamic aList2 = [42];
 
-/*element: consume2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume2:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 consume2(
         /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
     x;
 
-/*element: test2:[null]*/
+/*member: test2:[null]*/
 test2() {
   dynamic theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
@@ -74,18 +74,18 @@
   consume2(aList2);
 }
 
-/*element: aDouble3:Union([exact=JSDouble], [null|exact=JSExtendableArray])*/
+/*member: aDouble3:Union([exact=JSDouble], [null|exact=JSExtendableArray])*/
 dynamic aDouble3 = 42.5;
 
-/*element: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 dynamic aList3 = [42];
 
-/*element: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume3:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 consume3(
         /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
     x;
 
-/*element: test3:[null]*/
+/*member: test3:[null]*/
 test3() {
   dynamic theMap = <dynamic, dynamic>{'a': 2.2, 'b': 3.3, 'c': 4.4};
   theMap
@@ -105,18 +105,18 @@
   consume3(aList3);
 }
 
-/*element: aDouble4:[null|exact=JSDouble]*/
+/*member: aDouble4:[null|exact=JSDouble]*/
 dynamic aDouble4 = 42.5;
 
-/*element: aList4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 dynamic aList4 = [42];
 
-/*element: consume4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume4:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 consume4(
         /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
     x;
 
-/*element: test4:[null]*/
+/*member: test4:[null]*/
 test4() {
   var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': 5.5};
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
@@ -133,18 +133,18 @@
   consume4(aList4);
 }
 
-/*element: aDouble5:[null|exact=JSDouble]*/
+/*member: aDouble5:[null|exact=JSDouble]*/
 dynamic aDouble5 = 42.5;
 
-/*element: aList5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: aList5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 dynamic aList5 = [42];
 
-/*element: consume5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
+/*member: consume5:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 consume5(
         /*Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/ x) =>
     x;
 
-/*element: test5:[null]*/
+/*member: test5:[null]*/
 test5() {
   var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, aList5: 5.5};
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
@@ -161,17 +161,17 @@
   consume5(aList5);
 }
 
-/*element: aDouble6:Union([null|exact=JSDouble], [null|exact=JSExtendableArray])*/
+/*member: aDouble6:Union([null|exact=JSDouble], [null|exact=JSExtendableArray])*/
 dynamic aDouble6 = 42.5;
-/*element: aList6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: aList6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 dynamic aList6 = [42];
 
-/*element: consume6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
+/*member: consume6:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/
 consume6(
         /*Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 1)*/ x) =>
     x;
 
-/*element: test6:[null]*/
+/*member: test6:[null]*/
 test6() {
   var theMap = {'a': 2.2, 'b': 3.3, 'c': 4.4, 'd': aList6};
   /*iterator: [exact=LinkedHashMapKeyIterable]*/
diff --git a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
index 909a33e..8528a7e 100644
--- a/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
+++ b/tests/compiler/dart2js/inference/data/mixin_constructor_default_parameter_values.dart
@@ -10,14 +10,14 @@
 import '../libs/mixin_constructor_default_parameter_values_lib.dart';
 
 class Mixin {
-  /*element: Mixin.foo:[exact=JSString]*/
+  /*member: Mixin.foo:[exact=JSString]*/
   String get foo => "Mixin:$this";
 }
 
 // ignore: MIXIN_HAS_NO_CONSTRUCTORS
 class D = C with Mixin;
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   // ignore: NEW_WITH_UNDEFINED_CONSTRUCTOR
   print(new D.a(42). /*[exact=D]*/ foo);
diff --git a/tests/compiler/dart2js/inference/data/narrowing.dart b/tests/compiler/dart2js/inference/data/narrowing.dart
index 4ab579c..ba26c79 100644
--- a/tests/compiler/dart2js/inference/data/narrowing.dart
+++ b/tests/compiler/dart2js/inference/data/narrowing.dart
@@ -5,75 +5,75 @@
 /// Regression test for Issue #33761: is-checks and null-checks were assumed to
 /// be true even in nested non-condition contexts.
 
-/*element: argIsNonNull1:[null]*/
+/*member: argIsNonNull1:[null]*/
 argIsNonNull1(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull1:[null]*/
+/*member: nonNull1:[null]*/
 void nonNull1() {
   var x = 1;
   if (x == null) return;
   argIsNonNull1(x);
 }
 
-/*element: argIsNonNull2:[null]*/
+/*member: argIsNonNull2:[null]*/
 argIsNonNull2(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull2:[null]*/
+/*member: nonNull2:[null]*/
 void nonNull2() {
   var x = 1;
   if ((x == null) /*invoke: [exact=JSBool]*/ == true) return;
   argIsNonNull2(x);
 }
 
-/*element: argIsNonNull3:[null]*/
+/*member: argIsNonNull3:[null]*/
 argIsNonNull3(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull3:[null]*/
+/*member: nonNull3:[null]*/
 void nonNull3() {
   var x = 1;
   if ((x == null) /*invoke: [exact=JSBool]*/ != false) return;
   argIsNonNull3(x);
 }
 
-/*element: argIsNonNull4:[null]*/
+/*member: argIsNonNull4:[null]*/
 argIsNonNull4(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: discard:Value([exact=JSBool], value: false)*/
+/*member: discard:Value([exact=JSBool], value: false)*/
 discard(/*[exact=JSBool]*/ x) => false;
 
-/*element: nonNull4:[null]*/
+/*member: nonNull4:[null]*/
 void nonNull4() {
   var x = 1;
   if (discard(x != null)) return;
   argIsNonNull4(x);
 }
 
-/*element: argIsNonNull5:[null]*/
+/*member: argIsNonNull5:[null]*/
 argIsNonNull5(/*[null|exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull5:[null]*/
+/*member: nonNull5:[null]*/
 void nonNull5() {
   var x = 1;
   if (x != null ? false : false) return;
   argIsNonNull5(x);
 }
 
-/*element: argIsNonNull6:[null]*/
+/*member: argIsNonNull6:[null]*/
 argIsNonNull6(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull6:[null]*/
+/*member: nonNull6:[null]*/
 void nonNull6() {
   var x = 1;
   if ((/*[exact=JSBool]*/ (/*[exact=JSBool]*/ y) => y && false)(x != null))
@@ -81,12 +81,12 @@
   argIsNonNull6(x);
 }
 
-/*element: argIsNonNull7:[null]*/
+/*member: argIsNonNull7:[null]*/
 argIsNonNull7(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull7:[null]*/
+/*member: nonNull7:[null]*/
 void nonNull7() {
   var f = false;
   var x = 1;
@@ -94,12 +94,12 @@
   argIsNonNull7(x);
 }
 
-/*element: argIsNonNull8:[null]*/
+/*member: argIsNonNull8:[null]*/
 argIsNonNull8(/*[exact=JSUInt31]*/ x) {
   print('>> is null: ${x == null}');
 }
 
-/*element: nonNull8:[null]*/
+/*member: nonNull8:[null]*/
 void nonNull8() {
   var f = false;
   var x = 1;
@@ -107,7 +107,7 @@
   argIsNonNull8(x);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 void main() {
   nonNull1();
   nonNull2();
diff --git a/tests/compiler/dart2js/inference/data/native.dart b/tests/compiler/dart2js/inference/data/native.dart
index e9ec7b9..a1bfd75 100644
--- a/tests/compiler/dart2js/inference/data/native.dart
+++ b/tests/compiler/dart2js/inference/data/native.dart
@@ -2,12 +2,12 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   nativeMethod();
 }
 
-/*element: nativeMethod:[null|subclass=Object]*/
+/*member: nativeMethod:[null|subclass=Object]*/
 nativeMethod()
     // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
     native;
diff --git a/tests/compiler/dart2js/inference/data/native2.dart b/tests/compiler/dart2js/inference/data/native2.dart
index bae53e9..e9b712c 100644
--- a/tests/compiler/dart2js/inference/data/native2.dart
+++ b/tests/compiler/dart2js/inference/data/native2.dart
@@ -6,16 +6,16 @@
 import 'dart:_foreign_helper' as foreign show JS;
 import 'dart:html';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   createElement();
   createRectangle();
 }
 
-/*element: createElement:[null|subclass=Element]*/
+/*member: createElement:[null|subclass=Element]*/
 Element createElement()
     // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
     native;
 
-/*element: createRectangle:[subclass=DomRectReadOnly]*/
+/*member: createRectangle:[subclass=DomRectReadOnly]*/
 createRectangle() => foreign.JS('Rectangle', "#", null);
diff --git a/tests/compiler/dart2js/inference/data/native3.dart b/tests/compiler/dart2js/inference/data/native3.dart
index 73e458f..f2e7167 100644
--- a/tests/compiler/dart2js/inference/data/native3.dart
+++ b/tests/compiler/dart2js/inference/data/native3.dart
@@ -4,12 +4,12 @@
 
 import 'dart:html';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   createRectangle();
 }
 
-/*element: createRectangle:[null|subclass=DomRectReadOnly]*/
+/*member: createRectangle:[null|subclass=DomRectReadOnly]*/
 Rectangle createRectangle()
     // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
     native;
diff --git a/tests/compiler/dart2js/inference/data/new.dart b/tests/compiler/dart2js/inference/data/new.dart
index 35ad6d3..fb9e9ff 100644
--- a/tests/compiler/dart2js/inference/data/new.dart
+++ b/tests/compiler/dart2js/inference/data/new.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   generativeConstructorCall();
   factoryConstructorCall1();
@@ -22,10 +22,10 @@
 /// Call default constructor of a field-less class.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {}
 
-/*element: generativeConstructorCall:[exact=Class1]*/
+/*member: generativeConstructorCall:[exact=Class1]*/
 generativeConstructorCall() => new Class1();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -33,11 +33,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.:[null]*/
+  /*member: Class2.:[null]*/
   factory Class2() => null;
 }
 
-/*element: factoryConstructorCall1:[null]*/
+/*member: factoryConstructorCall1:[null]*/
 factoryConstructorCall1() => new Class2();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -45,13 +45,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.:[exact=Class3]*/
+  /*member: Class3.:[exact=Class3]*/
   factory Class3() => new Class3.named();
-  /*element: Class3.named:[exact=Class3]*/
+  /*member: Class3.named:[exact=Class3]*/
   Class3.named();
 }
 
-/*element: factoryConstructorCall2:[exact=Class3]*/
+/*member: factoryConstructorCall2:[exact=Class3]*/
 factoryConstructorCall2() => new Class3();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -59,14 +59,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4a {
-  /*element: Class4a.:[exact=Class4b]*/
+  /*member: Class4a.:[exact=Class4b]*/
   factory Class4a() => new Class4b();
 }
 
-/*element: Class4b.:[exact=Class4b]*/
+/*member: Class4b.:[exact=Class4b]*/
 class Class4b implements Class4a {}
 
-/*element: factoryConstructorCall3:[exact=Class4b]*/
+/*member: factoryConstructorCall3:[exact=Class4b]*/
 factoryConstructorCall3() => new Class4a();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -74,13 +74,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class5 {
-  final /*element: Class5.field:[exact=JSUInt31]*/ field;
+  final /*member: Class5.field:[exact=JSUInt31]*/ field;
 
-  /*element: Class5.:[exact=Class5]*/
+  /*member: Class5.:[exact=Class5]*/
   Class5(this. /*[exact=JSUInt31]*/ field);
 }
 
-/*element: classWithFinalFieldInitializer:[exact=Class5]*/
+/*member: classWithFinalFieldInitializer:[exact=Class5]*/
 classWithFinalFieldInitializer() => new Class5(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -88,13 +88,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class6 {
-  var /*element: Class6.field:[exact=JSUInt31]*/ field;
+  var /*member: Class6.field:[exact=JSUInt31]*/ field;
 
-  /*element: Class6.:[exact=Class6]*/
+  /*member: Class6.:[exact=Class6]*/
   Class6(this. /*[exact=JSUInt31]*/ field);
 }
 
-/*element: classWithNonFinalFieldInitializer:[exact=Class6]*/
+/*member: classWithNonFinalFieldInitializer:[exact=Class6]*/
 classWithNonFinalFieldInitializer() => new Class6(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -102,13 +102,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class7 {
-  var /*element: Class7.field:[exact=JSUInt31]*/ field;
+  var /*member: Class7.field:[exact=JSUInt31]*/ field;
 
-  /*element: Class7.:[exact=Class7]*/
+  /*member: Class7.:[exact=Class7]*/
   Class7(/*[exact=JSUInt31]*/ value) : this.field = value;
 }
 
-/*element: classWithExplicitFieldInitializer:[exact=Class7]*/
+/*member: classWithExplicitFieldInitializer:[exact=Class7]*/
 classWithExplicitFieldInitializer() => new Class7(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -116,15 +116,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class8 {
-  var /*element: Class8.field:[exact=JSUInt31]*/ field;
+  var /*member: Class8.field:[exact=JSUInt31]*/ field;
 
-  /*element: Class8.:[exact=Class8]*/
+  /*member: Class8.:[exact=Class8]*/
   Class8(/*[exact=JSUInt31]*/ value) {
     this. /*update: [exact=Class8]*/ field = value;
   }
 }
 
-/*element: classWithFieldInitializerInBody:[exact=Class8]*/
+/*member: classWithFieldInitializerInBody:[exact=Class8]*/
 classWithFieldInitializerInBody() => new Class8(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -133,13 +133,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class9 {
-  var /*element: Class9.field:[null]*/ field = null;
+  var /*member: Class9.field:[null]*/ field = null;
 
-  /*element: Class9.:[exact=Class9]*/
+  /*member: Class9.:[exact=Class9]*/
   Class9() {}
 }
 
-/*element: classWithNullNoFieldInitializerInBody:[exact=Class9]*/
+/*member: classWithNullNoFieldInitializerInBody:[exact=Class9]*/
 classWithNullNoFieldInitializerInBody() => new Class9();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -148,15 +148,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class10 {
-  var /*element: Class10.field:[exact=JSUInt31]*/ field = null;
+  var /*member: Class10.field:[exact=JSUInt31]*/ field = null;
 
-  /*element: Class10.:[exact=Class10]*/
+  /*member: Class10.:[exact=Class10]*/
   Class10(/*[exact=JSUInt31]*/ value) {
     this. /*update: [exact=Class10]*/ field = value;
   }
 }
 
-/*element: classWithNullFieldInitializerInBody:[exact=Class10]*/
+/*member: classWithNullFieldInitializerInBody:[exact=Class10]*/
 classWithNullFieldInitializerInBody() => new Class10(0);
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -165,18 +165,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class11 {
-  var /*element: Class11.field:[null|exact=JSUInt31]*/ field = null;
+  var /*member: Class11.field:[null|exact=JSUInt31]*/ field = null;
 
-  /*element: Class11.a:[exact=Class11]*/
+  /*member: Class11.a:[exact=Class11]*/
   Class11.a(/*[exact=JSUInt31]*/ value) {
     this. /*update: [exact=Class11]*/ field = value;
   }
 
-  /*element: Class11.b:[exact=Class11]*/
+  /*member: Class11.b:[exact=Class11]*/
   Class11.b() {}
 }
 
-/*element: classWithNullMaybeFieldInitializerInBody:[exact=Class11]*/
+/*member: classWithNullMaybeFieldInitializerInBody:[exact=Class11]*/
 classWithNullMaybeFieldInitializerInBody() {
   new Class11.a(0);
   return new Class11.b();
@@ -187,13 +187,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class12 {
-  final /*element: Class12.field:[null]*/ field = null;
+  final /*member: Class12.field:[null]*/ field = null;
 
-  /*element: Class12.:[exact=Class12]*/
+  /*member: Class12.:[exact=Class12]*/
   Class12();
 }
 
-/*element: classWithNullFinalFieldInitializer:[exact=Class12]*/
+/*member: classWithNullFinalFieldInitializer:[exact=Class12]*/
 classWithNullFinalFieldInitializer() {
   return new Class12();
 }
diff --git a/tests/compiler/dart2js/inference/data/no_such_method.dart b/tests/compiler/dart2js/inference/data/no_such_method.dart
index 2803433..6fc1c46 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method.dart
@@ -1,4 +1,4 @@
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   missingGetter();
   missingMethod();
@@ -10,9 +10,9 @@
 // Access missing getter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.noSuchMethod:[exact=JSUInt31]*/
+  /*member: Class1.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           Invocation
               /*strong.[null|subclass=Object]*/
@@ -22,23 +22,23 @@
               _) =>
       42;
 
-  /*element: Class1.method:[exact=JSUInt31]*/
+  /*member: Class1.method:[exact=JSUInt31]*/
   method() {
     dynamic a = this;
     return a. /*[exact=Class1]*/ missingGetter;
   }
 }
 
-/*element: missingGetter:[exact=JSUInt31]*/
+/*member: missingGetter:[exact=JSUInt31]*/
 missingGetter() => new Class1(). /*invoke: [exact=Class1]*/ method();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Invoke missing method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.noSuchMethod:[exact=JSUInt31]*/
+  /*member: Class2.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           Invocation
               /*strong.[null|subclass=Object]*/
@@ -48,23 +48,23 @@
               _) =>
       42;
 
-  /*element: Class2.method:[exact=JSUInt31]*/
+  /*member: Class2.method:[exact=JSUInt31]*/
   method() {
     dynamic a = this;
     return a. /*invoke: [exact=Class2]*/ missingMethod();
   }
 }
 
-/*element: missingMethod:[exact=JSUInt31]*/
+/*member: missingMethod:[exact=JSUInt31]*/
 missingMethod() => new Class2(). /*invoke: [exact=Class2]*/ method();
 
 ////////////////////////////////////////////////////////////////////////////////
 // Pass closure to missing method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.noSuchMethod:[null|subclass=Object]*/
+  /*member: Class3.noSuchMethod:[null|subclass=Object]*/
   noSuchMethod(
       Invocation
           /*strong.[null|subclass=Object]*/
@@ -81,7 +81,7 @@
         first;
   }
 
-  /*element: Class3.method:[null|subclass=Object]*/
+  /*member: Class3.method:[null|subclass=Object]*/
   method() {
     dynamic a = this;
     return a. /*invoke: [exact=Class3]*/ missingMethod(
@@ -89,7 +89,7 @@
   }
 }
 
-/*element: closureThroughMissingMethod:[null|subclass=Object]*/
+/*member: closureThroughMissingMethod:[null|subclass=Object]*/
 closureThroughMissingMethod() =>
     new Class3(). /*invoke: [exact=Class3]*/ method();
 
@@ -97,12 +97,12 @@
 // Pass closure to missing setter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field:[null|subclass=Object]*/
+  /*member: Class4.field:[null|subclass=Object]*/
   var field;
 
-  /*element: Class4.noSuchMethod:[null]*/
+  /*member: Class4.noSuchMethod:[null]*/
   noSuchMethod(
       Invocation
           /*strong.[null|subclass=Object]*/
@@ -120,7 +120,7 @@
     return null;
   }
 
-  /*element: Class4.method:[null]*/
+  /*member: Class4.method:[null]*/
   method() {
     dynamic a = this;
     a. /*update: [exact=Class4]*/ missingSetter =
@@ -129,6 +129,6 @@
   }
 }
 
-/*element: closureThroughMissingSetter:[null]*/
+/*member: closureThroughMissingSetter:[null]*/
 closureThroughMissingSetter() =>
     new Class4(). /*invoke: [exact=Class4]*/ method();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method1.dart b/tests/compiler/dart2js/inference/data/no_such_method1.dart
index eeaed0e..c80bfb6 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method1.dart
@@ -2,9 +2,9 @@
 // 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.
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
-  /*element: A.noSuchMethod:[exact=JSUInt31]*/
+  /*member: A.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
@@ -14,48 +14,48 @@
       42;
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:[exact=JSUInt31]*/
+  /*member: B.foo:[exact=JSUInt31]*/
   /*invoke: [subclass=B]*/ foo();
 }
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C extends B {
-  /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 }
 
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
 dynamic a = [new B(), new C()]
     /*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
     [0];
 
-/*element: test1:[exact=JSUInt31]*/
+/*member: test1:[exact=JSUInt31]*/
 test1() {
   dynamic e = new A();
   return e. /*invoke: [exact=A]*/ foo();
 }
 
-/*element: test2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test2:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 test2() => a. /*invoke: [null|subclass=B]*/ foo();
 
-/*element: test3:[exact=JSUInt31]*/
+/*member: test3:[exact=JSUInt31]*/
 test3() => new B(). /*invoke: [exact=B]*/ foo();
 
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test4() => new C(). /*invoke: [exact=C]*/ foo();
 
-/*element: test5:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test5:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 test5() {
   dynamic e = (a ? new A() : new B());
   return e. /*invoke: [subclass=A]*/ foo();
 }
 
-/*element: test6:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
+/*member: test6:Union([exact=JSUInt31], [subclass=JsLinkedHashMap])*/
 test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method2.dart b/tests/compiler/dart2js/inference/data/no_such_method2.dart
index 3bce145..45a3251 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method2.dart
@@ -2,9 +2,9 @@
 // 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.
 
-/*element: A.:[subclass=B]*/
+/*member: A.:[subclass=B]*/
 abstract class A {
-  /*element: A.noSuchMethod:[exact=JSUInt31]*/
+  /*member: A.noSuchMethod:[exact=JSUInt31]*/
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
@@ -14,24 +14,24 @@
       42;
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 }
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C extends B {
-  /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 }
 
-/*element: D.:[exact=D]*/
+/*member: D.:[exact=D]*/
 class D implements A {
-  /*element: D.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: D.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 
-  /*element: D.noSuchMethod:[exact=JSDouble]*/
+  /*member: D.noSuchMethod:[exact=JSDouble]*/
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
@@ -41,67 +41,67 @@
       42.5;
 }
 
-/*element: a:Union([exact=D], [null|subclass=B])*/
+/*member: a:Union([exact=D], [null|subclass=B])*/
 dynamic a = [new B(), new C(), new D()]
     /*Container([exact=JSExtendableArray], element: Union([exact=D], [subclass=B]), length: 3)*/
     [0];
 
-/*element: test1:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test1:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test1() => a. /*invoke: Union([exact=D], [null|subclass=B])*/ foo();
 
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test2() => new B(). /*invoke: [exact=B]*/ foo();
 
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test3() => new C(). /*invoke: [exact=C]*/ foo();
 
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test4() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
 
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test5() {
   dynamic e = (a ? new B() : new D());
   return e. /*invoke: Union([exact=B], [exact=D])*/ foo();
 }
 
 // Can hit A.noSuchMethod, D.noSuchMethod and Object.noSuchMethod.
-/*element: test6:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: test6:Union([exact=JSDouble], [exact=JSUInt31])*/
 test6() => a. /*invoke: Union([exact=D], [null|subclass=B])*/ bar();
 
 // Can hit A.noSuchMethod.
-/*element: test7:[exact=JSUInt31]*/
+/*member: test7:[exact=JSUInt31]*/
 test7() {
   dynamic e = new B();
   return e. /*invoke: [exact=B]*/ bar();
 }
 
-/*element: test8:[exact=JSUInt31]*/
+/*member: test8:[exact=JSUInt31]*/
 test8() {
   dynamic e = new C();
   return e. /*invoke: [exact=C]*/ bar();
 }
 
-/*element: test9:[exact=JSUInt31]*/
+/*member: test9:[exact=JSUInt31]*/
 test9() {
   dynamic e = (a ? new B() : new C());
   return e. /*invoke: [subclass=B]*/ bar();
 }
 
 // Can hit A.noSuchMethod and D.noSuchMethod.
-/*element: test10:Union([exact=JSDouble], [exact=JSUInt31])*/
+/*member: test10:Union([exact=JSDouble], [exact=JSUInt31])*/
 test10() {
   dynamic e = (a ? new B() : new D());
   return e. /*invoke: Union([exact=B], [exact=D])*/ bar();
 }
 
 // Can hit D.noSuchMethod.
-/*element: test11:[exact=JSDouble]*/
+/*member: test11:[exact=JSDouble]*/
 test11() {
   dynamic e = new D();
   return e. /*invoke: [exact=D]*/ bar();
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method3.dart b/tests/compiler/dart2js/inference/data/no_such_method3.dart
index 07c56bd..0a41b65 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method3.dart
@@ -2,11 +2,11 @@
 // 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.
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
   // We may ignore this for type inference because syntactically it always
   // throws an exception.
-  /*element: A.noSuchMethod:[empty]*/
+  /*member: A.noSuchMethod:[empty]*/
   noSuchMethod(
           /*strong.[null|subclass=Object]*/
           /*omit.[null|exact=JSInvocationMirror]*/
@@ -16,47 +16,47 @@
       throw 'foo';
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 }
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C extends B {
-  /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+  /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
   foo() => {};
 }
 
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
 dynamic a = [new B(), new C()]
     /*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
     [0];
-/*element: test1:[empty]*/
+/*member: test1:[empty]*/
 test1() {
   dynamic e = new A();
   return e. /*invoke: [exact=A]*/ foo();
 }
 
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test2() => a. /*invoke: [null|subclass=B]*/ foo();
 
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test3() => new B(). /*invoke: [exact=B]*/ foo();
 
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test4() => new C(). /*invoke: [exact=C]*/ foo();
 
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test5() {
   dynamic e = (a ? new A() : new B());
   return e. /*invoke: [subclass=A]*/ foo();
 }
 
-/*element: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
diff --git a/tests/compiler/dart2js/inference/data/no_such_method4.dart b/tests/compiler/dart2js/inference/data/no_such_method4.dart
index 13af644..7e489ec 100644
--- a/tests/compiler/dart2js/inference/data/no_such_method4.dart
+++ b/tests/compiler/dart2js/inference/data/no_such_method4.dart
@@ -2,55 +2,55 @@
 // 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.
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
   // We may ignore this for type inference because it forwards to a default
   // noSuchMethod implementation, which always throws an exception.
   noSuchMethod(im) => super.noSuchMethod(im);
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+  /*member: B.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
       {};
 }
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C extends B {
-  /*element: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
+  /*member: C.foo:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/ foo() =>
       {};
 }
 
-/*element: a:[null|subclass=B]*/
+/*member: a:[null|subclass=B]*/
 dynamic a = [new B(), new C()]
     /*Container([exact=JSExtendableArray], element: [subclass=B], length: 2)*/
     [0];
 
-/*element: test1:[empty]*/
+/*member: test1:[empty]*/
 test1() {
   dynamic e = new A();
   return e. /*invoke: [exact=A]*/ foo();
 }
 
-/*element: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test2:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test2() => a. /*invoke: [null|subclass=B]*/ foo();
 
-/*element: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test3:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test3() => new B(). /*invoke: [exact=B]*/ foo();
 
-/*element: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test4:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test4() => new C(). /*invoke: [exact=C]*/ foo();
 
-/*element: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test5:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test5() {
   dynamic e = (a ? new A() : new B());
   return e. /*invoke: [subclass=A]*/ foo();
 }
 
-/*element: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
+/*member: test6:Dictionary([subclass=JsLinkedHashMap], key: [empty], value: [null], map: {})*/
 test6() => (a ? new B() : new C()). /*invoke: [subclass=B]*/ foo();
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   test1();
   test2();
diff --git a/tests/compiler/dart2js/inference/data/non_null.dart b/tests/compiler/dart2js/inference/data/non_null.dart
index da87bbe..96be59d 100644
--- a/tests/compiler/dart2js/inference/data/non_null.dart
+++ b/tests/compiler/dart2js/inference/data/non_null.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   nonNullStaticField();
   nonNullInstanceField1();
@@ -10,42 +10,42 @@
   nonNullLocal();
 }
 
-/*element: staticField:[null|exact=JSUInt31]*/
+/*member: staticField:[null|exact=JSUInt31]*/
 var staticField;
 
-/*element: nonNullStaticField:[exact=JSUInt31]*/
+/*member: nonNullStaticField:[exact=JSUInt31]*/
 nonNullStaticField() => staticField ??= 42;
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[null|exact=JSUInt31]*/
+  /*member: Class1.field:[null|exact=JSUInt31]*/
   var field;
 }
 
-/*element: nonNullInstanceField1:[exact=JSUInt31]*/
+/*member: nonNullInstanceField1:[exact=JSUInt31]*/
 nonNullInstanceField1() {
   return new Class1(). /*[exact=Class1]*/ /*update: [exact=Class1]*/ field ??=
       42;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[null|exact=JSUInt31]*/
+  /*member: Class2.field:[null|exact=JSUInt31]*/
   var field;
 
-  /*element: Class2.method:[exact=JSUInt31]*/
+  /*member: Class2.method:[exact=JSUInt31]*/
   method() {
     return /*[exact=Class2]*/ /*update: [exact=Class2]*/ field ??= 42;
   }
 }
 
-/*element: nonNullInstanceField2:[exact=JSUInt31]*/
+/*member: nonNullInstanceField2:[exact=JSUInt31]*/
 nonNullInstanceField2() {
   return new Class2(). /*invoke: [exact=Class2]*/ method();
 }
 
 // TODO(johnniwinther): We should infer that the returned value cannot be null.
-/*element: nonNullLocal:[null|exact=JSUInt31]*/
+/*member: nonNullLocal:[null|exact=JSUInt31]*/
 nonNullLocal() {
   var local = null;
   return local ??= 42;
diff --git a/tests/compiler/dart2js/inference/data/null.dart b/tests/compiler/dart2js/inference/data/null.dart
index 0a220f0..9e53378 100644
--- a/tests/compiler/dart2js/inference/data/null.dart
+++ b/tests/compiler/dart2js/inference/data/null.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   ifThenNullCheck(0);
   ifThenNullCheck(null);
@@ -22,7 +22,7 @@
   ifThenNotNullGradualCheck2(null, 0);
 }
 
-/*element: ifThenNullCheck:[exact=JSUInt31]*/
+/*member: ifThenNullCheck:[exact=JSUInt31]*/
 ifThenNullCheck(int /*[null|exact=JSUInt31]*/ value) {
   if (value == null) {
     return 0;
@@ -30,7 +30,7 @@
   return value;
 }
 
-/*element: ifThenElseNullCheck:[exact=JSUInt31]*/
+/*member: ifThenElseNullCheck:[exact=JSUInt31]*/
 ifThenElseNullCheck(int /*[null|exact=JSUInt31]*/ value) {
   if (value == null) {
     return 0;
@@ -39,7 +39,7 @@
   }
 }
 
-/*element: ifNotThenNullCheck:[exact=JSUInt31]*/
+/*member: ifNotThenNullCheck:[exact=JSUInt31]*/
 ifNotThenNullCheck(int /*[null|exact=JSUInt31]*/ value) {
   if (value != null) {
     return value;
@@ -47,7 +47,7 @@
   return 0;
 }
 
-/*element: ifNotThenElseNullCheck:[exact=JSUInt31]*/
+/*member: ifNotThenElseNullCheck:[exact=JSUInt31]*/
 ifNotThenElseNullCheck(int /*[null|exact=JSUInt31]*/ value) {
   if (value != null) {
     return value;
@@ -56,7 +56,7 @@
   }
 }
 
-/*element: ifThenNotNullComplexCheck:[exact=JSUInt31]*/
+/*member: ifThenNotNullComplexCheck:[exact=JSUInt31]*/
 ifThenNotNullComplexCheck(
     int /*[null|exact=JSUInt31]*/ a, int /*[null|exact=JSUInt31]*/ b) {
   if (a != null && a /*invoke: [exact=JSUInt31]*/ != b) {
@@ -65,7 +65,7 @@
   return 0;
 }
 
-/*element: ifThenElseNotNullComplexCheck:[null|exact=JSUInt31]*/
+/*member: ifThenElseNotNullComplexCheck:[null|exact=JSUInt31]*/
 ifThenElseNotNullComplexCheck(
     int /*[null|exact=JSUInt31]*/ a, int /*[null|exact=JSUInt31]*/ b) {
   if (a != null && a /*invoke: [exact=JSUInt31]*/ != b) {
@@ -74,7 +74,7 @@
   return a;
 }
 
-/*element: ifThenNotNullGradualCheck1:[exact=JSUInt31]*/
+/*member: ifThenNotNullGradualCheck1:[exact=JSUInt31]*/
 ifThenNotNullGradualCheck1(
     int /*[null|exact=JSUInt31]*/ a, int /*[exact=JSUInt31]*/ b) {
   if (a /*invoke: [null|exact=JSUInt31]*/ != b) {
@@ -85,7 +85,7 @@
   return 0;
 }
 
-/*element: ifThenNotNullGradualCheck2:[exact=JSUInt31]*/
+/*member: ifThenNotNullGradualCheck2:[exact=JSUInt31]*/
 ifThenNotNullGradualCheck2(
     int /*[null|exact=JSUInt31]*/ a, int /*[exact=JSUInt31]*/ b) {
   if (a != null) {
diff --git a/tests/compiler/dart2js/inference/data/optimizer_hints.dart b/tests/compiler/dart2js/inference/data/optimizer_hints.dart
index 919332e..c51ce4f 100644
--- a/tests/compiler/dart2js/inference/data/optimizer_hints.dart
+++ b/tests/compiler/dart2js/inference/data/optimizer_hints.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   assumeDynamic();
   notAssumeDynamic();
@@ -18,11 +18,11 @@
 // the 'dynamic' type.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _assumeDynamic:[null|subclass=Object]*/
+/*member: _assumeDynamic:[null|subclass=Object]*/
 @pragma('dart2js:assumeDynamic')
 _assumeDynamic(/*[null|subclass=Object]*/ o) => o;
 
-/*element: assumeDynamic:[null]*/
+/*member: assumeDynamic:[null]*/
 assumeDynamic() {
   _assumeDynamic(0);
 }
@@ -31,10 +31,10 @@
 // As above but without the annotation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _notAssumeDynamic:[exact=JSUInt31]*/
+/*member: _notAssumeDynamic:[exact=JSUInt31]*/
 _notAssumeDynamic(/*[exact=JSUInt31]*/ o) => o;
 
-/*element: notAssumeDynamic:[null]*/
+/*member: notAssumeDynamic:[null]*/
 notAssumeDynamic() {
   _notAssumeDynamic(0);
 }
@@ -43,7 +43,7 @@
 // No annotation is needed to trust return type annotation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: trustReturnTypeString:[null|exact=JSString]*/
+/*member: trustReturnTypeString:[null|exact=JSString]*/
 String trustReturnTypeString() {
   return _assumeDynamic(0);
 }
@@ -52,10 +52,10 @@
 // No annotation is needed to trust parameter type annotation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _trustParameterTypeString:[null]*/
+/*member: _trustParameterTypeString:[null]*/
 _trustParameterTypeString(String /*[null|exact=JSString]*/ o) {}
 
-/*element: trustParameterTypeString:[null]*/
+/*member: trustParameterTypeString:[null]*/
 trustParameterTypeString() {
   _trustParameterTypeString(_assumeDynamic(0));
 }
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index 27b45a3..e9b8e84 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   trustParameters();
 }
@@ -13,7 +13,7 @@
 // Test that we trust the explicit type of a parameter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _trustParameters:[exact=JSUInt31]*/
+/*member: _trustParameters:[exact=JSUInt31]*/
 _trustParameters(
     int
         /*strong.Union([exact=JSString], [exact=JSUInt31])*/
@@ -24,7 +24,7 @@
   return i;
 }
 
-/*element: trustParameters:[null]*/
+/*member: trustParameters:[null]*/
 trustParameters() {
   dynamic f = _trustParameters;
   Expect.equals(0, f(0));
diff --git a/tests/compiler/dart2js/inference/data/postfix.dart b/tests/compiler/dart2js/inference/data/postfix.dart
index edd497f..8cba579 100644
--- a/tests/compiler/dart2js/inference/data/postfix.dart
+++ b/tests/compiler/dart2js/inference/data/postfix.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   localPostfixInc();
   localPostfixDec();
@@ -18,7 +18,7 @@
 // Postfix increment on local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: localPostfixInc:[exact=JSUInt31]*/
+/*member: localPostfixInc:[exact=JSUInt31]*/
 localPostfixInc() {
   var local;
   if (local == null) {
@@ -31,7 +31,7 @@
 // Postfix decrement on local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: localPostfixDec:[exact=JSUInt31]*/
+/*member: localPostfixDec:[exact=JSUInt31]*/
 localPostfixDec() {
   var local;
   if (local == null) {
@@ -44,10 +44,10 @@
 // Postfix increment on static field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _staticField1:[null|subclass=JSPositiveInt]*/
+/*member: _staticField1:[null|subclass=JSPositiveInt]*/
 var _staticField1;
 
-/*element: staticFieldPostfixInc:[subclass=JSPositiveInt]*/
+/*member: staticFieldPostfixInc:[subclass=JSPositiveInt]*/
 staticFieldPostfixInc() {
   if (_staticField1 == null) {
     _staticField1 = 0;
@@ -59,10 +59,10 @@
 // Postfix decrement on static field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _staticField2:[null|subclass=JSInt]*/
+/*member: _staticField2:[null|subclass=JSInt]*/
 var _staticField2;
 
-/*element: staticFieldPostfixDec:[subclass=JSInt]*/
+/*member: staticFieldPostfixDec:[subclass=JSInt]*/
 staticFieldPostfixDec() {
   if (_staticField2 == null) {
     _staticField2 = 0;
@@ -74,13 +74,13 @@
 // Postfix increment on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field1:[null|subclass=JSPositiveInt]*/
+  /*member: Class1.field1:[null|subclass=JSPositiveInt]*/
   var field1;
 }
 
-/*element: instanceFieldPostfixInc:[subclass=JSPositiveInt]*/
+/*member: instanceFieldPostfixInc:[subclass=JSPositiveInt]*/
 instanceFieldPostfixInc() {
   var c = new Class1();
   if (c. /*[exact=Class1]*/ field1 == null) {
@@ -96,13 +96,13 @@
 // Postfix decrement on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field2:[null|subclass=JSInt]*/
+  /*member: Class2.field2:[null|subclass=JSInt]*/
   var field2;
 }
 
-/*element: instanceFieldPostfixDec:[subclass=JSInt]*/
+/*member: instanceFieldPostfixDec:[subclass=JSInt]*/
 instanceFieldPostfixDec() {
   var c = new Class2();
   if (c. /*[exact=Class2]*/ field2 == null) {
@@ -118,13 +118,13 @@
 // Conditional postfix increment on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.field3:[null|subclass=JSPositiveInt]*/
+  /*member: Class3.field3:[null|subclass=JSPositiveInt]*/
   var field3;
 }
 
-/*element: conditionalInstanceFieldPostfixInc:[null|subclass=JSPositiveInt]*/
+/*member: conditionalInstanceFieldPostfixInc:[null|subclass=JSPositiveInt]*/
 conditionalInstanceFieldPostfixInc() {
   var c = new Class3();
   if (c. /*[exact=Class3]*/ field3 == null) {
@@ -140,13 +140,13 @@
 // Conditional postfix decrement on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field4:[null|subclass=JSInt]*/
+  /*member: Class4.field4:[null|subclass=JSInt]*/
   var field4;
 }
 
-/*element: conditionalInstanceFieldPostfixDec:[null|subclass=JSInt]*/
+/*member: conditionalInstanceFieldPostfixDec:[null|subclass=JSInt]*/
 conditionalInstanceFieldPostfixDec() {
   var c = new Class4();
   if (c. /*[exact=Class4]*/ field4 == null) {
diff --git a/tests/compiler/dart2js/inference/data/postfix_prefix.dart b/tests/compiler/dart2js/inference/data/postfix_prefix.dart
index 92a47c2..9342997 100644
--- a/tests/compiler/dart2js/inference/data/postfix_prefix.dart
+++ b/tests/compiler/dart2js/inference/data/postfix_prefix.dart
@@ -2,49 +2,49 @@
 // 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.
 
-/*element: index:[empty]*/
+/*member: index:[empty]*/
 dynamic get index => throw '';
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
-  /*element: A.foo:Value([exact=JSString], value: "string")*/
+  /*member: A.foo:Value([exact=JSString], value: "string")*/
   get foo => 'string';
 
   set foo(/*[subclass=JSNumber]*/ value) {}
 
-  /*element: A.[]:Value([exact=JSString], value: "string")*/
+  /*member: A.[]:Value([exact=JSString], value: "string")*/
   operator [](/*[empty]*/ index) => 'string';
 
-  /*element: A.[]=:[null]*/
+  /*member: A.[]=:[null]*/
   operator []=(/*[empty]*/ index, /*[subclass=JSNumber]*/ value) {}
 
-  /*element: A.returnDynamic1:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A.returnDynamic1:Union([exact=JSString], [exact=JSUInt31])*/
   returnDynamic1() => /*[subclass=A]*/ /*update: [subclass=A]*/ foo
       /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --;
 
-  /*element: A.returnNum1:[subclass=JSNumber]*/
+  /*member: A.returnNum1:[subclass=JSNumber]*/
   returnNum1() => /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --
       /*[subclass=A]*/ /*update: [subclass=A]*/ foo;
 
-  /*element: A.returnNum2:[subclass=JSNumber]*/
+  /*member: A.returnNum2:[subclass=JSNumber]*/
   returnNum2() => /*[subclass=A]*/ /*update: [subclass=A]*/ foo
       /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ -= 42;
 
-  /*element: A.returnDynamic2:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: A.returnDynamic2:Union([exact=JSString], [exact=JSUInt31])*/
   returnDynamic2() => this
           /*[subclass=A]*/ /*update: [subclass=A]*/ [index]
       /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --;
 
-  /*element: A.returnNum3:[subclass=JSNumber]*/
+  /*member: A.returnNum3:[subclass=JSNumber]*/
   returnNum3() => /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ --this
       /*[subclass=A]*/ /*update: [subclass=A]*/ [index];
 
-  /*element: A.returnNum4:[subclass=JSNumber]*/
+  /*member: A.returnNum4:[subclass=JSNumber]*/
   returnNum4() => this
           /*[subclass=A]*/ /*update: [subclass=A]*/ [index]
       /*invoke: Union([exact=JSString], [exact=JSUInt31])*/ -= 42;
 
-  /*element: A.returnEmpty3:[empty]*/
+  /*member: A.returnEmpty3:[empty]*/
   returnEmpty3() {
     dynamic a = this;
     return a. /*[subclass=A]*/ /*update: [subclass=A]*/
@@ -52,14 +52,14 @@
         /*invoke: [empty]*/ --;
   }
 
-  /*element: A.returnEmpty1:[empty]*/
+  /*member: A.returnEmpty1:[empty]*/
   returnEmpty1() {
     dynamic a = this;
     return /*invoke: [empty]*/ --a
         . /*[subclass=A]*/ /*update: [subclass=A]*/ bar;
   }
 
-  /*element: A.returnEmpty2:[empty]*/
+  /*member: A.returnEmpty2:[empty]*/
   returnEmpty2() {
     dynamic a = this;
     return a. /*[subclass=A]*/ /*update: [subclass=A]*/ bar
@@ -67,41 +67,41 @@
   }
 }
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {
-  /*element: B.foo:[exact=JSUInt31]*/
+  /*member: B.foo:[exact=JSUInt31]*/
   get foo => 42;
-  /*element: B.[]:[exact=JSUInt31]*/
+  /*member: B.[]:[exact=JSUInt31]*/
   operator [](/*[empty]*/ index) => 42;
 
-  /*element: B.returnString1:Value([exact=JSString], value: "string")*/
+  /*member: B.returnString1:Value([exact=JSString], value: "string")*/
   returnString1() =>
       super.foo /*invoke: Value([exact=JSString], value: "string")*/ --;
 
-  /*element: B.returnDynamic1:[empty]*/
+  /*member: B.returnDynamic1:[empty]*/
   returnDynamic1() =>
       /*invoke: Value([exact=JSString], value: "string")*/
       --super.foo;
 
-  /*element: B.returnDynamic2:[empty]*/
+  /*member: B.returnDynamic2:[empty]*/
   returnDynamic2() =>
       super.foo /*invoke: Value([exact=JSString], value: "string")*/ -= 42;
 
-  /*element: B.returnString2:Value([exact=JSString], value: "string")*/
+  /*member: B.returnString2:Value([exact=JSString], value: "string")*/
   returnString2() => super[index]
       /*invoke: Value([exact=JSString], value: "string")*/ --;
 
-  /*element: B.returnDynamic3:[empty]*/
+  /*member: B.returnDynamic3:[empty]*/
   returnDynamic3() =>
       /*invoke: Value([exact=JSString], value: "string")*/
       --super[index];
 
-  /*element: B.returnDynamic4:[empty]*/
+  /*member: B.returnDynamic4:[empty]*/
   returnDynamic4() => super[index]
       /*invoke: Value([exact=JSString], value: "string")*/ -= 42;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new A()
     .. /*invoke: [exact=A]*/ returnNum1()
diff --git a/tests/compiler/dart2js/inference/data/prefix.dart b/tests/compiler/dart2js/inference/data/prefix.dart
index 32118ab..544ae70 100644
--- a/tests/compiler/dart2js/inference/data/prefix.dart
+++ b/tests/compiler/dart2js/inference/data/prefix.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   localPrefixInc();
   localPrefixDec();
@@ -18,7 +18,7 @@
 // Prefix increment on local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: localPrefixInc:[subclass=JSUInt32]*/
+/*member: localPrefixInc:[subclass=JSUInt32]*/
 localPrefixInc() {
   var local;
   if (local == null) {
@@ -31,7 +31,7 @@
 // Prefix decrement on local variable.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: localPrefixDec:[subclass=JSInt]*/
+/*member: localPrefixDec:[subclass=JSInt]*/
 localPrefixDec() {
   var local;
   if (local == null) {
@@ -44,10 +44,10 @@
 // Prefix increment on static field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _staticField1:[null|subclass=JSPositiveInt]*/
+/*member: _staticField1:[null|subclass=JSPositiveInt]*/
 var _staticField1;
 
-/*element: staticFieldPrefixInc:[subclass=JSPositiveInt]*/
+/*member: staticFieldPrefixInc:[subclass=JSPositiveInt]*/
 staticFieldPrefixInc() {
   if (_staticField1 == null) {
     _staticField1 = 0;
@@ -59,10 +59,10 @@
 // Prefix decrement on static field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _staticField2:[null|subclass=JSInt]*/
+/*member: _staticField2:[null|subclass=JSInt]*/
 var _staticField2;
 
-/*element: staticFieldPrefixDec:[subclass=JSInt]*/
+/*member: staticFieldPrefixDec:[subclass=JSInt]*/
 staticFieldPrefixDec() {
   if (_staticField2 == null) {
     _staticField2 = 0;
@@ -74,13 +74,13 @@
 // Prefix increment on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field1:[null|subclass=JSPositiveInt]*/
+  /*member: Class1.field1:[null|subclass=JSPositiveInt]*/
   var field1;
 }
 
-/*element: instanceFieldPrefixInc:[subclass=JSPositiveInt]*/
+/*member: instanceFieldPrefixInc:[subclass=JSPositiveInt]*/
 instanceFieldPrefixInc() {
   var c = new Class1();
   if (c. /*[exact=Class1]*/ field1 == null) {
@@ -97,13 +97,13 @@
 // Prefix decrement on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field2:[null|subclass=JSInt]*/
+  /*member: Class2.field2:[null|subclass=JSInt]*/
   var field2;
 }
 
-/*element: instanceFieldPrefixDec:[subclass=JSInt]*/
+/*member: instanceFieldPrefixDec:[subclass=JSInt]*/
 instanceFieldPrefixDec() {
   var c = new Class2();
   if (c. /*[exact=Class2]*/ field2 == null) {
@@ -120,13 +120,13 @@
 // Conditional prefix increment on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.field3:[null|subclass=JSPositiveInt]*/
+  /*member: Class3.field3:[null|subclass=JSPositiveInt]*/
   var field3;
 }
 
-/*element: conditionalInstanceFieldPrefixInc:[null|subclass=JSPositiveInt]*/
+/*member: conditionalInstanceFieldPrefixInc:[null|subclass=JSPositiveInt]*/
 conditionalInstanceFieldPrefixInc() {
   var c = new Class3();
   if (c. /*[exact=Class3]*/ field3 == null) {
@@ -143,13 +143,13 @@
 // Conditional prefix decrement on instance field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field4:[null|subclass=JSInt]*/
+  /*member: Class4.field4:[null|subclass=JSInt]*/
   var field4;
 }
 
-/*element: conditionalInstanceFieldPrefixDec:[null|subclass=JSInt]*/
+/*member: conditionalInstanceFieldPrefixDec:[null|subclass=JSInt]*/
 conditionalInstanceFieldPrefixDec() {
   var c = new Class4();
   if (c. /*[exact=Class4]*/ field4 == null) {
diff --git a/tests/compiler/dart2js/inference/data/refine_captured_locals.dart b/tests/compiler/dart2js/inference/data/refine_captured_locals.dart
index f11fc71..5a13864 100644
--- a/tests/compiler/dart2js/inference/data/refine_captured_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_captured_locals.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   refineBeforeCapture();
   refineAfterCapture();
@@ -14,13 +14,13 @@
 // Refine a local before it has been captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.method1:[null]*/
+  /*member: Class1.method1:[null]*/
   method1() {}
 }
 
-/*element: _refineBeforeCapture:[exact=Class1]*/
+/*member: _refineBeforeCapture:[exact=Class1]*/
 _refineBeforeCapture(/*[null|exact=Class1]*/ o) {
   o. /*invoke: [null|exact=Class1]*/ method1();
   o. /*invoke: [exact=Class1]*/ method1();
@@ -29,7 +29,7 @@
   return localFunction();
 }
 
-/*element: refineBeforeCapture:[null]*/
+/*member: refineBeforeCapture:[null]*/
 refineBeforeCapture() {
   _refineBeforeCapture(new Class1());
   _refineBeforeCapture(null);
@@ -39,16 +39,16 @@
 // Refine a local after it has been captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.method3:[null]*/
+  /*member: Class3.method3:[null]*/
   method3() {}
 }
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {}
 
-/*element: _refineAfterCapture:Union([exact=Class3], [exact=Class4])*/
+/*member: _refineAfterCapture:Union([exact=Class3], [exact=Class4])*/
 _refineAfterCapture(/*Union([exact=Class3], [exact=Class4])*/ o) {
   /*Union([exact=Class3], [exact=Class4])*/ localFunction() => o;
 
@@ -58,7 +58,7 @@
   return localFunction();
 }
 
-/*element: refineAfterCapture:[null]*/
+/*member: refineAfterCapture:[null]*/
 refineAfterCapture() {
   _refineAfterCapture(new Class3());
   _refineAfterCapture(new Class4());
@@ -68,16 +68,16 @@
 // Refine a local after it has been captured in a nested local function.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
 class Class5 {
-  /*element: Class5.method5:[null]*/
+  /*member: Class5.method5:[null]*/
   method5() {}
 }
 
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
 class Class6 {}
 
-/*element: _refineAfterNestedCapture:Union([exact=Class5], [exact=Class6])*/
+/*member: _refineAfterNestedCapture:Union([exact=Class5], [exact=Class6])*/
 _refineAfterNestedCapture(/*Union([exact=Class5], [exact=Class6])*/ o) {
   /*Union([exact=Class5], [exact=Class6])*/ localFunction() {
     /*Union([exact=Class5], [exact=Class6])*/ nestedFunction() => o;
@@ -90,7 +90,7 @@
   return localFunction();
 }
 
-/*element: refineAfterNestedCapture:[null]*/
+/*member: refineAfterNestedCapture:[null]*/
 refineAfterNestedCapture() {
   _refineAfterNestedCapture(new Class5());
   _refineAfterNestedCapture(new Class6());
@@ -100,16 +100,16 @@
 // Refine a local in a local function after it has been captured.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
 class Class7 {
-  /*element: Class7.method7:[null]*/
+  /*member: Class7.method7:[null]*/
   method7() {}
 }
 
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
 class Class8 {}
 
-/*element: _refineAfterCaptureInNested:Union([exact=Class7], [exact=Class8])*/
+/*member: _refineAfterCaptureInNested:Union([exact=Class7], [exact=Class8])*/
 _refineAfterCaptureInNested(/*Union([exact=Class7], [exact=Class8])*/ o) {
   /*Union([exact=Class7], [exact=Class8])*/ localFunction(
       /*Union([exact=Class7], [exact=Class8])*/ p) {
@@ -124,7 +124,7 @@
   return localFunction(o);
 }
 
-/*element: refineAfterCaptureInNested:[null]*/
+/*member: refineAfterCaptureInNested:[null]*/
 refineAfterCaptureInNested() {
   _refineAfterCaptureInNested(new Class7());
   _refineAfterCaptureInNested(new Class8());
diff --git a/tests/compiler/dart2js/inference/data/refine_locals.dart b/tests/compiler/dart2js/inference/data/refine_locals.dart
index b14eede..64f339d 100644
--- a/tests/compiler/dart2js/inference/data/refine_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_locals.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   refineToClass();
   refineToClosure();
@@ -13,31 +13,31 @@
 // accesses and updates.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.method0:[null]*/
+  /*member: Class1.method0:[null]*/
   method0() {}
-  /*element: Class1.method1:[null]*/
+  /*member: Class1.method1:[null]*/
   method1() {}
-  /*element: Class1.field0:[null|exact=JSUInt31]*/
+  /*member: Class1.field0:[null|exact=JSUInt31]*/
   var field0;
-  /*element: Class1.field1:[null|exact=JSUInt31]*/
+  /*member: Class1.field1:[null|exact=JSUInt31]*/
   var field1;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.method0:[null]*/
+  /*member: Class2.method0:[null]*/
   method0() {}
-  /*element: Class2.method2:[null]*/
+  /*member: Class2.method2:[null]*/
   method2() {}
-  /*element: Class2.field0:[null]*/
+  /*member: Class2.field0:[null]*/
   var field0;
-  /*element: Class2.field2:[null]*/
+  /*member: Class2.field2:[null]*/
   var field2;
 }
 
-/*element: _refineUnion:Union([exact=Class1], [exact=Class2])*/
+/*member: _refineUnion:Union([exact=Class1], [exact=Class2])*/
 _refineUnion(/*Union([null|exact=Class1], [null|exact=Class2])*/ o) {
   o. /*invoke: Union([null|exact=Class1], [null|exact=Class2])*/ method0();
   o. /*invoke: Union([exact=Class1], [exact=Class2])*/ method1();
@@ -45,28 +45,28 @@
   return o;
 }
 
-/*element: _refineFromMethod:[exact=Class1]*/
+/*member: _refineFromMethod:[exact=Class1]*/
 _refineFromMethod(/*[null|exact=Class1]*/ o) {
   o. /*invoke: [null|exact=Class1]*/ method0();
   o. /*invoke: [exact=Class1]*/ method1();
   return o;
 }
 
-/*element: _refineFromGetter:[exact=Class2]*/
+/*member: _refineFromGetter:[exact=Class2]*/
 _refineFromGetter(/*[null|exact=Class2]*/ o) {
   o. /*[null|exact=Class2]*/ field0;
   o. /*[exact=Class2]*/ field2;
   return o;
 }
 
-/*element: _refineFromSetter:[exact=Class1]*/
+/*member: _refineFromSetter:[exact=Class1]*/
 _refineFromSetter(/*[null|exact=Class1]*/ o) {
   o. /*update: [null|exact=Class1]*/ field0 = 0;
   o. /*update: [exact=Class1]*/ field1 = 0;
   return o;
 }
 
-/*element: _noRefinementNullAware:[null|exact=Class1]*/
+/*member: _noRefinementNullAware:[null|exact=Class1]*/
 _noRefinementNullAware(/*[null|exact=Class1]*/ o) {
   o
       ?.
@@ -75,7 +75,7 @@
   return o;
 }
 
-/*element: _noRefinementNullSelectors:[exact=Class2]*/
+/*member: _noRefinementNullSelectors:[exact=Class2]*/
 _noRefinementNullSelectors(/*[null|exact=Class2]*/ o) {
   o /*invoke: [null|exact=Class2]*/ == 2;
   o. /*[null|exact=Class2]*/ hashCode;
@@ -88,18 +88,18 @@
   return o;
 }
 
-/*element: _noRefinementUpdatedVariable:[null|exact=Class1]*/
+/*member: _noRefinementUpdatedVariable:[null|exact=Class1]*/
 _noRefinementUpdatedVariable(/*[null|exact=Class1]*/ o) {
   (o = o). /*invoke: [null|exact=Class1]*/ method1();
   (o = o). /*invoke: [null|exact=Class1]*/ method0();
   return o;
 }
 
-/*element: _condition:Value([exact=JSBool], value: false)*/
+/*member: _condition:Value([exact=JSBool], value: false)*/
 @pragma('dart2js:assumeDynamic')
 get _condition => false;
 
-/*element: refineToClass:[null]*/
+/*member: refineToClass:[null]*/
 refineToClass() {
   var nullOrClass1 = _condition ? null : new Class1();
   var nullOrClass2 = _condition ? null : new Class2();
@@ -118,21 +118,21 @@
 // Refine the type of a local variable through a sequence of invocations.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _refineToClosureLocal:[subclass=Closure]*/
+/*member: _refineToClosureLocal:[subclass=Closure]*/
 _refineToClosureLocal() {
   var f = /*[null]*/ ({/*[exact=JSUInt31]*/ a}) {};
   f(a: 0);
   return f;
 }
 
-/*element: _refineToClosureLocalCall:[subclass=Closure]*/
+/*member: _refineToClosureLocalCall:[subclass=Closure]*/
 _refineToClosureLocalCall() {
   var f = /*[null]*/ ({/*[exact=JSUInt31]*/ b}) {};
   f.call(b: 0);
   return f;
 }
 
-/*element: refineToClosure:[null]*/
+/*member: refineToClosure:[null]*/
 refineToClosure() {
   _refineToClosureLocal();
   _refineToClosureLocalCall();
diff --git a/tests/compiler/dart2js/inference/data/refine_order.dart b/tests/compiler/dart2js/inference/data/refine_order.dart
index 9bfe307..1a0b93e 100644
--- a/tests/compiler/dart2js/inference/data/refine_order.dart
+++ b/tests/compiler/dart2js/inference/data/refine_order.dart
@@ -2,16 +2,16 @@
 // 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.
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.field:[exact=JSUInt31]*/
+  /*member: Class.field:[exact=JSUInt31]*/
   var field = 42;
 
-  /*element: Class.method:[null]*/
+  /*member: Class.method:[null]*/
   method([/*[null|exact=JSUInt31]*/ a, /*[null|exact=JSUInt31]*/ b]) {}
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new Class();
   statementOrderFieldAccess(null);
@@ -31,7 +31,7 @@
 // Accesses in statements.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: statementOrderFieldAccess:[null]*/
+/*member: statementOrderFieldAccess:[null]*/
 @pragma('dart2js:assumeDynamic')
 statementOrderFieldAccess(/*[null|subclass=Object]*/ o) {
   o.field;
@@ -42,7 +42,7 @@
 // Updates in statements.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: statementOrderFieldUpdate:[null]*/
+/*member: statementOrderFieldUpdate:[null]*/
 @pragma('dart2js:assumeDynamic')
 statementOrderFieldUpdate(/*[null|subclass=Object]*/ o) {
   o.field = 42;
@@ -53,7 +53,7 @@
 // Invocations in statements.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: statementOrderInvocation:[null]*/
+/*member: statementOrderInvocation:[null]*/
 @pragma('dart2js:assumeDynamic')
 statementOrderInvocation(/*[null|subclass=Object]*/ o) {
   o.method(null);
@@ -64,7 +64,7 @@
 // Access in argument before method call.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: receiverVsArgument:[null]*/
+/*member: receiverVsArgument:[null]*/
 @pragma('dart2js:assumeDynamic')
 receiverVsArgument(/*[null|subclass=Object]*/ o) {
   // TODO(johnniwinther): The arguments should refine the receiver.
@@ -76,7 +76,7 @@
 // Access in multiple arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: argumentsOrder:[null]*/
+/*member: argumentsOrder:[null]*/
 @pragma('dart2js:assumeDynamic')
 argumentsOrder(/*[null|subclass=Object]*/ o) {
   // TODO(johnniwinther): The arguments should refine the receiver.
@@ -88,7 +88,7 @@
 // Access in both sides of an operator call.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: operatorOrder:[null]*/
+/*member: operatorOrder:[null]*/
 @pragma('dart2js:assumeDynamic')
 operatorOrder(/*[null|subclass=Object]*/ o) {
   o.field /*invoke: [exact=JSUInt31]*/ < o. /*[subclass=Object]*/ field;
@@ -99,7 +99,7 @@
 // Assign after access in right-hand side.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: updateVsRhs:[null]*/
+/*member: updateVsRhs:[null]*/
 @pragma('dart2js:assumeDynamic')
 updateVsRhs(/*[null|subclass=Object]*/ o) {
   // TODO(johnniwinther): The right-hand side should refine the left-hand side
@@ -112,7 +112,7 @@
 // Access in both sides of a logical or.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: logicalOr:[null]*/
+/*member: logicalOr:[null]*/
 @pragma('dart2js:assumeDynamic')
 logicalOr(/*[null|subclass=Object]*/ o) {
   o.field || o. /*[subclass=Object]*/ field;
@@ -123,7 +123,7 @@
 // Access in condition of a conditional expression.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: conditionalCondition:[null]*/
+/*member: conditionalCondition:[null]*/
 @pragma('dart2js:assumeDynamic')
 conditionalCondition(/*[null|subclass=Object]*/ o) {
   o.field ? o. /*[subclass=Object]*/ field : o. /*[subclass=Object]*/ field;
@@ -134,7 +134,7 @@
 // Access both branches of a conditional expression.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: conditionalBothBranches:[null]*/
+/*member: conditionalBothBranches:[null]*/
 @pragma('dart2js:assumeDynamic')
 conditionalBothBranches(/*[null|subclass=Object]*/ o) {
   // ignore: DEAD_CODE
@@ -146,7 +146,7 @@
 // Access in only one branch of a conditional expression.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: conditionalOneBranchOnly:[null]*/
+/*member: conditionalOneBranchOnly:[null]*/
 @pragma('dart2js:assumeDynamic')
 conditionalOneBranchOnly(/*[null|subclass=Object]*/ o) {
   // ignore: DEAD_CODE
diff --git a/tests/compiler/dart2js/inference/data/return.dart b/tests/compiler/dart2js/inference/data/return.dart
index 3e6d17c..01a574f 100644
--- a/tests/compiler/dart2js/inference/data/return.dart
+++ b/tests/compiler/dart2js/inference/data/return.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   return null;
 }
diff --git a/tests/compiler/dart2js/inference/data/simple.dart b/tests/compiler/dart2js/inference/data/simple.dart
index a4429ce..81fcc94 100644
--- a/tests/compiler/dart2js/inference/data/simple.dart
+++ b/tests/compiler/dart2js/inference/data/simple.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   zero();
   one();
@@ -28,113 +28,113 @@
 /// Return a zero integer literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: zero:[exact=JSUInt31]*/
+/*member: zero:[exact=JSUInt31]*/
 zero() => 0;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a positive integer literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: one:[exact=JSUInt31]*/
+/*member: one:[exact=JSUInt31]*/
 one() => 1;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a double literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: half:[exact=JSDouble]*/
+/*member: half:[exact=JSDouble]*/
 half() => 0.5;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return an integer valued zero double literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: zeroPointZero:[exact=JSUInt31]*/
+/*member: zeroPointZero:[exact=JSUInt31]*/
 zeroPointZero() => 0.0;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return an integer valued double literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: onePointZero:[exact=JSUInt31]*/
+/*member: onePointZero:[exact=JSUInt31]*/
 onePointZero() => 1.0;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a >31bit integer literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: large:[subclass=JSUInt32]*/
+/*member: large:[subclass=JSUInt32]*/
 large() => 2147483648;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a >32bit integer literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: huge:[subclass=JSPositiveInt]*/
+/*member: huge:[subclass=JSPositiveInt]*/
 huge() => 4294967296;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a negative integer literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: minusOne:[subclass=JSInt]*/
+/*member: minusOne:[subclass=JSInt]*/
 minusOne() => /*invoke: [exact=JSUInt31]*/ -1;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a negative double literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: minusHalf:[subclass=JSNumber]*/
+/*member: minusHalf:[subclass=JSNumber]*/
 minusHalf() => /*invoke: [exact=JSDouble]*/ -0.5;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return an empty string.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: emptyString:Value([exact=JSString], value: "")*/
+/*member: emptyString:Value([exact=JSString], value: "")*/
 emptyString() => '';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a non-empty string.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: nonEmptyString:Value([exact=JSString], value: "foo")*/
+/*member: nonEmptyString:Value([exact=JSString], value: "foo")*/
 nonEmptyString() => 'foo';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a string juxtaposition.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: stringJuxtaposition:[exact=JSString]*/
+/*member: stringJuxtaposition:[exact=JSString]*/
 stringJuxtaposition() => 'foo' 'bar';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a string constant interpolation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: stringConstantInterpolation:[exact=JSString]*/
+/*member: stringConstantInterpolation:[exact=JSString]*/
 stringConstantInterpolation() => 'foo${'bar'}';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a string non-constant interpolation.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[exact=JSBool]*/
+/*member: _method1:[exact=JSBool]*/
 _method1(/*[exact=JSBool]*/ c) => c;
 
-/*element: stringNonConstantInterpolation:[exact=JSString]*/
+/*member: stringNonConstantInterpolation:[exact=JSString]*/
 stringNonConstantInterpolation() => 'foo${_method1(true)}${_method1(false)}';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a symbol literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: symbolLiteral:[exact=Symbol]*/
+/*member: symbolLiteral:[exact=Symbol]*/
 symbolLiteral() => #main;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Return a type literal.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: typeLiteral:[exact=TypeImpl]*/
+/*member: typeLiteral:[exact=TypeImpl]*/
 typeLiteral() => Object;
diff --git a/tests/compiler/dart2js/inference/data/static.dart b/tests/compiler/dart2js/inference/data/static.dart
index 4b65a4c..2187263 100644
--- a/tests/compiler/dart2js/inference/data/static.dart
+++ b/tests/compiler/dart2js/inference/data/static.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleStaticCall();
   staticCallWithPositionalArguments1();
@@ -39,10 +39,10 @@
 /// Call a static method that has a constant return value.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleStaticCall:[exact=JSUInt31]*/
+/*member: simpleStaticCall:[exact=JSUInt31]*/
 simpleStaticCall() => _returnInt();
 
-/*element: _returnInt:[exact=JSUInt31]*/
+/*member: _returnInt:[exact=JSUInt31]*/
 _returnInt() => 0;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -50,10 +50,10 @@
 /// is returned.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithPositionalArguments1:[exact=JSUInt31]*/
+/*member: staticCallWithPositionalArguments1:[exact=JSUInt31]*/
 staticCallWithPositionalArguments1() => _returnFirst(0, 0.5);
 
-/*element: _returnFirst:[exact=JSUInt31]*/
+/*member: _returnFirst:[exact=JSUInt31]*/
 _returnFirst(/*[exact=JSUInt31]*/ a, /*[exact=JSDouble]*/ b) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -61,10 +61,10 @@
 /// is returned.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithPositionalArguments2:[exact=JSDouble]*/
+/*member: staticCallWithPositionalArguments2:[exact=JSDouble]*/
 staticCallWithPositionalArguments2() => _returnSecond(0, 0.5);
 
-/*element: _returnSecond:[exact=JSDouble]*/
+/*member: _returnSecond:[exact=JSDouble]*/
 _returnSecond(/*[exact=JSUInt31]*/ a, /*[exact=JSDouble]*/ b) => b;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -72,10 +72,10 @@
 /// value. Only one call site with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments1:[null]*/
+/*member: staticCallWithOptionalArguments1:[null]*/
 staticCallWithOptionalArguments1() => _returnDefaultNull();
 
-/*element: _returnDefaultNull:[null]*/
+/*member: _returnDefaultNull:[null]*/
 _returnDefaultNull([/*[null]*/ a]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -83,10 +83,10 @@
 /// value of `null`. Only one call site with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments2:[null]*/
+/*member: staticCallWithOptionalArguments2:[null]*/
 staticCallWithOptionalArguments2() => _returnDefaultNullExplicit();
 
-/*element: _returnDefaultNullExplicit:[null]*/
+/*member: _returnDefaultNullExplicit:[null]*/
 _returnDefaultNullExplicit([/*[null]*/ a = null]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -94,10 +94,10 @@
 /// explicit argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments3:[exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments3:[exact=JSUInt31]*/
 staticCallWithOptionalArguments3() => _returnDefaultNullCalled(0);
 
-/*element: _returnDefaultNullCalled:[exact=JSUInt31]*/
+/*member: _returnDefaultNullCalled:[exact=JSUInt31]*/
 _returnDefaultNullCalled([/*[exact=JSUInt31]*/ a]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -105,13 +105,13 @@
 /// with an explicit argument and one with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments4a:[null|exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments4a:[null|exact=JSUInt31]*/
 staticCallWithOptionalArguments4a() => _returnDefaultNullCalledTwice();
 
-/*element: staticCallWithOptionalArguments4b:[null|exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments4b:[null|exact=JSUInt31]*/
 staticCallWithOptionalArguments4b() => _returnDefaultNullCalledTwice(0);
 
-/*element: _returnDefaultNullCalledTwice:[null|exact=JSUInt31]*/
+/*member: _returnDefaultNullCalledTwice:[null|exact=JSUInt31]*/
 _returnDefaultNullCalledTwice([/*[null|exact=JSUInt31]*/ a]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -119,10 +119,10 @@
 /// Only one call site with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments5:[exact=JSUInt31]*/
+/*member: staticCallWithOptionalArguments5:[exact=JSUInt31]*/
 staticCallWithOptionalArguments5() => _returnDefaultZero();
 
-/*element: _returnDefaultZero:[exact=JSUInt31]*/
+/*member: _returnDefaultZero:[exact=JSUInt31]*/
 _returnDefaultZero([/*[exact=JSUInt31]*/ a = 0]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -130,10 +130,10 @@
 /// Only one call site with an argument of a different type.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithOptionalArguments6:[exact=JSDouble]*/
+/*member: staticCallWithOptionalArguments6:[exact=JSDouble]*/
 staticCallWithOptionalArguments6() => _returnDefaultZeroCalled(0.5);
 
-/*element: _returnDefaultZeroCalled:[exact=JSDouble]*/
+/*member: _returnDefaultZeroCalled:[exact=JSDouble]*/
 _returnDefaultZeroCalled([/*[exact=JSDouble]*/ a = 0]) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -141,10 +141,10 @@
 /// Only one call site with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithNamedArguments1:[exact=JSUInt31]*/
+/*member: staticCallWithNamedArguments1:[exact=JSUInt31]*/
 staticCallWithNamedArguments1() => _returnNamedDefaultZero();
 
-/*element: _returnNamedDefaultZero:[exact=JSUInt31]*/
+/*member: _returnNamedDefaultZero:[exact=JSUInt31]*/
 _returnNamedDefaultZero({/*[exact=JSUInt31]*/ a: 0}) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -152,10 +152,10 @@
 /// Only one call site with an argument of a different type.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithNamedArguments2:[exact=JSDouble]*/
+/*member: staticCallWithNamedArguments2:[exact=JSDouble]*/
 staticCallWithNamedArguments2() => _returnNamedDefaultZeroCalled(a: 0.5);
 
-/*element: _returnNamedDefaultZeroCalled:[exact=JSDouble]*/
+/*member: _returnNamedDefaultZeroCalled:[exact=JSDouble]*/
 _returnNamedDefaultZeroCalled({/*[exact=JSDouble]*/ a: 0}) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -163,55 +163,55 @@
 /// explicit argument and one with no arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: staticCallWithNamedArguments3a:[null|exact=JSDouble]*/
+/*member: staticCallWithNamedArguments3a:[null|exact=JSDouble]*/
 staticCallWithNamedArguments3a() => _returnNamedNullCalledTwice();
 
-/*element: staticCallWithNamedArguments3b:[null|exact=JSDouble]*/
+/*member: staticCallWithNamedArguments3b:[null|exact=JSDouble]*/
 staticCallWithNamedArguments3b() => _returnNamedNullCalledTwice(a: 0.5);
 
-/*element: _returnNamedNullCalledTwice:[null|exact=JSDouble]*/
+/*member: _returnNamedNullCalledTwice:[null|exact=JSDouble]*/
 _returnNamedNullCalledTwice({/*[null|exact=JSDouble]*/ a}) => a;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Call an uninitialized top level field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field1:[null]*/
+/*member: _field1:[null]*/
 dynamic _field1;
 
-/*element: invokeStaticFieldUninitialized:[null|subclass=Object]*/
+/*member: invokeStaticFieldUninitialized:[null|subclass=Object]*/
 invokeStaticFieldUninitialized() => _field1();
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Call a top level field initialized to a tear-off of a top level method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[exact=JSUInt31]*/
+/*member: _method1:[exact=JSUInt31]*/
 _method1() => 42;
 
-/*strong.element: _field2:[null|subclass=Closure]*/
-/*omit.element: _field2:[null|subclass=Closure]*/
-/*strongConst.element: _field2:[subclass=Closure]*/
-/*omitConst.element: _field2:[subclass=Closure]*/
+/*strong.member: _field2:[null|subclass=Closure]*/
+/*omit.member: _field2:[null|subclass=Closure]*/
+/*strongConst.member: _field2:[subclass=Closure]*/
+/*omitConst.member: _field2:[subclass=Closure]*/
 dynamic _field2 = _method1;
 
-/*element: invokeStaticFieldTearOff:[null|subclass=Object]*/
+/*member: invokeStaticFieldTearOff:[null|subclass=Object]*/
 invokeStaticFieldTearOff() => _field2();
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Call a top level field initialized to a tear-off of a top level method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method5:Value([exact=JSString], value: "")*/
+/*member: _method5:Value([exact=JSString], value: "")*/
 String _method5() => '';
 
-/*strong.element: _field5:[null|subclass=Closure]*/
-/*omit.element: _field5:[null|subclass=Closure]*/
-/*strongConst.element: _field5:[subclass=Closure]*/
-/*omitConst.element: _field5:[subclass=Closure]*/
+/*strong.member: _field5:[null|subclass=Closure]*/
+/*omit.member: _field5:[null|subclass=Closure]*/
+/*strongConst.member: _field5:[subclass=Closure]*/
+/*omitConst.member: _field5:[subclass=Closure]*/
 String Function() _field5 = _method5;
 
-/*element: invokeStaticTypedFieldTearOff:[null|exact=JSString]*/
+/*member: invokeStaticTypedFieldTearOff:[null|exact=JSString]*/
 invokeStaticTypedFieldTearOff() => _field5();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -219,51 +219,51 @@
 /// taking one argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method2:[exact=JSUInt31]*/
+/*member: _method2:[exact=JSUInt31]*/
 _method2(/*[exact=JSUInt31]*/ o) => 42;
 
-/*strong.element: _field3:[null|subclass=Closure]*/
-/*omit.element: _field3:[null|subclass=Closure]*/
-/*strongConst.element: _field3:[subclass=Closure]*/
-/*omitConst.element: _field3:[subclass=Closure]*/
+/*strong.member: _field3:[null|subclass=Closure]*/
+/*omit.member: _field3:[null|subclass=Closure]*/
+/*strongConst.member: _field3:[subclass=Closure]*/
+/*omitConst.member: _field3:[subclass=Closure]*/
 dynamic _field3 = _method2;
 
-/*element: invokeStaticFieldTearOffParameters:[null|subclass=Object]*/
+/*member: invokeStaticFieldTearOffParameters:[null|subclass=Object]*/
 invokeStaticFieldTearOffParameters() => _field3(42);
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Call a top level getter returning a tear-off of a top level method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method3:[exact=JSUInt31]*/
+/*member: _method3:[exact=JSUInt31]*/
 _method3() => 42;
 
-/*element: _getter1:[subclass=Closure]*/
+/*member: _getter1:[subclass=Closure]*/
 get _getter1 => _method3;
 
-/*element: invokeStaticGetterTearOff:[null|subclass=Object]*/
+/*member: invokeStaticGetterTearOff:[null|subclass=Object]*/
 invokeStaticGetterTearOff() => _getter1();
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Call a typed top level getter returning a tear-off of a top level method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method6:[exact=JSUInt31]*/
+/*member: _method6:[exact=JSUInt31]*/
 int _method6() => 0;
 
-/*strong.element: _field7:[null|subclass=Closure]*/
-/*omit.element: _field7:[null|subclass=Closure]*/
-/*strongConst.element: _field7:[subclass=Closure]*/
-/*omitConst.element: _field7:[subclass=Closure]*/
+/*strong.member: _field7:[null|subclass=Closure]*/
+/*omit.member: _field7:[null|subclass=Closure]*/
+/*strongConst.member: _field7:[subclass=Closure]*/
+/*omitConst.member: _field7:[subclass=Closure]*/
 int Function() _field7 = _method6;
 
-/*strong.element: _getter3:[null|subclass=Closure]*/
-/*omit.element: _getter3:[null|subclass=Closure]*/
-/*strongConst.element: _getter3:[subclass=Closure]*/
-/*omitConst.element: _getter3:[subclass=Closure]*/
+/*strong.member: _getter3:[null|subclass=Closure]*/
+/*omit.member: _getter3:[null|subclass=Closure]*/
+/*strongConst.member: _getter3:[subclass=Closure]*/
+/*omitConst.member: _getter3:[subclass=Closure]*/
 int Function() get _getter3 => _field7;
 
-/*element: invokeStaticTypedGetterTearOff:[null|subclass=JSInt]*/
+/*member: invokeStaticTypedGetterTearOff:[null|subclass=JSInt]*/
 invokeStaticTypedGetterTearOff() => _getter3();
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -271,13 +271,13 @@
 /// arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method4:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _method4:Union([exact=JSString], [exact=JSUInt31])*/
 T _method4<T>(T /*Union([exact=JSString], [exact=JSUInt31])*/ t) => t;
 
-/*element: invokeStaticGenericMethod1:[exact=JSUInt31]*/
+/*member: invokeStaticGenericMethod1:[exact=JSUInt31]*/
 invokeStaticGenericMethod1() => _method4(0);
 
-/*element: invokeStaticGenericMethod2:[exact=JSString]*/
+/*member: invokeStaticGenericMethod2:[exact=JSString]*/
 invokeStaticGenericMethod2() => _method4('');
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -285,13 +285,13 @@
 /// arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _getter2:[subclass=Closure]*/
+/*member: _getter2:[subclass=Closure]*/
 T Function<T>(T) get _getter2 => _method4;
 
-/*element: invokeStaticGenericGetter1:[null|subclass=JSInt]*/
+/*member: invokeStaticGenericGetter1:[null|subclass=JSInt]*/
 invokeStaticGenericGetter1() => _getter2(0);
 
-/*element: invokeStaticGenericGetter2:[null|exact=JSString]*/
+/*member: invokeStaticGenericGetter2:[null|exact=JSString]*/
 invokeStaticGenericGetter2() => _getter2('');
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -299,14 +299,14 @@
 /// arguments.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*strong.element: _field4:[null|subclass=Closure]*/
-/*omit.element: _field4:[null|subclass=Closure]*/
-/*strongConst.element: _field4:[subclass=Closure]*/
-/*omitConst.element: _field4:[subclass=Closure]*/
+/*strong.member: _field4:[null|subclass=Closure]*/
+/*omit.member: _field4:[null|subclass=Closure]*/
+/*strongConst.member: _field4:[subclass=Closure]*/
+/*omitConst.member: _field4:[subclass=Closure]*/
 T Function<T>(T) _field4 = _method4;
 
-/*element: invokeStaticGenericField1:[null|subclass=JSInt]*/
+/*member: invokeStaticGenericField1:[null|subclass=JSInt]*/
 invokeStaticGenericField1() => _field4(0);
 
-/*element: invokeStaticGenericField2:[null|exact=JSString]*/
+/*member: invokeStaticGenericField2:[null|exact=JSString]*/
 invokeStaticGenericField2() => _field4('');
diff --git a/tests/compiler/dart2js/inference/data/static_get.dart b/tests/compiler/dart2js/inference/data/static_get.dart
index 032a9ed..0a3bf8a 100644
--- a/tests/compiler/dart2js/inference/data/static_get.dart
+++ b/tests/compiler/dart2js/inference/data/static_get.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   getTopLevelFieldUninitialized();
   getStaticFieldUninitialized();
@@ -22,10 +22,10 @@
 /// Static get of an uninitialized top level field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field1:[null]*/
+/*member: _field1:[null]*/
 var _field1;
 
-/*element: getTopLevelFieldUninitialized:[null]*/
+/*member: getTopLevelFieldUninitialized:[null]*/
 getTopLevelFieldUninitialized() => _field1;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -33,21 +33,21 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.field:[null]*/
+  /*member: Class1.field:[null]*/
   static var field;
 }
 
-/*element: getStaticFieldUninitialized:[null]*/
+/*member: getStaticFieldUninitialized:[null]*/
 getStaticFieldUninitialized() => Class1.field;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Static get of an initialized top level field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _field2:[exact=JSUInt31]*/
+/*member: _field2:[exact=JSUInt31]*/
 var _field2 = 42;
 
-/*element: getTopLevelFieldInitialized:[exact=JSUInt31]*/
+/*member: getTopLevelFieldInitialized:[exact=JSUInt31]*/
 getTopLevelFieldInitialized() => _field2;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -55,11 +55,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field:[exact=JSUInt31]*/
+  /*member: Class2.field:[exact=JSUInt31]*/
   static var field = 42;
 }
 
-/*element: getStaticFieldInitialized:[exact=JSUInt31]*/
+/*member: getStaticFieldInitialized:[exact=JSUInt31]*/
 getStaticFieldInitialized() => Class2.field;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -67,13 +67,13 @@
 /// null.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method3:[exact=JSUInt31]*/
+/*member: _method3:[exact=JSUInt31]*/
 _method3() => 42;
 
-/*element: _field3:[null|exact=JSUInt31]*/
+/*member: _field3:[null|exact=JSUInt31]*/
 var _field3 = _method3();
 
-/*element: getTopLevelFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
+/*member: getTopLevelFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
 getTopLevelFieldInitializedPotentiallyNull() => _field3;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -81,24 +81,24 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3 {
-  /*element: Class3.method:[exact=JSUInt31]*/
+  /*member: Class3.method:[exact=JSUInt31]*/
   static method() => 42;
 
-  /*element: Class3.field:[null|exact=JSUInt31]*/
+  /*member: Class3.field:[null|exact=JSUInt31]*/
   static var field = method();
 }
 
-/*element: getStaticFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
+/*member: getStaticFieldInitializedPotentiallyNull:[null|exact=JSUInt31]*/
 getStaticFieldInitializedPotentiallyNull() => Class3.field;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Static get of a top level method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method4:[exact=JSUInt31]*/
+/*member: _method4:[exact=JSUInt31]*/
 _method4() => 42;
 
-/*element: getTopLevelMethod:[subclass=Closure]*/
+/*member: getTopLevelMethod:[subclass=Closure]*/
 getTopLevelMethod() => _method4;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -106,21 +106,21 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4 {
-  /*element: Class4.method:[exact=JSUInt31]*/
+  /*member: Class4.method:[exact=JSUInt31]*/
   static method() => 42;
 }
 
-/*element: getStaticMethod:[subclass=Closure]*/
+/*member: getStaticMethod:[subclass=Closure]*/
 getStaticMethod() => Class4.method;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Static get of a top level getter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _getter1:[exact=JSUInt31]*/
+/*member: _getter1:[exact=JSUInt31]*/
 get _getter1 => 42;
 
-/*element: getTopLevelGetter:[exact=JSUInt31]*/
+/*member: getTopLevelGetter:[exact=JSUInt31]*/
 getTopLevelGetter() => _getter1;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -128,9 +128,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class5 {
-  /*element: Class5.getter:[exact=JSUInt31]*/
+  /*member: Class5.getter:[exact=JSUInt31]*/
   static get getter => 42;
 }
 
-/*element: getStaticGetter:[exact=JSUInt31]*/
+/*member: getStaticGetter:[exact=JSUInt31]*/
 getStaticGetter() => Class5.getter;
diff --git a/tests/compiler/dart2js/inference/data/static_set.dart b/tests/compiler/dart2js/inference/data/static_set.dart
index 9510845..80c95eb 100644
--- a/tests/compiler/dart2js/inference/data/static_set.dart
+++ b/tests/compiler/dart2js/inference/data/static_set.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   setTopLevelFieldUninitialized();
   setStaticFieldUninitialized();
@@ -17,10 +17,10 @@
 /// Static set of an uninitialized top level field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: field1:[null|exact=JSUInt31]*/
+/*member: field1:[null|exact=JSUInt31]*/
 var field1;
 
-/*element: setTopLevelFieldUninitialized:[exact=JSUInt31]*/
+/*member: setTopLevelFieldUninitialized:[exact=JSUInt31]*/
 setTopLevelFieldUninitialized() => field1 = 42;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -28,21 +28,21 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.field:[null|exact=JSUInt31]*/
+  /*member: Class1.field:[null|exact=JSUInt31]*/
   static var field;
 }
 
-/*element: setStaticFieldUninitialized:[exact=JSUInt31]*/
+/*member: setStaticFieldUninitialized:[exact=JSUInt31]*/
 setStaticFieldUninitialized() => Class1.field = 42;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Static set of an initialized top level field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: field2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: field2:Union([exact=JSString], [exact=JSUInt31])*/
 dynamic field2 = '';
 
-/*element: setTopLevelFieldInitialized:[exact=JSUInt31]*/
+/*member: setTopLevelFieldInitialized:[exact=JSUInt31]*/
 setTopLevelFieldInitialized() => field2 = 42;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -50,11 +50,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.field:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: Class2.field:Union([exact=JSString], [exact=JSUInt31])*/
   static dynamic field = '';
 }
 
-/*element: setStaticFieldInitialized:[exact=JSUInt31]*/
+/*member: setStaticFieldInitialized:[exact=JSUInt31]*/
 setStaticFieldInitialized() => Class2.field = 42;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -63,7 +63,7 @@
 
 set _setter1(/*[exact=JSUInt31]*/ value) {}
 
-/*element: setTopLevelSetter:[exact=JSUInt31]*/
+/*member: setTopLevelSetter:[exact=JSUInt31]*/
 setTopLevelSetter() => _setter1 = 42;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -74,5 +74,5 @@
   static set setter(/*[exact=JSUInt31]*/ value) {}
 }
 
-/*element: setStaticSetter:[exact=JSUInt31]*/
+/*member: setStaticSetter:[exact=JSUInt31]*/
 setStaticSetter() => Class3.setter = 42;
diff --git a/tests/compiler/dart2js/inference/data/static_type.dart b/tests/compiler/dart2js/inference/data/static_type.dart
index b25a3a8..d9b0e0b 100644
--- a/tests/compiler/dart2js/inference/data/static_type.dart
+++ b/tests/compiler/dart2js/inference/data/static_type.dart
@@ -3,19 +3,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C<T> {
-  /*element: C.field:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: C.field:Union([exact=JSString], [exact=JSUInt31])*/
   final T field;
 
-  /*element: C.fixedFunctionField:[subclass=Closure]*/
+  /*member: C.fixedFunctionField:[subclass=Closure]*/
   int Function() fixedFunctionField = /*[exact=JSUInt31]*/ () => 0;
 
-  /*element: C.functionField:[null|subclass=Closure]*/
+  /*member: C.functionField:[null|subclass=Closure]*/
   T Function() functionField;
 
-  /*element: C.genericFunctionField:[null|subclass=Closure]*/
+  /*member: C.genericFunctionField:[null|subclass=Closure]*/
   S Function<S>(S) genericFunctionField;
 
-  /*element: C.:[exact=C]*/
+  /*member: C.:[exact=C]*/
   C(this. /*Union([exact=JSString], [exact=JSUInt31])*/ field) {
     /*update: [subclass=C]*/ functionField =
         /*Union([exact=JSString], [exact=JSUInt31])*/
@@ -25,125 +25,125 @@
     /*update: [subclass=C]*/ genericFunctionField = local;
   }
 
-  /*element: C.method:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: C.method:Union([exact=JSString], [exact=JSUInt31])*/
   T method() => /*[subclass=C]*/ field;
 
-  /*element: C.+:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: C.+:Union([exact=JSString], [exact=JSUInt31])*/
   T operator +(T /*Union([exact=JSString], [exact=JSUInt31])*/ t) =>
       /*[subclass=C]*/ field;
 
-  /*element: C.getter:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: C.getter:Union([exact=JSString], [exact=JSUInt31])*/
   T get getter => /*[subclass=C]*/ field;
 
-  /*element: C.fixedFunctionGetter:[subclass=Closure]*/
+  /*member: C.fixedFunctionGetter:[subclass=Closure]*/
   int Function() get fixedFunctionGetter => /*[exact=JSUInt31]*/ () => 0;
 
-  /*element: C.functionGetter:[null|subclass=Closure]*/
+  /*member: C.functionGetter:[null|subclass=Closure]*/
   T Function() get functionGetter => /*[subclass=C]*/ functionField;
 
-  /*element: C.genericFunctionGetter:[null|subclass=Closure]*/
+  /*member: C.genericFunctionGetter:[null|subclass=Closure]*/
   S Function<S>(S) get genericFunctionGetter =>
       /*[subclass=C]*/ genericFunctionField;
 
-  /*element: C.genericMethod:Union([exact=JSString], [exact=JSUInt31])*/
+  /*member: C.genericMethod:Union([exact=JSString], [exact=JSUInt31])*/
   S genericMethod<S>(S /*Union([exact=JSString], [exact=JSUInt31])*/ s) => s;
 }
 
 class D1 extends C<int> {
-  /*element: D1.:[exact=D1]*/
+  /*member: D1.:[exact=D1]*/
   D1(int /*[exact=JSUInt31]*/ field) : super(field);
 
-  /*element: D1.superFieldAccess:[exact=JSUInt31]*/
+  /*member: D1.superFieldAccess:[exact=JSUInt31]*/
   superFieldAccess() => super.field;
 
-  /*element: D1.superFieldInvoke:[null|subclass=JSInt]*/
+  /*member: D1.superFieldInvoke:[null|subclass=JSInt]*/
   superFieldInvoke() => super.functionField();
 
-  /*element: D1.superFixedFieldInvoke:[null|subclass=JSInt]*/
+  /*member: D1.superFixedFieldInvoke:[null|subclass=JSInt]*/
   superFixedFieldInvoke() => super.fixedFunctionField();
 
-  /*element: D1.superMethodInvoke:[exact=JSUInt31]*/
+  /*member: D1.superMethodInvoke:[exact=JSUInt31]*/
   superMethodInvoke() => super.method();
 
-  /*element: D1.superOperatorInvoke:[exact=JSUInt31]*/
+  /*member: D1.superOperatorInvoke:[exact=JSUInt31]*/
   superOperatorInvoke() => super + 0;
 
-  /*element: D1.superGetterAccess:[exact=JSUInt31]*/
+  /*member: D1.superGetterAccess:[exact=JSUInt31]*/
   superGetterAccess() => super.getter;
 
-  /*element: D1.superGetterInvoke:[null|subclass=JSInt]*/
+  /*member: D1.superGetterInvoke:[null|subclass=JSInt]*/
   superGetterInvoke() => super.functionGetter();
 
-  /*element: D1.superFixedGetterInvoke:[null|subclass=JSInt]*/
+  /*member: D1.superFixedGetterInvoke:[null|subclass=JSInt]*/
   superFixedGetterInvoke() => super.fixedFunctionGetter();
 
-  /*element: D1.superGenericFieldInvoke1:[null|exact=JSString]*/
+  /*member: D1.superGenericFieldInvoke1:[null|exact=JSString]*/
   superGenericFieldInvoke1() => super.genericFunctionField('');
 
-  /*element: D1.superGenericFieldInvoke2:[null|subclass=JSInt]*/
+  /*member: D1.superGenericFieldInvoke2:[null|subclass=JSInt]*/
   superGenericFieldInvoke2() => super.genericFunctionField(0);
 
-  /*element: D1.superGenericMethodInvoke1:[exact=JSString]*/
+  /*member: D1.superGenericMethodInvoke1:[exact=JSString]*/
   superGenericMethodInvoke1() => super.genericMethod('');
 
-  /*element: D1.superGenericMethodInvoke2:[exact=JSUInt31]*/
+  /*member: D1.superGenericMethodInvoke2:[exact=JSUInt31]*/
   superGenericMethodInvoke2() => super.genericMethod(0);
 
-  /*element: D1.superGenericGetterInvoke1:[null|exact=JSString]*/
+  /*member: D1.superGenericGetterInvoke1:[null|exact=JSString]*/
   superGenericGetterInvoke1() => super.genericFunctionGetter('');
 
-  /*element: D1.superGenericGetterInvoke2:[null|subclass=JSInt]*/
+  /*member: D1.superGenericGetterInvoke2:[null|subclass=JSInt]*/
   superGenericGetterInvoke2() => super.genericFunctionGetter(0);
 }
 
 class D2 extends C<String> {
-  /*element: D2.:[exact=D2]*/
+  /*member: D2.:[exact=D2]*/
   D2(String /*Value([exact=JSString], value: "")*/ field) : super(field);
 
-  /*element: D2.superFieldAccess:[exact=JSString]*/
+  /*member: D2.superFieldAccess:[exact=JSString]*/
   superFieldAccess() => super.field;
 
-  /*element: D2.superFieldInvoke:[null|exact=JSString]*/
+  /*member: D2.superFieldInvoke:[null|exact=JSString]*/
   superFieldInvoke() => super.functionField();
 
-  /*element: D2.superFixedFieldInvoke:[null|subclass=JSInt]*/
+  /*member: D2.superFixedFieldInvoke:[null|subclass=JSInt]*/
   superFixedFieldInvoke() => super.fixedFunctionField();
 
-  /*element: D2.superMethodInvoke:[exact=JSString]*/
+  /*member: D2.superMethodInvoke:[exact=JSString]*/
   superMethodInvoke() => super.method();
 
-  /*element: D2.superOperatorInvoke:[exact=JSString]*/
+  /*member: D2.superOperatorInvoke:[exact=JSString]*/
   superOperatorInvoke() => super + '';
 
-  /*element: D2.superGetterAccess:[exact=JSString]*/
+  /*member: D2.superGetterAccess:[exact=JSString]*/
   superGetterAccess() => super.getter;
 
-  /*element: D2.superGetterInvoke:[null|exact=JSString]*/
+  /*member: D2.superGetterInvoke:[null|exact=JSString]*/
   superGetterInvoke() => super.functionGetter();
 
-  /*element: D2.superFixedGetterInvoke:[null|subclass=JSInt]*/
+  /*member: D2.superFixedGetterInvoke:[null|subclass=JSInt]*/
   superFixedGetterInvoke() => super.fixedFunctionGetter();
 
-  /*element: D2.superGenericFieldInvoke1:[null|exact=JSString]*/
+  /*member: D2.superGenericFieldInvoke1:[null|exact=JSString]*/
   superGenericFieldInvoke1() => super.genericFunctionField('');
 
-  /*element: D2.superGenericFieldInvoke2:[null|subclass=JSInt]*/
+  /*member: D2.superGenericFieldInvoke2:[null|subclass=JSInt]*/
   superGenericFieldInvoke2() => super.genericFunctionField(0);
 
-  /*element: D2.superGenericMethodInvoke1:[exact=JSString]*/
+  /*member: D2.superGenericMethodInvoke1:[exact=JSString]*/
   superGenericMethodInvoke1() => super.genericMethod('');
 
-  /*element: D2.superGenericMethodInvoke2:[exact=JSUInt31]*/
+  /*member: D2.superGenericMethodInvoke2:[exact=JSUInt31]*/
   superGenericMethodInvoke2() => super.genericMethod(0);
 
-  /*element: D2.superGenericGetterInvoke1:[null|exact=JSString]*/
+  /*member: D2.superGenericGetterInvoke1:[null|exact=JSString]*/
   superGenericGetterInvoke1() => super.genericFunctionGetter('');
 
-  /*element: D2.superGenericGetterInvoke2:[null|subclass=JSInt]*/
+  /*member: D2.superGenericGetterInvoke2:[null|subclass=JSInt]*/
   superGenericGetterInvoke2() => super.genericFunctionGetter(0);
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   closureInvoke();
   localFunctionInvoke();
@@ -200,20 +200,20 @@
     .. /*invoke: [exact=D2]*/ superGenericGetterInvoke2();
 }
 
-/*element: closureInvoke:[null|subclass=JSInt]*/
+/*member: closureInvoke:[null|subclass=JSInt]*/
 closureInvoke() {
   int Function() f = /*[exact=JSUInt31]*/ () => 0;
   return f();
 }
 
-/*element: localFunctionInvoke:[exact=JSUInt31]*/
+/*member: localFunctionInvoke:[exact=JSUInt31]*/
 localFunctionInvoke() {
   /*[exact=JSUInt31]*/
   int local() => 0;
   return local();
 }
 
-/*element: genericLocalFunctionInvoke:[null]*/
+/*member: genericLocalFunctionInvoke:[null]*/
 genericLocalFunctionInvoke() {
   /*Union([exact=JSString], [exact=JSUInt31])*/
   S local<S>(S /*Union([exact=JSString], [exact=JSUInt31])*/ s) => s;
@@ -222,121 +222,121 @@
   local(''). /*invoke: [exact=JSString]*/ toString();
 }
 
-/*element: fieldAccess1:[exact=JSUInt31]*/
+/*member: fieldAccess1:[exact=JSUInt31]*/
 fieldAccess1() {
   C<int> c = new C<int>(0);
   return c. /*[exact=C]*/ field;
 }
 
-/*element: fieldAccess2:[exact=JSString]*/
+/*member: fieldAccess2:[exact=JSString]*/
 fieldAccess2() {
   C<String> c = new C<String>('');
   return c. /*[exact=C]*/ field;
 }
 
-/*element: fixedFieldInvoke:[null|subclass=JSInt]*/
+/*member: fixedFieldInvoke:[null|subclass=JSInt]*/
 fixedFieldInvoke() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ fixedFunctionField();
 }
 
-/*element: fieldInvoke1:[null|subclass=JSInt]*/
+/*member: fieldInvoke1:[null|subclass=JSInt]*/
 fieldInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ functionField();
 }
 
-/*element: fieldInvoke2:[null|exact=JSString]*/
+/*member: fieldInvoke2:[null|exact=JSString]*/
 fieldInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ functionField();
 }
 
-/*element: methodInvoke1:[exact=JSUInt31]*/
+/*member: methodInvoke1:[exact=JSUInt31]*/
 methodInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ method();
 }
 
-/*element: methodInvoke2:[exact=JSString]*/
+/*member: methodInvoke2:[exact=JSString]*/
 methodInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ method();
 }
 
-/*element: operatorInvoke1:[exact=JSUInt31]*/
+/*member: operatorInvoke1:[exact=JSUInt31]*/
 operatorInvoke1() {
   C<int> c = new C<int>(0);
   return c /*invoke: [exact=C]*/ + 0;
 }
 
-/*element: operatorInvoke2:[exact=JSString]*/
+/*member: operatorInvoke2:[exact=JSString]*/
 operatorInvoke2() {
   C<String> c = new C<String>('');
   return c /*invoke: [exact=C]*/ + '';
 }
 
-/*element: fixedGetterInvoke:[null|subclass=JSInt]*/
+/*member: fixedGetterInvoke:[null|subclass=JSInt]*/
 fixedGetterInvoke() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ fixedFunctionGetter();
 }
 
-/*element: getterAccess1:[exact=JSUInt31]*/
+/*member: getterAccess1:[exact=JSUInt31]*/
 getterAccess1() {
   C<int> c = new C<int>(0);
   return c. /*[exact=C]*/ getter;
 }
 
-/*element: getterAccess2:[exact=JSString]*/
+/*member: getterAccess2:[exact=JSString]*/
 getterAccess2() {
   C<String> c = new C<String>('');
   return c. /*[exact=C]*/ getter;
 }
 
-/*element: getterInvoke1:[null|subclass=JSInt]*/
+/*member: getterInvoke1:[null|subclass=JSInt]*/
 getterInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ functionGetter();
 }
 
-/*element: getterInvoke2:[null|exact=JSString]*/
+/*member: getterInvoke2:[null|exact=JSString]*/
 getterInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ functionGetter();
 }
 
-/*element: genericFieldInvoke1:[null|exact=JSString]*/
+/*member: genericFieldInvoke1:[null|exact=JSString]*/
 genericFieldInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ genericFunctionField('');
 }
 
-/*element: genericFieldInvoke2:[null|subclass=JSInt]*/
+/*member: genericFieldInvoke2:[null|subclass=JSInt]*/
 genericFieldInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ genericFunctionField(0);
 }
 
-/*element: genericMethodInvoke1:[exact=JSString]*/
+/*member: genericMethodInvoke1:[exact=JSString]*/
 genericMethodInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ genericMethod('');
 }
 
-/*element: genericMethodInvoke2:[exact=JSUInt31]*/
+/*member: genericMethodInvoke2:[exact=JSUInt31]*/
 genericMethodInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ genericMethod(0);
 }
 
-/*element: genericGetterInvoke1:[null|exact=JSString]*/
+/*member: genericGetterInvoke1:[null|exact=JSString]*/
 genericGetterInvoke1() {
   C<int> c = new C<int>(0);
   return c. /*invoke: [exact=C]*/ genericFunctionGetter('');
 }
 
-/*element: genericGetterInvoke2:[null|subclass=JSInt]*/
+/*member: genericGetterInvoke2:[null|subclass=JSInt]*/
 genericGetterInvoke2() {
   C<String> c = new C<String>('');
   return c. /*invoke: [exact=C]*/ genericFunctionGetter(0);
diff --git a/tests/compiler/dart2js/inference/data/super_get.dart b/tests/compiler/dart2js/inference/data/super_get.dart
index d1f15f2..680d080 100644
--- a/tests/compiler/dart2js/inference/data/super_get.dart
+++ b/tests/compiler/dart2js/inference/data/super_get.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   superFieldAccess();
   superGetterAccess();
@@ -13,19 +13,19 @@
 // Access of super field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
 class Super1 {
-  /*element: Super1.field:[exact=JSUInt31]*/
+  /*member: Super1.field:[exact=JSUInt31]*/
   var field = 42;
 }
 
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
 class Sub1 extends Super1 {
-  /*element: Sub1.method:[exact=JSUInt31]*/
+  /*member: Sub1.method:[exact=JSUInt31]*/
   method() => super.field;
 }
 
-/*element: superFieldAccess:[null]*/
+/*member: superFieldAccess:[null]*/
 superFieldAccess() {
   new Sub1(). /*invoke: [exact=Sub1]*/ method();
 }
@@ -34,19 +34,19 @@
 // Access of super getter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
 class Super2 {
-  /*element: Super2.getter:[exact=JSUInt31]*/
+  /*member: Super2.getter:[exact=JSUInt31]*/
   get getter => 42;
 }
 
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
 class Sub2 extends Super2 {
-  /*element: Sub2.method:[exact=JSUInt31]*/
+  /*member: Sub2.method:[exact=JSUInt31]*/
   method() => super.getter;
 }
 
-/*element: superGetterAccess:[null]*/
+/*member: superGetterAccess:[null]*/
 superGetterAccess() {
   new Sub2(). /*invoke: [exact=Sub2]*/ method();
 }
@@ -55,19 +55,19 @@
 // Access of super method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super3.:[exact=Super3]*/
+/*member: Super3.:[exact=Super3]*/
 class Super3 {
-  /*element: Super3.superMethod:[null]*/
+  /*member: Super3.superMethod:[null]*/
   superMethod() {}
 }
 
-/*element: Sub3.:[exact=Sub3]*/
+/*member: Sub3.:[exact=Sub3]*/
 class Sub3 extends Super3 {
-  /*element: Sub3.method:[subclass=Closure]*/
+  /*member: Sub3.method:[subclass=Closure]*/
   method() => super.superMethod;
 }
 
-/*element: superMethodAccess:[null]*/
+/*member: superMethodAccess:[null]*/
 superMethodAccess() {
   new Sub3(). /*invoke: [exact=Sub3]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/super_invoke.dart b/tests/compiler/dart2js/inference/data/super_invoke.dart
index 4d8c081..8392f1d 100644
--- a/tests/compiler/dart2js/inference/data/super_invoke.dart
+++ b/tests/compiler/dart2js/inference/data/super_invoke.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   superMethodInvoke();
   superFieldInvoke();
@@ -14,22 +14,22 @@
 // Invocation of super method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
 class Super1 {
-  /*element: Super1.method:[exact=JSUInt31]*/
+  /*member: Super1.method:[exact=JSUInt31]*/
   method() => 42;
 }
 
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
 class Sub1 extends Super1 {
-  /*element: Sub1.method:[subclass=JSPositiveInt]*/
+  /*member: Sub1.method:[subclass=JSPositiveInt]*/
   method() {
     var a = super.method();
     return a. /*invoke: [exact=JSUInt31]*/ abs();
   }
 }
 
-/*element: superMethodInvoke:[null]*/
+/*member: superMethodInvoke:[null]*/
 superMethodInvoke() {
   new Sub1(). /*invoke: [exact=Sub1]*/ method();
 }
@@ -38,24 +38,24 @@
 // Invocation of super field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[exact=JSUInt31]*/
+/*member: _method1:[exact=JSUInt31]*/
 _method1() => 42;
 
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
 class Super2 {
-  /*element: Super2.field:[subclass=Closure]*/
+  /*member: Super2.field:[subclass=Closure]*/
   var field = _method1;
 }
 
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
 class Sub2 extends Super2 {
-  /*element: Sub2.method:[null|subclass=Object]*/
+  /*member: Sub2.method:[null|subclass=Object]*/
   method() {
     return super.field();
   }
 }
 
-/*element: superFieldInvoke:[null]*/
+/*member: superFieldInvoke:[null]*/
 superFieldInvoke() {
   new Sub2(). /*invoke: [exact=Sub2]*/ method();
 }
@@ -64,24 +64,24 @@
 // Invocation of super getter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method2:[exact=JSUInt31]*/
+/*member: _method2:[exact=JSUInt31]*/
 _method2() => 42;
 
-/*element: Super3.:[exact=Super3]*/
+/*member: Super3.:[exact=Super3]*/
 class Super3 {
-  /*element: Super3.getter:[subclass=Closure]*/
+  /*member: Super3.getter:[subclass=Closure]*/
   get getter => _method2;
 }
 
-/*element: Sub3.:[exact=Sub3]*/
+/*member: Sub3.:[exact=Sub3]*/
 class Sub3 extends Super3 {
-  /*element: Sub3.method:[null|subclass=Object]*/
+  /*member: Sub3.method:[null|subclass=Object]*/
   method() {
     return super.getter();
   }
 }
 
-/*element: superGetterInvoke:[null]*/
+/*member: superGetterInvoke:[null]*/
 superGetterInvoke() {
   new Sub3(). /*invoke: [exact=Sub3]*/ method();
 }
@@ -90,24 +90,24 @@
 // Invocation of abstract super method that overrides a concrete method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: SuperSuper10.:[exact=SuperSuper10]*/
+/*member: SuperSuper10.:[exact=SuperSuper10]*/
 class SuperSuper10 {
-  /*element: SuperSuper10.method:[exact=JSUInt31]*/
+  /*member: SuperSuper10.method:[exact=JSUInt31]*/
   method() => 42;
 }
 
-/*element: Super10.:[exact=Super10]*/
+/*member: Super10.:[exact=Super10]*/
 class Super10 extends SuperSuper10 {
   method();
 }
 
-/*element: Sub10.:[exact=Sub10]*/
+/*member: Sub10.:[exact=Sub10]*/
 class Sub10 extends Super10 {
-  /*element: Sub10.method:[exact=JSUInt31]*/
+  /*member: Sub10.method:[exact=JSUInt31]*/
   method() => super.method();
 }
 
-/*element: overridingAbstractSuperMethodInvoke:[null]*/
+/*member: overridingAbstractSuperMethodInvoke:[null]*/
 overridingAbstractSuperMethodInvoke() {
   new Sub10(). /*invoke: [exact=Sub10]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/super_set.dart b/tests/compiler/dart2js/inference/data/super_set.dart
index e4f5314..1365c01 100644
--- a/tests/compiler/dart2js/inference/data/super_set.dart
+++ b/tests/compiler/dart2js/inference/data/super_set.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   superFieldUpdate();
   superSetterUpdate();
@@ -12,22 +12,22 @@
 // Update of super field.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super1.:[exact=Super1]*/
+/*member: Super1.:[exact=Super1]*/
 class Super1 {
-  /*element: Super1.field:Union([exact=JSUInt31], [exact=Sub1])*/
+  /*member: Super1.field:Union([exact=JSUInt31], [exact=Sub1])*/
   dynamic field = 42;
 }
 
-/*element: Sub1.:[exact=Sub1]*/
+/*member: Sub1.:[exact=Sub1]*/
 class Sub1 extends Super1 {
-  /*element: Sub1.method:[subclass=Closure]*/
+  /*member: Sub1.method:[subclass=Closure]*/
   method() {
     var a = super.field = new Sub1();
     return a. /*[exact=Sub1]*/ method;
   }
 }
 
-/*element: superFieldUpdate:[null]*/
+/*member: superFieldUpdate:[null]*/
 superFieldUpdate() {
   new Sub1(). /*invoke: [exact=Sub1]*/ method();
 }
@@ -36,21 +36,21 @@
 // Update of super setter.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Super2.:[exact=Super2]*/
+/*member: Super2.:[exact=Super2]*/
 class Super2 {
   set setter(/*[exact=Sub2]*/ value) {}
 }
 
-/*element: Sub2.:[exact=Sub2]*/
+/*member: Sub2.:[exact=Sub2]*/
 class Sub2 extends Super2 {
-  /*element: Sub2.method:[subclass=Closure]*/
+  /*member: Sub2.method:[subclass=Closure]*/
   method() {
     var a = super.setter = new Sub2();
     return a. /*[exact=Sub2]*/ method;
   }
 }
 
-/*element: superSetterUpdate:[null]*/
+/*member: superSetterUpdate:[null]*/
 superSetterUpdate() {
   new Sub2(). /*invoke: [exact=Sub2]*/ method();
 }
diff --git a/tests/compiler/dart2js/inference/data/switch.dart b/tests/compiler/dart2js/inference/data/switch.dart
index c5a44ad..c7e9cb4 100644
--- a/tests/compiler/dart2js/inference/data/switch.dart
+++ b/tests/compiler/dart2js/inference/data/switch.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   switchWithoutDefault();
   switchWithDefault();
@@ -15,7 +15,7 @@
 // Switch statement without default case.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _switchWithoutDefault:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: _switchWithoutDefault:Union([exact=JSUInt31], [null|exact=JSString])*/
 _switchWithoutDefault(/*[exact=JSUInt31]*/ o) {
   var local;
   switch (o) {
@@ -29,7 +29,7 @@
   return local;
 }
 
-/*element: switchWithoutDefault:[null]*/
+/*member: switchWithoutDefault:[null]*/
 switchWithoutDefault() {
   _switchWithoutDefault(0);
   _switchWithoutDefault(1);
@@ -39,7 +39,7 @@
 // Switch statement with default case.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _switchWithDefault:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithDefault:Union([exact=JSString], [exact=JSUInt31])*/
 _switchWithDefault(/*[exact=JSUInt31]*/ o) {
   var local;
   switch (o) {
@@ -54,7 +54,7 @@
   return local;
 }
 
-/*element: switchWithDefault:[null]*/
+/*member: switchWithDefault:[null]*/
 switchWithDefault() {
   _switchWithDefault(0);
   _switchWithDefault(1);
@@ -64,7 +64,7 @@
 // Switch statement with default case without break.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _switchWithDefaultWithoutBreak:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithDefaultWithoutBreak:Union([exact=JSString], [exact=JSUInt31])*/
 _switchWithDefaultWithoutBreak(/*[exact=JSUInt31]*/ o) {
   var local;
   switch (o) {
@@ -78,7 +78,7 @@
   return local;
 }
 
-/*element: switchWithDefaultWithoutBreak:[null]*/
+/*member: switchWithDefaultWithoutBreak:[null]*/
 switchWithDefaultWithoutBreak() {
   _switchWithDefaultWithoutBreak(0);
   _switchWithDefaultWithoutBreak(1);
@@ -88,7 +88,7 @@
 // Switch statement with continue.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _switchWithContinue:Union([exact=JSBool], [exact=JSString], [null|exact=JSUInt31])*/
+/*member: _switchWithContinue:Union([exact=JSBool], [exact=JSString], [null|exact=JSUInt31])*/
 _switchWithContinue(/*[exact=JSUInt31]*/ o) {
   dynamic local;
   switch (o) {
@@ -107,7 +107,7 @@
   return local;
 }
 
-/*element: switchWithContinue:[null]*/
+/*member: switchWithContinue:[null]*/
 switchWithContinue() {
   _switchWithContinue(0);
   _switchWithContinue(1);
@@ -118,7 +118,7 @@
 // the continue statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _switchWithoutContinue:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: _switchWithoutContinue:Union([exact=JSString], [exact=JSUInt31])*/
 _switchWithoutContinue(/*[exact=JSUInt31]*/ o) {
   dynamic local;
   switch (o) {
@@ -135,7 +135,7 @@
   return local;
 }
 
-/*element: switchWithoutContinue:[null]*/
+/*member: switchWithoutContinue:[null]*/
 switchWithoutContinue() {
   _switchWithoutContinue(0);
   _switchWithoutContinue(1);
diff --git a/tests/compiler/dart2js/inference/data/switch1.dart b/tests/compiler/dart2js/inference/data/switch1.dart
index 036ccba..a9f9e32 100644
--- a/tests/compiler/dart2js/inference/data/switch1.dart
+++ b/tests/compiler/dart2js/inference/data/switch1.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:[exact=JSString]*/
+/*member: foo:[exact=JSString]*/
 foo(int /*[subclass=JSInt]*/ x) {
   var a = "one";
   switch (x) {
@@ -16,6 +16,6 @@
   return a;
 }
 
-/*element: main:[null]*/ main() {
+/*member: main:[null]*/ main() {
   foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
 }
diff --git a/tests/compiler/dart2js/inference/data/switch2.dart b/tests/compiler/dart2js/inference/data/switch2.dart
index ed9a38e..c2aaa71 100644
--- a/tests/compiler/dart2js/inference/data/switch2.dart
+++ b/tests/compiler/dart2js/inference/data/switch2.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:Value([null|exact=JSString], value: "two")*/
+/*member: foo:Value([null|exact=JSString], value: "two")*/
 foo(int /*[subclass=JSInt]*/ x) {
   var a;
   switch (x) {
@@ -16,7 +16,7 @@
   return a;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
 }
diff --git a/tests/compiler/dart2js/inference/data/switch5.dart b/tests/compiler/dart2js/inference/data/switch5.dart
index 1ce09a6..3263b55 100644
--- a/tests/compiler/dart2js/inference/data/switch5.dart
+++ b/tests/compiler/dart2js/inference/data/switch5.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:[null|exact=JSUInt31]*/
+/*member: foo:[null|exact=JSUInt31]*/
 foo(int /*[subclass=JSInt]*/ x) {
   var a;
   switch (x) {
@@ -18,7 +18,7 @@
   return a;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
 }
diff --git a/tests/compiler/dart2js/inference/data/switch6.dart b/tests/compiler/dart2js/inference/data/switch6.dart
index 8761199..2155d6f 100644
--- a/tests/compiler/dart2js/inference/data/switch6.dart
+++ b/tests/compiler/dart2js/inference/data/switch6.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: foo:[null|exact=JSUInt31]*/
+/*member: foo:[null|exact=JSUInt31]*/
 foo(int /*[subclass=JSInt]*/ x) {
   var a;
   do {
@@ -20,7 +20,7 @@
   return a;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   foo(new DateTime.now(). /*[exact=DateTime]*/ millisecondsSinceEpoch);
 }
diff --git a/tests/compiler/dart2js/inference/data/throw.dart b/tests/compiler/dart2js/inference/data/throw.dart
index 679147c..e844463 100644
--- a/tests/compiler/dart2js/inference/data/throw.dart
+++ b/tests/compiler/dart2js/inference/data/throw.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   unconditionalThrow();
   conditionalThrow();
@@ -14,19 +14,19 @@
 /// Method that throws unconditionally.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: unconditionalThrow:[empty]*/
+/*member: unconditionalThrow:[empty]*/
 unconditionalThrow() => throw 'foo';
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Method that throws conditionally.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _conditionalThrow:[null]*/
+/*member: _conditionalThrow:[null]*/
 _conditionalThrow(/*[exact=JSBool]*/ o) {
   if (o) throw 'foo';
 }
 
-/*element: conditionalThrow:[null]*/
+/*member: conditionalThrow:[null]*/
 conditionalThrow() {
   _conditionalThrow(true);
   _conditionalThrow(false);
@@ -36,13 +36,13 @@
 /// Method that throws conditionally and return 0.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _conditionalThrowReturn:[exact=JSUInt31]*/
+/*member: _conditionalThrowReturn:[exact=JSUInt31]*/
 _conditionalThrowReturn(/*[exact=JSBool]*/ o) {
   if (o) throw 'foo';
   return 0;
 }
 
-/*element: conditionalThrowReturn:[null]*/
+/*member: conditionalThrowReturn:[null]*/
 conditionalThrowReturn() {
   _conditionalThrowReturn(true);
   _conditionalThrowReturn(false);
@@ -52,7 +52,7 @@
 /// Method that rethrows unconditionally.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: unconditionalRethrow:[null]*/
+/*member: unconditionalRethrow:[null]*/
 unconditionalRethrow() {
   try {
     throw 'foo';
diff --git a/tests/compiler/dart2js/inference/data/try.dart b/tests/compiler/dart2js/inference/data/try.dart
index 340c852..ac0416f 100644
--- a/tests/compiler/dart2js/inference/data/try.dart
+++ b/tests/compiler/dart2js/inference/data/try.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   emptyTryCatch();
   emptyTryFinally();
@@ -25,13 +25,13 @@
 /// Parameter passed through an empty try-catch statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _emptyTryCatch:[exact=JSUInt31]*/
+/*member: _emptyTryCatch:[exact=JSUInt31]*/
 _emptyTryCatch(/*[exact=JSUInt31]*/ o) {
   try {} catch (e) {}
   return o;
 }
 
-/*element: emptyTryCatch:[null]*/
+/*member: emptyTryCatch:[null]*/
 emptyTryCatch() {
   _emptyTryCatch(0);
 }
@@ -40,13 +40,13 @@
 /// Parameter passed through an empty try-finally statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _emptyTryFinally:[exact=JSUInt31]*/
+/*member: _emptyTryFinally:[exact=JSUInt31]*/
 _emptyTryFinally(/*[exact=JSUInt31]*/ o) {
   try {} finally {}
   return o;
 }
 
-/*element: emptyTryFinally:[null]*/
+/*member: emptyTryFinally:[null]*/
 emptyTryFinally() {
   _emptyTryFinally(0);
 }
@@ -55,13 +55,13 @@
 /// Parameter passed through an empty try-catch-finally statement.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _emptyTryCatchFinally:[exact=JSUInt31]*/
+/*member: _emptyTryCatchFinally:[exact=JSUInt31]*/
 _emptyTryCatchFinally(/*[exact=JSUInt31]*/ o) {
   try {} catch (e) {} finally {}
   return o;
 }
 
-/*element: emptyTryCatchFinally:[null]*/
+/*member: emptyTryCatchFinally:[null]*/
 emptyTryCatchFinally() {
   _emptyTryCatchFinally(0);
 }
@@ -70,7 +70,7 @@
 /// A try-catch statement with an assignment in the try block.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: tryCatchAssignmentInTry:[null|exact=JSUInt31]*/
+/*member: tryCatchAssignmentInTry:[null|exact=JSUInt31]*/
 tryCatchAssignmentInTry() {
   var o = 0;
   try {
@@ -83,7 +83,7 @@
 /// A try-catch statement with an assignment in the catch block.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: tryCatchAssignmentInCatch:[null|exact=JSUInt31]*/
+/*member: tryCatchAssignmentInCatch:[null|exact=JSUInt31]*/
 tryCatchAssignmentInCatch() {
   var o = 0;
   try {} catch (e) {
@@ -96,7 +96,7 @@
 /// A try-finally statement with an assignment in the finally clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: tryFinallyAssignmentInFinally:[null]*/
+/*member: tryFinallyAssignmentInFinally:[null]*/
 tryFinallyAssignmentInFinally() {
   var o = 0;
   try {} finally {
@@ -110,7 +110,7 @@
 /// block.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: tryCatchAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: tryCatchAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
 tryCatchAssignmentInTryCatch() {
   dynamic o = 0;
   try {
@@ -126,7 +126,7 @@
 /// finally block.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: tryCatchAssignmentInTryFinally:[null]*/
+/*member: tryCatchAssignmentInTryFinally:[null]*/
 tryCatchAssignmentInTryFinally() {
   dynamic o = 0;
   try {
@@ -142,7 +142,7 @@
 /// catch clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryCatchParameterAssignmentInTry:[null|exact=JSUInt31]*/
+/*member: _tryCatchParameterAssignmentInTry:[null|exact=JSUInt31]*/
 _tryCatchParameterAssignmentInTry(/*[exact=JSUInt31]*/ o) {
   try {
     o = null;
@@ -150,7 +150,7 @@
   return o;
 }
 
-/*element: tryCatchParameterAssignmentInTry:[null]*/
+/*member: tryCatchParameterAssignmentInTry:[null]*/
 tryCatchParameterAssignmentInTry() {
   _tryCatchParameterAssignmentInTry(0);
 }
@@ -160,7 +160,7 @@
 /// catch clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryCatchParameterAssignmentInCatch:[null|exact=JSUInt31]*/
+/*member: _tryCatchParameterAssignmentInCatch:[null|exact=JSUInt31]*/
 _tryCatchParameterAssignmentInCatch(/*[exact=JSUInt31]*/ o) {
   try {} catch (e) {
     o = null;
@@ -168,7 +168,7 @@
   return o;
 }
 
-/*element: tryCatchParameterAssignmentInCatch:[null]*/
+/*member: tryCatchParameterAssignmentInCatch:[null]*/
 tryCatchParameterAssignmentInCatch() {
   _tryCatchParameterAssignmentInCatch(0);
 }
@@ -178,7 +178,7 @@
 /// finally clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryFinallyParameterAssignmentInFinally:[null]*/
+/*member: _tryFinallyParameterAssignmentInFinally:[null]*/
 _tryFinallyParameterAssignmentInFinally(/*[exact=JSUInt31]*/ o) {
   try {} finally {
     o = null;
@@ -186,7 +186,7 @@
   return o;
 }
 
-/*element: tryFinallyParameterAssignmentInFinally:[null]*/
+/*member: tryFinallyParameterAssignmentInFinally:[null]*/
 tryFinallyParameterAssignmentInFinally() {
   _tryFinallyParameterAssignmentInFinally(0);
 }
@@ -196,7 +196,7 @@
 /// catch clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryCatchParameterAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
+/*member: _tryCatchParameterAssignmentInTryCatch:Union([exact=JSUInt31], [null|exact=JSString])*/
 _tryCatchParameterAssignmentInTryCatch(/*[exact=JSUInt31]*/ o) {
   try {
     o = '';
@@ -206,7 +206,7 @@
   return o;
 }
 
-/*element: tryCatchParameterAssignmentInTryCatch:[null]*/
+/*member: tryCatchParameterAssignmentInTryCatch:[null]*/
 tryCatchParameterAssignmentInTryCatch() {
   _tryCatchParameterAssignmentInTryCatch(0);
 }
@@ -216,7 +216,7 @@
 /// finally clause.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryFinallyParameterAssignmentInTryFinally:[null]*/
+/*member: _tryFinallyParameterAssignmentInTryFinally:[null]*/
 _tryFinallyParameterAssignmentInTryFinally(/*[exact=JSUInt31]*/ o) {
   try {
     o = '';
@@ -226,7 +226,7 @@
   return o;
 }
 
-/*element: tryFinallyParameterAssignmentInTryFinally:[null]*/
+/*member: tryFinallyParameterAssignmentInTryFinally:[null]*/
 tryFinallyParameterAssignmentInTryFinally() {
   _tryFinallyParameterAssignmentInTryFinally(0);
 }
diff --git a/tests/compiler/dart2js/inference/data/try_catch.dart b/tests/compiler/dart2js/inference/data/try_catch.dart
index b4209bb..9dfe310 100644
--- a/tests/compiler/dart2js/inference/data/try_catch.dart
+++ b/tests/compiler/dart2js/inference/data/try_catch.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: returnInt1:[exact=JSUInt31]*/
+/*member: returnInt1:[exact=JSUInt31]*/
 returnInt1() {
   var a = 42;
   try {
@@ -11,7 +11,7 @@
   return a;
 }
 
-/*element: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn1() {
   dynamic a = 42;
   try {
@@ -20,7 +20,7 @@
   return a;
 }
 
-/*element: returnInt2:[exact=JSUInt31]*/
+/*member: returnInt2:[exact=JSUInt31]*/
 returnInt2() {
   var a = 42;
   try {
@@ -31,7 +31,7 @@
   return a;
 }
 
-/*element: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn2() {
   dynamic a = 42;
   try {
@@ -42,7 +42,7 @@
   return a;
 }
 
-/*element: returnInt3:[exact=JSUInt31]*/
+/*member: returnInt3:[exact=JSUInt31]*/
 returnInt3() {
   dynamic a = 42;
   try {
@@ -55,7 +55,7 @@
   return a;
 }
 
-/*element: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn3() {
   dynamic a = 42;
   try {
@@ -70,7 +70,7 @@
   return a;
 }
 
-/*element: returnInt4:[exact=JSUInt31]*/
+/*member: returnInt4:[exact=JSUInt31]*/
 returnInt4() {
   var a = 42;
   try {
@@ -85,7 +85,7 @@
   return a;
 }
 
-/*element: returnDyn4:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn4:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn4() {
   dynamic a = 42;
   if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -96,7 +96,7 @@
   return a;
 }
 
-/*element: returnInt5:[exact=JSUInt31]*/
+/*member: returnInt5:[exact=JSUInt31]*/
 returnInt5() {
   var a = 42;
   if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -107,7 +107,7 @@
   return a;
 }
 
-/*element: returnDyn5:Union([exact=JSString], [exact=JSUInt31])*/
+/*member: returnDyn5:Union([exact=JSString], [exact=JSUInt31])*/
 returnDyn5() {
   dynamic a = 42;
   if (a /*invoke: [exact=JSUInt31]*/ == 54) {
@@ -120,7 +120,7 @@
   return a;
 }
 
-/*element: returnInt6:[subclass=JSInt]*/
+/*member: returnInt6:[subclass=JSInt]*/
 returnInt6() {
   try {
     throw 42;
@@ -131,7 +131,7 @@
   return 42;
 }
 
-/*element: returnDyn6:[null|subclass=Object]*/
+/*member: returnDyn6:[null|subclass=Object]*/
 returnDyn6() {
   try {
     throw 42;
@@ -140,7 +140,7 @@
   }
 }
 
-/*element: returnInt7:[exact=JSUInt31]*/
+/*member: returnInt7:[exact=JSUInt31]*/
 returnInt7() {
   dynamic a = 'foo';
   try {
@@ -150,7 +150,7 @@
   return 2;
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   returnInt1();
   returnDyn1();
diff --git a/tests/compiler/dart2js/inference/data/type_literal.dart b/tests/compiler/dart2js/inference/data/type_literal.dart
index 46644d9..63ab341 100644
--- a/tests/compiler/dart2js/inference/data/type_literal.dart
+++ b/tests/compiler/dart2js/inference/data/type_literal.dart
@@ -2,20 +2,20 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   typeLiteral();
   typeLiteralToString();
   typeLiteralSubstring();
 }
 
-/*element: typeLiteral:[exact=TypeImpl]*/
+/*member: typeLiteral:[exact=TypeImpl]*/
 typeLiteral() => Object;
 
-/*element: typeLiteralToString:[exact=JSString]*/
+/*member: typeLiteralToString:[exact=JSString]*/
 typeLiteralToString() => (Object). /*invoke: [exact=TypeImpl]*/ toString();
 
-/*element: typeLiteralSubstring:[exact=JSString]*/
+/*member: typeLiteralSubstring:[exact=JSString]*/
 typeLiteralSubstring() {
   String name = (List). /*invoke: [exact=TypeImpl]*/ toString();
   name = name. /*invoke: [exact=JSString]*/ substring(
diff --git a/tests/compiler/dart2js/inference/data/unregister_call.dart b/tests/compiler/dart2js/inference/data/unregister_call.dart
index cfe5be7..b07989b 100644
--- a/tests/compiler/dart2js/inference/data/unregister_call.dart
+++ b/tests/compiler/dart2js/inference/data/unregister_call.dart
@@ -2,16 +2,16 @@
 // 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.
 
-/*element: a:Value([exact=JSString], value: "")*/
+/*member: a:Value([exact=JSString], value: "")*/
 var a = '';
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {
-  /*element: A.+:[exact=JSUInt31]*/
+  /*member: A.+:[exact=JSUInt31]*/
   operator +(/*[exact=JSUInt31]*/ other) => other;
 }
 
-/*element: foo:[exact=JSString]*/
+/*member: foo:[exact=JSString]*/
 foo() {
   // The following '+' call will first say that it may call A::+,
   // String::+, or int::+. After all methods have been analyzed, we know
@@ -21,7 +21,7 @@
   return a /*invoke: Value([exact=JSString], value: "")*/ + 'foo';
 }
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   new A() /*invoke: [exact=A]*/ + 42;
   foo();
diff --git a/tests/compiler/dart2js/inference/data/use_static_types.dart b/tests/compiler/dart2js/inference/data/use_static_types.dart
index 1d59e90..f701b6d 100644
--- a/tests/compiler/dart2js/inference/data/use_static_types.dart
+++ b/tests/compiler/dart2js/inference/data/use_static_types.dart
@@ -2,77 +2,77 @@
 // 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.
 
-/*element: A.:[exact=A]*/
+/*member: A.:[exact=A]*/
 class A {}
 
-/*element: B.:[exact=B]*/
+/*member: B.:[exact=B]*/
 class B extends A {}
 
-/*element: C.:[exact=C]*/
+/*member: C.:[exact=C]*/
 class C {}
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   invokeFunctions();
   invokeGenericClasses();
   invokeGenericMethods();
 }
 
-/*element: invokeFunction1:[null|subclass=A]*/
+/*member: invokeFunction1:[null|subclass=A]*/
 invokeFunction1(A Function() /*[subclass=Closure]*/ f) {
   return f();
 }
 
-/*element: invokeFunction2:[null|exact=B]*/
+/*member: invokeFunction2:[null|exact=B]*/
 invokeFunction2(B Function() /*[subclass=Closure]*/ f) {
   return f();
 }
 
-/*element: invokeFunction3:[null|exact=C]*/
+/*member: invokeFunction3:[null|exact=C]*/
 invokeFunction3(C Function() /*[subclass=Closure]*/ f) {
   return f();
 }
 
-/*element: genericFunction:[null|subclass=Object]*/
+/*member: genericFunction:[null|subclass=Object]*/
 T genericFunction<T>(T Function() /*[subclass=Closure]*/ f) => f();
 
-/*element: invokeGenericFunction1:[null|subclass=A]*/
+/*member: invokeGenericFunction1:[null|subclass=A]*/
 invokeGenericFunction1() {
   return genericFunction<A>(/*[exact=A]*/ () => new A());
 }
 
-/*element: invokeGenericFunction2:[null|exact=B]*/
+/*member: invokeGenericFunction2:[null|exact=B]*/
 invokeGenericFunction2() {
   return genericFunction<B>(/*[exact=B]*/ () => new B());
 }
 
-/*element: invokeGenericFunction3:[null|exact=C]*/
+/*member: invokeGenericFunction3:[null|exact=C]*/
 invokeGenericFunction3() {
   return genericFunction<C>(/*[exact=C]*/ () => new C());
 }
 
-/*element: invokeGenericLocalFunction1:[null|subclass=A]*/
+/*member: invokeGenericLocalFunction1:[null|subclass=A]*/
 invokeGenericLocalFunction1() {
   /*[null|subclass=Object]*/
   T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
   return local<A>(/*[exact=A]*/ () => new A());
 }
 
-/*element: invokeGenericLocalFunction2:[null|exact=B]*/
+/*member: invokeGenericLocalFunction2:[null|exact=B]*/
 invokeGenericLocalFunction2() {
   /*[null|subclass=Object]*/
   T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
   return local<B>(/*[exact=B]*/ () => new B());
 }
 
-/*element: invokeGenericLocalFunction3:[null|exact=C]*/
+/*member: invokeGenericLocalFunction3:[null|exact=C]*/
 invokeGenericLocalFunction3() {
   /*[null|subclass=Object]*/
   T local<T>(T Function() /*[subclass=Closure]*/ f) => f();
   return local<C>(/*[exact=C]*/ () => new C());
 }
 
-/*element: invokeFunctions:[null]*/
+/*member: invokeFunctions:[null]*/
 invokeFunctions() {
   invokeFunction1(/*[exact=A]*/ () => new A());
   invokeFunction2(/*[exact=B]*/ () => new B());
@@ -86,214 +86,214 @@
 }
 
 class GenericClass<T> {
-  /*element: GenericClass.field:Union([exact=C], [subclass=A])*/
+  /*member: GenericClass.field:Union([exact=C], [subclass=A])*/
   final T field;
 
-  /*element: GenericClass.functionTypedField:[subclass=Closure]*/
+  /*member: GenericClass.functionTypedField:[subclass=Closure]*/
   final T Function() functionTypedField;
 
-  /*element: GenericClass.:[exact=GenericClass]*/
+  /*member: GenericClass.:[exact=GenericClass]*/
   GenericClass(this. /*Union([exact=C], [subclass=A])*/ field)
       : functionTypedField = (/*Union([exact=C], [subclass=A])*/ () => field);
 
-  /*element: GenericClass.getter:Union([exact=C], [subclass=A])*/
+  /*member: GenericClass.getter:Union([exact=C], [subclass=A])*/
   T get getter => /*[subclass=GenericClass]*/ field;
 
-  /*element: GenericClass.functionTypedGetter:[subclass=Closure]*/
+  /*member: GenericClass.functionTypedGetter:[subclass=Closure]*/
   T Function()
       get functionTypedGetter => /*[subclass=GenericClass]*/ functionTypedField;
 
-  /*element: GenericClass.method:Union([exact=C], [subclass=A])*/
+  /*member: GenericClass.method:Union([exact=C], [subclass=A])*/
   T method() => /*[subclass=GenericClass]*/ field;
 
-  /*element: GenericClass.functionTypedMethod:[subclass=Closure]*/
+  /*member: GenericClass.functionTypedMethod:[subclass=Closure]*/
   T Function()
       functionTypedMethod() => /*[subclass=GenericClass]*/ functionTypedField;
 }
 
 class GenericSubclass<T> extends GenericClass<T> {
-  /*element: GenericSubclass.:[exact=GenericSubclass]*/
+  /*member: GenericSubclass.:[exact=GenericSubclass]*/
   GenericSubclass(T /*Union([exact=C], [subclass=A])*/ field) : super(field);
 
-  /*element: GenericSubclass.superField:Union([exact=C], [subclass=A])*/
+  /*member: GenericSubclass.superField:Union([exact=C], [subclass=A])*/
   superField() => super.field;
 
-  /*element: GenericSubclass.superGetter:Union([exact=C], [subclass=A])*/
+  /*member: GenericSubclass.superGetter:Union([exact=C], [subclass=A])*/
   superGetter() => super.getter;
 
-  /*element: GenericSubclass.superMethod:Union([exact=C], [subclass=A])*/
+  /*member: GenericSubclass.superMethod:Union([exact=C], [subclass=A])*/
   superMethod() => super.method();
 
-  /*element: GenericSubclass.superFieldInvoke:[null|subclass=Object]*/
+  /*member: GenericSubclass.superFieldInvoke:[null|subclass=Object]*/
   superFieldInvoke() => super.functionTypedField();
 
-  /*element: GenericSubclass.superGetterInvoke:[null|subclass=Object]*/
+  /*member: GenericSubclass.superGetterInvoke:[null|subclass=Object]*/
   superGetterInvoke() => super.functionTypedGetter();
 
-  /*element: GenericSubclass.superMethodInvoke:[null|subclass=Object]*/
+  /*member: GenericSubclass.superMethodInvoke:[null|subclass=Object]*/
   superMethodInvoke() => super.functionTypedMethod()();
 }
 
-/*element: invokeInstanceMethod1:[subclass=A]*/
+/*member: invokeInstanceMethod1:[subclass=A]*/
 invokeInstanceMethod1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ method();
 
-/*element: invokeInstanceMethod2:[exact=B]*/
+/*member: invokeInstanceMethod2:[exact=B]*/
 invokeInstanceMethod2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ method();
 
-/*element: invokeInstanceMethod3:[exact=C]*/
+/*member: invokeInstanceMethod3:[exact=C]*/
 invokeInstanceMethod3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ method();
 
-/*element: invokeInstanceGetter1:[subclass=A]*/
+/*member: invokeInstanceGetter1:[subclass=A]*/
 invokeInstanceGetter1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ getter;
 
-/*element: invokeInstanceGetter2:[exact=B]*/
+/*member: invokeInstanceGetter2:[exact=B]*/
 invokeInstanceGetter2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ getter;
 
-/*element: invokeInstanceGetter3:[exact=C]*/
+/*member: invokeInstanceGetter3:[exact=C]*/
 invokeInstanceGetter3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ getter;
 
-/*element: accessInstanceField1:[subclass=A]*/
+/*member: accessInstanceField1:[subclass=A]*/
 accessInstanceField1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ field;
 
-/*element: accessInstanceField2:[exact=B]*/
+/*member: accessInstanceField2:[exact=B]*/
 accessInstanceField2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ field;
 
-/*element: accessInstanceField3:[exact=C]*/
+/*member: accessInstanceField3:[exact=C]*/
 accessInstanceField3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*[exact=GenericClass]*/ field;
 
-/*element: invokeSuperMethod1:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod1:Union([exact=C], [subclass=A])*/
 invokeSuperMethod1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethod();
 
-/*element: invokeSuperMethod2:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod2:Union([exact=C], [subclass=A])*/
 invokeSuperMethod2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethod();
 
-/*element: invokeSuperMethod3:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperMethod3:Union([exact=C], [subclass=A])*/
 invokeSuperMethod3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethod();
 
-/*element: invokeSuperGetter1:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter1:Union([exact=C], [subclass=A])*/
 invokeSuperGetter1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetter();
 
-/*element: invokeSuperGetter2:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter2:Union([exact=C], [subclass=A])*/
 invokeSuperGetter2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetter();
 
-/*element: invokeSuperGetter3:Union([exact=C], [subclass=A])*/
+/*member: invokeSuperGetter3:Union([exact=C], [subclass=A])*/
 invokeSuperGetter3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetter();
 
-/*element: accessSuperField1:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField1:Union([exact=C], [subclass=A])*/
 accessSuperField1(GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superField();
 
-/*element: accessSuperField2:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField2:Union([exact=C], [subclass=A])*/
 accessSuperField2(GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superField();
 
-/*element: accessSuperField3:Union([exact=C], [subclass=A])*/
+/*member: accessSuperField3:Union([exact=C], [subclass=A])*/
 accessSuperField3(GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superField();
 
-/*element: invokeFunctionTypedInstanceMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceMethod1:[null|subclass=A]*/
 invokeFunctionTypedInstanceMethod1(
         GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
 
-/*element: invokeFunctionTypedInstanceMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceMethod2:[null|exact=B]*/
 invokeFunctionTypedInstanceMethod2(
         GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
 
-/*element: invokeFunctionTypedInstanceMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceMethod3:[null|exact=C]*/
 invokeFunctionTypedInstanceMethod3(
         GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedMethod()();
 
-/*element: invokeFunctionTypedInstanceGetter1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceGetter1:[null|subclass=A]*/
 invokeFunctionTypedInstanceGetter1(
         GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
 
-/*element: invokeFunctionTypedInstanceGetter2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceGetter2:[null|exact=B]*/
 invokeFunctionTypedInstanceGetter2(
         GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
 
-/*element: invokeFunctionTypedInstanceGetter3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceGetter3:[null|exact=C]*/
 invokeFunctionTypedInstanceGetter3(
         GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedGetter();
 
-/*element: invokeFunctionTypedInstanceField1:[null|subclass=A]*/
+/*member: invokeFunctionTypedInstanceField1:[null|subclass=A]*/
 invokeFunctionTypedInstanceField1(GenericClass<A> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedField();
 
-/*element: invokeFunctionTypedInstanceField2:[null|exact=B]*/
+/*member: invokeFunctionTypedInstanceField2:[null|exact=B]*/
 invokeFunctionTypedInstanceField2(GenericClass<B> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedField();
 
-/*element: invokeFunctionTypedInstanceField3:[null|exact=C]*/
+/*member: invokeFunctionTypedInstanceField3:[null|exact=C]*/
 invokeFunctionTypedInstanceField3(GenericClass<C> /*[exact=GenericClass]*/ c) =>
     c. /*invoke: [exact=GenericClass]*/ functionTypedField();
 
-/*element: invokeFunctionTypedSuperMethod1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod1:[null|subclass=Object]*/
 invokeFunctionTypedSuperMethod1(
         GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
 
-/*element: invokeFunctionTypedSuperMethod2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod2:[null|subclass=Object]*/
 invokeFunctionTypedSuperMethod2(
         GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
 
-/*element: invokeFunctionTypedSuperMethod3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperMethod3:[null|subclass=Object]*/
 invokeFunctionTypedSuperMethod3(
         GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superMethodInvoke();
 
-/*element: invokeFunctionTypedSuperGetter1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter1:[null|subclass=Object]*/
 invokeFunctionTypedSuperGetter1(
         GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
 
-/*element: invokeFunctionTypedSuperGetter2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter2:[null|subclass=Object]*/
 invokeFunctionTypedSuperGetter2(
         GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
 
-/*element: invokeFunctionTypedSuperGetter3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperGetter3:[null|subclass=Object]*/
 invokeFunctionTypedSuperGetter3(
         GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superGetterInvoke();
 
-/*element: invokeFunctionTypedSuperField1:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField1:[null|subclass=Object]*/
 invokeFunctionTypedSuperField1(
         GenericSubclass<A> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
 
-/*element: invokeFunctionTypedSuperField2:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField2:[null|subclass=Object]*/
 invokeFunctionTypedSuperField2(
         GenericSubclass<B> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
 
-/*element: invokeFunctionTypedSuperField3:[null|subclass=Object]*/
+/*member: invokeFunctionTypedSuperField3:[null|subclass=Object]*/
 invokeFunctionTypedSuperField3(
         GenericSubclass<C> /*[exact=GenericSubclass]*/ c) =>
     c. /*invoke: [exact=GenericSubclass]*/ superFieldInvoke();
 
-/*element: invokeGenericClasses:[null]*/
+/*member: invokeGenericClasses:[null]*/
 invokeGenericClasses() {
   invokeInstanceMethod1(new GenericClass<A>(new A()));
   invokeInstanceMethod2(new GenericClass<B>(new B()));
@@ -336,128 +336,128 @@
   invokeFunctionTypedSuperField3(new GenericSubclass<C>(new C()));
 }
 
-/*element: genericMethod:Union([exact=C], [subclass=A])*/
+/*member: genericMethod:Union([exact=C], [subclass=A])*/
 T genericMethod<T>(T /*Union([exact=C], [subclass=A])*/ t) => t;
 
-/*element: functionTypedGenericMethod:[subclass=Closure]*/
+/*member: functionTypedGenericMethod:[subclass=Closure]*/
 T Function() functionTypedGenericMethod<T>(
         T /*Union([exact=C], [subclass=A])*/ t) =>
     /*Union([exact=C], [subclass=A])*/ () => t;
 
-/*element: Class.:[exact=Class]*/
+/*member: Class.:[exact=Class]*/
 class Class {
-  /*element: Class.genericMethod:Union([exact=C], [subclass=A])*/
+  /*member: Class.genericMethod:Union([exact=C], [subclass=A])*/
   T genericMethod<T>(T /*Union([exact=C], [subclass=A])*/ t) => t;
 
-  /*element: Class.functionTypedGenericMethod:[subclass=Closure]*/
+  /*member: Class.functionTypedGenericMethod:[subclass=Closure]*/
   T Function() functionTypedGenericMethod<T>(
           T /*Union([exact=C], [subclass=A])*/ t) =>
       /*Union([exact=C], [subclass=A])*/ () => t;
 }
 
-/*element: Subclass.:[exact=Subclass]*/
+/*member: Subclass.:[exact=Subclass]*/
 class Subclass extends Class {
-  /*element: Subclass.superMethod1:[subclass=A]*/
+  /*member: Subclass.superMethod1:[subclass=A]*/
   superMethod1() {
     return super.genericMethod<A>(new A());
   }
 
-  /*element: Subclass.superMethod2:[exact=B]*/
+  /*member: Subclass.superMethod2:[exact=B]*/
   superMethod2() {
     return super.genericMethod<B>(new B());
   }
 
-  /*element: Subclass.superMethod3:[exact=C]*/
+  /*member: Subclass.superMethod3:[exact=C]*/
   superMethod3() {
     return super.genericMethod<C>(new C());
   }
 
-  /*element: Subclass.functionTypedSuperMethod1:[null|subclass=A]*/
+  /*member: Subclass.functionTypedSuperMethod1:[null|subclass=A]*/
   functionTypedSuperMethod1() {
     return super.functionTypedGenericMethod<A>(new A())();
   }
 
-  /*element: Subclass.functionTypedSuperMethod2:[null|exact=B]*/
+  /*member: Subclass.functionTypedSuperMethod2:[null|exact=B]*/
   functionTypedSuperMethod2() {
     return super.functionTypedGenericMethod<B>(new B())();
   }
 
-  /*element: Subclass.functionTypedSuperMethod3:[null|exact=C]*/
+  /*member: Subclass.functionTypedSuperMethod3:[null|exact=C]*/
   functionTypedSuperMethod3() {
     return super.functionTypedGenericMethod<C>(new C())();
   }
 }
 
-/*element: invokeGenericMethod1:[subclass=A]*/
+/*member: invokeGenericMethod1:[subclass=A]*/
 invokeGenericMethod1(A /*[exact=A]*/ a) => genericMethod<A>(a);
 
-/*element: invokeGenericMethod2:[exact=B]*/
+/*member: invokeGenericMethod2:[exact=B]*/
 invokeGenericMethod2(B /*[exact=B]*/ b) => genericMethod<B>(b);
 
-/*element: invokeGenericMethod3:[exact=C]*/
+/*member: invokeGenericMethod3:[exact=C]*/
 invokeGenericMethod3(C /*[exact=C]*/ c) => genericMethod<C>(c);
 
-/*element: invokeGenericInstanceMethod1:[subclass=A]*/
+/*member: invokeGenericInstanceMethod1:[subclass=A]*/
 invokeGenericInstanceMethod1() =>
     new Class(). /*invoke: [exact=Class]*/ genericMethod<A>(new A());
 
-/*element: invokeGenericInstanceMethod2:[exact=B]*/
+/*member: invokeGenericInstanceMethod2:[exact=B]*/
 invokeGenericInstanceMethod2() =>
     new Class(). /*invoke: [exact=Class]*/ genericMethod<B>(new B());
 
-/*element: invokeGenericInstanceMethod3:[exact=C]*/
+/*member: invokeGenericInstanceMethod3:[exact=C]*/
 invokeGenericInstanceMethod3() =>
     new Class(). /*invoke: [exact=Class]*/ genericMethod<C>(new C());
 
-/*element: invokeGenericSuperMethod1:[subclass=A]*/
+/*member: invokeGenericSuperMethod1:[subclass=A]*/
 invokeGenericSuperMethod1() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ superMethod1();
 
-/*element: invokeGenericSuperMethod2:[exact=B]*/
+/*member: invokeGenericSuperMethod2:[exact=B]*/
 invokeGenericSuperMethod2() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ superMethod2();
 
-/*element: invokeGenericSuperMethod3:[exact=C]*/
+/*member: invokeGenericSuperMethod3:[exact=C]*/
 invokeGenericSuperMethod3() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ superMethod3();
 
-/*element: invokeFunctionTypedGenericMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericMethod1:[null|subclass=A]*/
 invokeFunctionTypedGenericMethod1(A /*[exact=A]*/ a) =>
     functionTypedGenericMethod<A>(a)();
 
-/*element: invokeFunctionTypedGenericMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericMethod2:[null|exact=B]*/
 invokeFunctionTypedGenericMethod2(B /*[exact=B]*/ b) =>
     functionTypedGenericMethod<B>(b)();
 
-/*element: invokeFunctionTypedGenericMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericMethod3:[null|exact=C]*/
 invokeFunctionTypedGenericMethod3(C /*[exact=C]*/ c) =>
     functionTypedGenericMethod<C>(c)();
 
-/*element: invokeFunctionTypedGenericInstanceMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericInstanceMethod1:[null|subclass=A]*/
 invokeFunctionTypedGenericInstanceMethod1() => new Class()
     . /*invoke: [exact=Class]*/ functionTypedGenericMethod<A>(new A())();
 
-/*element: invokeFunctionTypedGenericInstanceMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericInstanceMethod2:[null|exact=B]*/
 invokeFunctionTypedGenericInstanceMethod2() => new Class()
     . /*invoke: [exact=Class]*/ functionTypedGenericMethod<B>(new B())();
 
-/*element: invokeFunctionTypedGenericInstanceMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericInstanceMethod3:[null|exact=C]*/
 invokeFunctionTypedGenericInstanceMethod3() => new Class()
     . /*invoke: [exact=Class]*/ functionTypedGenericMethod<C>(new C())();
 
-/*element: invokeFunctionTypedGenericSuperMethod1:[null|subclass=A]*/
+/*member: invokeFunctionTypedGenericSuperMethod1:[null|subclass=A]*/
 invokeFunctionTypedGenericSuperMethod1() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod1();
 
-/*element: invokeFunctionTypedGenericSuperMethod2:[null|exact=B]*/
+/*member: invokeFunctionTypedGenericSuperMethod2:[null|exact=B]*/
 invokeFunctionTypedGenericSuperMethod2() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod2();
 
-/*element: invokeFunctionTypedGenericSuperMethod3:[null|exact=C]*/
+/*member: invokeFunctionTypedGenericSuperMethod3:[null|exact=C]*/
 invokeFunctionTypedGenericSuperMethod3() =>
     new Subclass(). /*invoke: [exact=Subclass]*/ functionTypedSuperMethod3();
 
-/*element: invokeGenericMethods:[null]*/
+/*member: invokeGenericMethods:[null]*/
 invokeGenericMethods() {
   invokeGenericMethod1(new A());
   invokeGenericMethod2(new B());
diff --git a/tests/compiler/dart2js/inference/data/while.dart b/tests/compiler/dart2js/inference/data/while.dart
index 1858bf4..a6f7373 100644
--- a/tests/compiler/dart2js/inference/data/while.dart
+++ b/tests/compiler/dart2js/inference/data/while.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   simpleWhile();
   whileNull();
@@ -20,7 +20,7 @@
 /// Simple int based while loop.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: simpleWhile:[null]*/
+/*member: simpleWhile:[null]*/
 simpleWhile() {
   var i = 0;
   while (i /*invoke: [subclass=JSPositiveInt]*/ < 10) {
@@ -33,7 +33,7 @@
 /// While loop with null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: whileNull:Value([null|exact=JSString], value: "null")*/
+/*member: whileNull:Value([null|exact=JSString], value: "null")*/
 whileNull() {
   var o;
   while (o == null) {
@@ -46,7 +46,7 @@
 /// While loop with not-null test.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: whileNotNull:[exact=JSString]*/
+/*member: whileNotNull:[exact=JSString]*/
 whileNotNull() {
   var o = '';
   while (o != null) {
@@ -59,7 +59,7 @@
 /// While loop with null test with an unreachable body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: whileNullUnreachable:[exact=JSString]*/
+/*member: whileNullUnreachable:[exact=JSString]*/
 whileNullUnreachable() {
   var o = '';
   while (o == null) {
@@ -72,7 +72,7 @@
 /// While loop with not-null test with an unreachable body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: whileNotNullUnreachable:[null]*/
+/*member: whileNotNullUnreachable:[null]*/
 whileNotNullUnreachable() {
   var o = null;
   while (o != null) {
@@ -86,19 +86,19 @@
 /// object to the [_whileUnion1] method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class1.:[exact=Class1]*/
+/*member: Class1.:[exact=Class1]*/
 class Class1 {
-  /*element: Class1.field:[null|exact=Class2]*/
+  /*member: Class1.field:[null|exact=Class2]*/
   var field;
 }
 
-/*element: Class2.:[exact=Class2]*/
+/*member: Class2.:[exact=Class2]*/
 class Class2 {
-  /*element: Class2.field:[null|exact=Class1]*/
+  /*member: Class2.field:[null|exact=Class1]*/
   var field;
 }
 
-/*element: _whileUnion1:Union([exact=Class1], [null|exact=Class2])*/
+/*member: _whileUnion1:Union([exact=Class1], [null|exact=Class2])*/
 _whileUnion1(/*[exact=Class1]*/ o) {
   while (o != null) {
     o = o. /*Union([exact=Class1], [exact=Class2])*/ field;
@@ -106,7 +106,7 @@
   return o;
 }
 
-/*element: whileUnion1:[null]*/
+/*member: whileUnion1:[null]*/
 whileUnion1() {
   var c1 = new Class1();
   var c2 = new Class2();
@@ -120,19 +120,19 @@
 /// object to the [_whileUnion2] method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class3.:[exact=Class3]*/
+/*member: Class3.:[exact=Class3]*/
 class Class3 {
-  /*element: Class3.field:[null|exact=Class4]*/
+  /*member: Class3.field:[null|exact=Class4]*/
   var field;
 }
 
-/*element: Class4.:[exact=Class4]*/
+/*member: Class4.:[exact=Class4]*/
 class Class4 {
-  /*element: Class4.field:[null|exact=Class3]*/
+  /*member: Class4.field:[null|exact=Class3]*/
   var field;
 }
 
-/*element: _whileUnion2:Union([exact=Class4], [null|exact=Class3])*/
+/*member: _whileUnion2:Union([exact=Class4], [null|exact=Class3])*/
 _whileUnion2(/*[exact=Class4]*/ o) {
   while (o != null) {
     o = o. /*Union([exact=Class3], [exact=Class4])*/ field;
@@ -140,7 +140,7 @@
   return o;
 }
 
-/*element: whileUnion2:[null]*/
+/*member: whileUnion2:[null]*/
 whileUnion2() {
   var c1 = new Class3();
   var c2 = new Class4();
@@ -154,19 +154,19 @@
 /// objects to the [_whileUnion3] method.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class5.:[exact=Class5]*/
+/*member: Class5.:[exact=Class5]*/
 class Class5 {
-  /*element: Class5.field:[null|exact=Class6]*/
+  /*member: Class5.field:[null|exact=Class6]*/
   var field;
 }
 
-/*element: Class6.:[exact=Class6]*/
+/*member: Class6.:[exact=Class6]*/
 class Class6 {
-  /*element: Class6.field:[null|exact=Class5]*/
+  /*member: Class6.field:[null|exact=Class5]*/
   var field;
 }
 
-/*element: _whileUnion3:Union([null|exact=Class5], [null|exact=Class6])*/
+/*member: _whileUnion3:Union([null|exact=Class5], [null|exact=Class6])*/
 _whileUnion3(/*Union([exact=Class5], [exact=Class6])*/ o) {
   while (o != null) {
     o = o. /*Union([exact=Class5], [exact=Class6])*/ field;
@@ -174,7 +174,7 @@
   return o;
 }
 
-/*element: whileUnion3:[null]*/
+/*member: whileUnion3:[null]*/
 whileUnion3() {
   var c1 = new Class5();
   var c2 = new Class6();
@@ -188,19 +188,19 @@
 /// While loop with is test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class7.:[exact=Class7]*/
+/*member: Class7.:[exact=Class7]*/
 class Class7 {
-  /*element: Class7.field:[null|exact=Class8]*/
+  /*member: Class7.field:[null|exact=Class8]*/
   var field;
 }
 
-/*element: Class8.:[exact=Class8]*/
+/*member: Class8.:[exact=Class8]*/
 class Class8 {
-  /*element: Class8.field:[null|exact=Class7]*/
+  /*member: Class8.field:[null|exact=Class7]*/
   var field;
 }
 
-/*element: _whileIs:Union([exact=Class7], [null|exact=Class8])*/
+/*member: _whileIs:Union([exact=Class7], [null|exact=Class8])*/
 _whileIs(/*[exact=Class7]*/ o) {
   while (o is Class7) {
     o = o. /*[exact=Class7]*/ field;
@@ -208,7 +208,7 @@
   return o;
 }
 
-/*element: whileIs:[null]*/
+/*member: whileIs:[null]*/
 whileIs() {
   var c1 = new Class7();
   var c2 = new Class8();
@@ -221,19 +221,19 @@
 /// While loop with is-not test that mixes field accesses.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: Class9.:[exact=Class9]*/
+/*member: Class9.:[exact=Class9]*/
 class Class9 {
-  /*element: Class9.field:[null|exact=Class10]*/
+  /*member: Class9.field:[null|exact=Class10]*/
   var field;
 }
 
-/*element: Class10.:[exact=Class10]*/
+/*member: Class10.:[exact=Class10]*/
 class Class10 {
-  /*element: Class10.field:[null|exact=Class9]*/
+  /*member: Class10.field:[null|exact=Class9]*/
   var field;
 }
 
-/*element: _whileIsNot:Union([exact=Class9], [null|exact=Class10])*/
+/*member: _whileIsNot:Union([exact=Class9], [null|exact=Class10])*/
 _whileIsNot(/*[exact=Class9]*/ o) {
   while (o is! Class10) {
     o = o. /*Union([exact=Class9], [null|exact=Class10])*/ field;
@@ -241,7 +241,7 @@
   return o;
 }
 
-/*element: whileIsNot:[null]*/
+/*member: whileIsNot:[null]*/
 whileIsNot() {
   var c1 = new Class9();
   var c2 = new Class10();
diff --git a/tests/compiler/dart2js/inference/data/yield.dart b/tests/compiler/dart2js/inference/data/yield.dart
index 14b1d21..3f89f21 100644
--- a/tests/compiler/dart2js/inference/data/yield.dart
+++ b/tests/compiler/dart2js/inference/data/yield.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[null]*/
+/*member: main:[null]*/
 main() {
   yieldZero();
   yieldList();
@@ -15,7 +15,7 @@
 // Yield a single integer.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: yieldZero:[exact=_SyncStarIterable]*/
+/*member: yieldZero:[exact=_SyncStarIterable]*/
 yieldZero() sync* {
   yield 0;
 }
@@ -24,7 +24,7 @@
 // Yield a list of integers.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: yieldList:[exact=_SyncStarIterable]*/
+/*member: yieldList:[exact=_SyncStarIterable]*/
 yieldList() sync* {
   yield [0, 1, 2, 3];
 }
@@ -33,7 +33,7 @@
 // Yield star of a list of integers.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: yieldStarList:[exact=_SyncStarIterable]*/
+/*member: yieldStarList:[exact=_SyncStarIterable]*/
 yieldStarList() sync* {
   yield* [0, 1, 2, 3];
 }
@@ -42,7 +42,7 @@
 // Yield multiple integers.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: yieldMany:[exact=_SyncStarIterable]*/
+/*member: yieldMany:[exact=_SyncStarIterable]*/
 yieldMany() sync* {
   yield 0;
   yield 1;
@@ -54,7 +54,7 @@
 // Yield an integer and a string.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: yieldIntAndString:[exact=_SyncStarIterable]*/
+/*member: yieldIntAndString:[exact=_SyncStarIterable]*/
 yieldIntAndString() sync* {
   yield 0;
   yield '';
diff --git a/tests/compiler/dart2js/inference/inference2_test.dart b/tests/compiler/dart2js/inference/inference2_test.dart
new file mode 100644
index 0000000..68b3c20
--- /dev/null
+++ b/tests/compiler/dart2js/inference/inference2_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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 'inference_test_helper.dart';
+
+main(List<String> args) {
+  runTests(args, 2);
+}
diff --git a/tests/compiler/dart2js/inference/inference3_test.dart b/tests/compiler/dart2js/inference/inference3_test.dart
new file mode 100644
index 0000000..6161412
--- /dev/null
+++ b/tests/compiler/dart2js/inference/inference3_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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 'inference_test_helper.dart';
+
+main(List<String> args) {
+  runTests(args, 3);
+}
diff --git a/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart b/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
index 8b629ec..d984418 100644
--- a/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
+++ b/tests/compiler/dart2js/inference/inference_data/called_in_loop.dart
@@ -11,13 +11,13 @@
   staticCalledIndirectlyInForLoop();
 }
 
-/*element: _staticCalledInForLoop:loop*/
+/*member: _staticCalledInForLoop:loop*/
 _staticCalledInForLoop() {}
 
-/*element: _staticNotCalledInForLoop:*/
+/*member: _staticNotCalledInForLoop:*/
 _staticNotCalledInForLoop() {}
 
-/*element: staticCalledInForLoop:*/
+/*member: staticCalledInForLoop:*/
 staticCalledInForLoop() {
   _staticNotCalledInForLoop();
   for (int i = 0; i < 10; i++) {
@@ -26,13 +26,13 @@
   _staticNotCalledInForLoop();
 }
 
-/*element: _staticCalledInForInLoop:loop*/
+/*member: _staticCalledInForInLoop:loop*/
 _staticCalledInForInLoop() {}
 
-/*element: _staticNotCalledInForInLoop:*/
+/*member: _staticNotCalledInForInLoop:*/
 _staticNotCalledInForInLoop() {}
 
-/*element: staticCalledInForInLoop:*/
+/*member: staticCalledInForInLoop:*/
 staticCalledInForInLoop() {
   _staticNotCalledInForInLoop();
   // ignore: unused_local_variable
@@ -42,13 +42,13 @@
   _staticNotCalledInForInLoop();
 }
 
-/*element: _staticCalledInWhileLoop:loop*/
+/*member: _staticCalledInWhileLoop:loop*/
 _staticCalledInWhileLoop() {}
 
-/*element: _staticNotCalledInWhileLoop:*/
+/*member: _staticNotCalledInWhileLoop:*/
 _staticNotCalledInWhileLoop() {}
 
-/*element: staticCalledInWhileLoop:*/
+/*member: staticCalledInWhileLoop:*/
 staticCalledInWhileLoop() {
   int i = 0;
   _staticNotCalledInWhileLoop();
@@ -59,13 +59,13 @@
   _staticNotCalledInWhileLoop();
 }
 
-/*element: _staticCalledInDoLoop:loop*/
+/*member: _staticCalledInDoLoop:loop*/
 _staticCalledInDoLoop() {}
 
-/*element: _staticNotCalledInDoLoop:*/
+/*member: _staticNotCalledInDoLoop:*/
 _staticNotCalledInDoLoop() {}
 
-/*element: staticCalledInDoLoop:*/
+/*member: staticCalledInDoLoop:*/
 staticCalledInDoLoop() {
   int i = 0;
   _staticNotCalledInDoLoop();
@@ -77,21 +77,21 @@
 }
 
 class Class {
-  /*element: Class.constructorCalledInForLoop:loop*/
+  /*member: Class.constructorCalledInForLoop:loop*/
   Class.constructorCalledInForLoop();
 
-  /*element: Class.constructorNotCalledInForLoop:*/
+  /*member: Class.constructorNotCalledInForLoop:*/
   Class.constructorNotCalledInForLoop();
 
   // TODO(johnniwinther): Should we track instance calls in loops?
-  /*element: Class.instanceCalledInForLoop:*/
+  /*member: Class.instanceCalledInForLoop:*/
   instanceCalledInForLoop() {}
 
-  /*element: Class.instanceNotCalledInForLoop:*/
+  /*member: Class.instanceNotCalledInForLoop:*/
   instanceNotCalledInForLoop() {}
 }
 
-/*element: instanceCalledInForLoop:*/
+/*member: instanceCalledInForLoop:*/
 instanceCalledInForLoop() {
   var c = new Class.constructorNotCalledInForLoop();
   c.instanceNotCalledInForLoop();
@@ -103,13 +103,13 @@
 }
 
 // TODO(johnniwinther): Should we track indirect calls in loops?
-/*element: _staticCalledIndirectlyInForLoop:*/
+/*member: _staticCalledIndirectlyInForLoop:*/
 _staticCalledIndirectlyInForLoop() {}
 
-/*element: _staticCalledIndirectlyInForLoopHelper:loop*/
+/*member: _staticCalledIndirectlyInForLoopHelper:loop*/
 _staticCalledIndirectlyInForLoopHelper() => _staticCalledIndirectlyInForLoop();
 
-/*element: staticCalledIndirectlyInForLoop:*/
+/*member: staticCalledIndirectlyInForLoop:*/
 staticCalledIndirectlyInForLoop() {
   for (int i = 0; i < 10; i++) {
     _staticCalledIndirectlyInForLoopHelper();
diff --git a/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart b/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
index b91c000..9c516ba 100644
--- a/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
+++ b/tests/compiler/dart2js/inference/inference_data/cannot_throw.dart
@@ -9,17 +9,17 @@
 }
 
 // We trust the annotation.
-/*element: noThrows:no-throw*/
+/*member: noThrows:no-throw*/
 @pragma('dart2js:noThrows')
 @pragma(
     'dart2js:noInline') // Required for the @pragma('dart2js:noThrows') annotation.
 noThrows() => throw '';
 
 // Check that the @pragma('dart2js:noInline') annotation has no impact on its own.
-/*element: noInline:*/
+/*member: noInline:*/
 @pragma('dart2js:noInline')
 noInline() {}
 
 // TODO(johnniwinther): Should we infer this?
-/*element: throws:*/
+/*member: throws:*/
 throws() => 0;
diff --git a/tests/compiler/dart2js/inference/inference_data/function_apply.dart b/tests/compiler/dart2js/inference/inference_data/function_apply.dart
index b02d84a..a74ae06 100644
--- a/tests/compiler/dart2js/inference/inference_data/function_apply.dart
+++ b/tests/compiler/dart2js/inference/inference_data/function_apply.dart
@@ -10,35 +10,35 @@
   instantiatedCall();
 }
 
-/*element: _directCall:apply*/
+/*member: _directCall:apply*/
 _directCall() {}
 
-/*element: directCall:*/
+/*member: directCall:*/
 void directCall() {
   Function.apply(_directCall, []);
 }
 
-/*element: _indirectCall:apply*/
+/*member: _indirectCall:apply*/
 _indirectCall() {}
 
-/*element: _indirectCallHelper:*/
+/*member: _indirectCallHelper:*/
 _indirectCallHelper(f) => Function.apply(f, []);
 
-/*element: indirectCall:*/
+/*member: indirectCall:*/
 void indirectCall() {
   _indirectCallHelper(_indirectCall);
 }
 
-/*element: Class.:*/
+/*member: Class.:*/
 class Class {
-  /*element: Class.instanceTearOff1:apply*/
+  /*member: Class.instanceTearOff1:apply*/
   instanceTearOff1() {}
 
-  /*element: Class.instanceTearOff2:*/
+  /*member: Class.instanceTearOff2:*/
   instanceTearOff2() {}
 }
 
-/*element: _instanceTearOffHelper:*/
+/*member: _instanceTearOffHelper:*/
 _instanceTearOffHelper(f) => Function.apply(f, []);
 
 instanceTearOff() {
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index 9259adb..bd0eddb 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -38,7 +38,7 @@
         testCFEConstants: true,
         skipForStrong: skipForStrong,
         shardIndex: shardIndex ?? 0,
-        shards: shardIndex != null ? 2 : 1);
+        shards: shardIndex != null ? 4 : 1);
   });
 }
 
diff --git a/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart b/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
index 8ae50e9..f734696 100644
--- a/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
+++ b/tests/compiler/dart2js/inference/libs/mixin_constructor_default_parameter_values_lib.dart
@@ -3,33 +3,33 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class _SECRET {
-  /*element: _SECRET.:[exact=_SECRET]*/
+  /*member: _SECRET.:[exact=_SECRET]*/
   const _SECRET();
-  /*element: _SECRET.toString:Value([exact=JSString], value: "SECRET!")*/
+  /*member: _SECRET.toString:Value([exact=JSString], value: "SECRET!")*/
   @override
   String toString() => "SECRET!";
 }
 
 class C {
-  /*element: C.x:[exact=JSUInt31]*/
+  /*member: C.x:[exact=JSUInt31]*/
   final int x;
 
-  /*element: C.y:Union([exact=JSString], [exact=_SECRET])*/
+  /*member: C.y:Union([exact=JSString], [exact=_SECRET])*/
   final y;
 
-  /*element: C.a:[exact=C]*/
+  /*member: C.a:[exact=C]*/
   C.a(int /*[exact=JSUInt31]*/ x,
       [var /*Union([exact=JSString], [exact=_SECRET])*/ b = const _SECRET()])
       : this.x = x,
         this.y = b;
 
-  /*element: C.b:[exact=C]*/
+  /*member: C.b:[exact=C]*/
   C.b(int /*[exact=JSUInt31]*/ x,
       {var /*Union([exact=JSString], [exact=_SECRET])*/ b: const _SECRET()})
       : this.x = x,
         this.y = b;
 
-  /*element: C.toString:[exact=JSString]*/
+  /*member: C.toString:[exact=JSString]*/
   @override
   String toString() => "C(${/*[exact=D]*/ x},${/*[exact=D]*/ y})";
 }
diff --git a/tests/compiler/dart2js/inference/side_effects/annotations.dart b/tests/compiler/dart2js/inference/side_effects/annotations.dart
index 4337cf8..a7d5f65 100644
--- a/tests/compiler/dart2js/inference/side_effects/annotations.dart
+++ b/tests/compiler/dart2js/inference/side_effects/annotations.dart
@@ -7,18 +7,18 @@
 
 /// Read a static field. This adds dependency of static properties to the
 /// side effects of the method.
-/*element: readStaticField:SideEffects(reads static; writes nothing)*/
+/*member: readStaticField:SideEffects(reads static; writes nothing)*/
 readStaticField() => field;
 
 /// Read a static field. If not for the `@pragma('dart2js:noSideEffects')`
 /// annotation this would add dependency of static properties to the side
 /// effects of the method.
-/*element: readStaticFieldAnnotated:SideEffects(reads nothing; writes nothing)*/
+/*member: readStaticFieldAnnotated:SideEffects(reads nothing; writes nothing)*/
 @pragma('dart2js:noInline')
 @pragma('dart2js:noSideEffects')
 readStaticFieldAnnotated() => field;
 
-/*element: main:SideEffects(reads static; writes nothing)*/
+/*member: main:SideEffects(reads static; writes nothing)*/
 main() {
   readStaticField();
   readStaticFieldAnnotated();
diff --git a/tests/compiler/dart2js/inference/side_effects/foreign.dart b/tests/compiler/dart2js/inference/side_effects/foreign.dart
index 9c4e18a..dc8ad67 100644
--- a/tests/compiler/dart2js/inference/side_effects/foreign.dart
+++ b/tests/compiler/dart2js/inference/side_effects/foreign.dart
@@ -11,41 +11,41 @@
 /// ignore: IMPORT_INTERNAL_LIBRARY, UNUSED_IMPORT
 import 'dart:_interceptors';
 
-/*element: jsCallEmpty:SideEffects(reads nothing; writes nothing)*/
+/*member: jsCallEmpty:SideEffects(reads nothing; writes nothing)*/
 jsCallEmpty() => JS('', '#', 0);
 
-/*element: jsCallInt:SideEffects(reads nothing; writes nothing)*/
+/*member: jsCallInt:SideEffects(reads nothing; writes nothing)*/
 jsCallInt() => JS('int', '#', 0);
 
-/*element: jsCallEffectsAllDependsNoIndex:SideEffects(reads field, static; writes anything)*/
+/*member: jsCallEffectsAllDependsNoIndex:SideEffects(reads field, static; writes anything)*/
 jsCallEffectsAllDependsNoIndex() => JS('effects:all;depends:no-index', '#', 0);
 
-/*element: jsCallEffectsNoInstanceDependsNoStatic:SideEffects(reads index, field; writes index, static)*/
+/*member: jsCallEffectsNoInstanceDependsNoStatic:SideEffects(reads index, field; writes index, static)*/
 jsCallEffectsNoInstanceDependsNoStatic() =>
     JS('effects:no-instance;depends:no-static', '#', 0);
 
-/*element: jsBuiltin_rawRtiToJsConstructorName:SideEffects(reads anything; writes anything)*/
+/*member: jsBuiltin_rawRtiToJsConstructorName:SideEffects(reads anything; writes anything)*/
 jsBuiltin_rawRtiToJsConstructorName() {
   return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, null);
 }
 
-/*element: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
+/*member: jsEmbeddedGlobal_getTypeFromName:SideEffects(reads static; writes nothing)*/
 jsEmbeddedGlobal_getTypeFromName() {
   return JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME);
 }
 
-/*element: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
+/*member: jsEmbeddedGlobal_libraries:SideEffects(reads static; writes nothing)*/
 jsEmbeddedGlobal_libraries() {
   return JS_EMBEDDED_GLOBAL('JSExtendableArray|Null', LIBRARIES);
 }
 
-/*element: jsStringConcat:SideEffects(reads nothing; writes nothing)*/
+/*member: jsStringConcat:SideEffects(reads nothing; writes nothing)*/
 jsStringConcat() => JS_STRING_CONCAT('a', 'b');
 
-/*element: jsGetStaticState:SideEffects(reads nothing; writes anything)*/
+/*member: jsGetStaticState:SideEffects(reads nothing; writes anything)*/
 jsGetStaticState() => JS_GET_STATIC_STATE();
 
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
 main() {
   jsCallInt();
   jsCallEmpty();
diff --git a/tests/compiler/dart2js/inference/side_effects/local_functions.dart b/tests/compiler/dart2js/inference/side_effects/local_functions.dart
index fdf569e..b6a53a0 100644
--- a/tests/compiler/dart2js/inference/side_effects/local_functions.dart
+++ b/tests/compiler/dart2js/inference/side_effects/local_functions.dart
@@ -4,31 +4,31 @@
 
 var field;
 
-/*element: anonymousClosureUnused:SideEffects(reads nothing; writes nothing)*/
+/*member: anonymousClosureUnused:SideEffects(reads nothing; writes nothing)*/
 anonymousClosureUnused() {
   /*SideEffects(reads static; writes nothing)*/
   () => field;
 }
 
-/*element: anonymousClosureCalled:SideEffects(reads anything; writes anything)*/
+/*member: anonymousClosureCalled:SideEffects(reads anything; writes anything)*/
 anonymousClosureCalled() {
   var localFunction = /*SideEffects(reads static; writes nothing)*/ () => field;
   return localFunction();
 }
 
-/*element: localFunctionUnused:SideEffects(reads nothing; writes nothing)*/
+/*member: localFunctionUnused:SideEffects(reads nothing; writes nothing)*/
 localFunctionUnused() {
   // ignore: UNUSED_ELEMENT
   /*SideEffects(reads static; writes nothing)*/ localFunction() => field;
 }
 
-/*element: localFunctionCalled:SideEffects(reads static; writes nothing)*/
+/*member: localFunctionCalled:SideEffects(reads static; writes nothing)*/
 localFunctionCalled() {
   /*SideEffects(reads static; writes nothing)*/ localFunction() => field;
   return localFunction();
 }
 
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
 main() {
   anonymousClosureUnused();
   anonymousClosureCalled();
diff --git a/tests/compiler/dart2js/inference/side_effects/methods.dart b/tests/compiler/dart2js/inference/side_effects/methods.dart
index 4774e55..99a0278 100644
--- a/tests/compiler/dart2js/inference/side_effects/methods.dart
+++ b/tests/compiler/dart2js/inference/side_effects/methods.dart
@@ -6,193 +6,193 @@
 var field;
 
 /// Static getter with no side effects. Used in tests below.
-/*element: emptyGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: emptyGetter:SideEffects(reads nothing; writes nothing)*/
 get emptyGetter => null;
 
 /// Static getter with a single side effect of reading a static. Used in tests
 /// below.
-/*element: nonEmptyGetter:SideEffects(reads static; writes nothing)*/
+/*member: nonEmptyGetter:SideEffects(reads static; writes nothing)*/
 get nonEmptyGetter => field;
 
 /// Static method with no side effects. Used in tests below.
-/*element: emptyMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: emptyMethod:SideEffects(reads nothing; writes nothing)*/
 emptyMethod() {}
 
 /// Static method with a single side effect of reading a static. Used in tests
 /// below.
-/*element: nonEmptyMethod:SideEffects(reads static; writes nothing)*/
+/*member: nonEmptyMethod:SideEffects(reads static; writes nothing)*/
 nonEmptyMethod() => field;
 
-/*element: Class.:SideEffects(reads nothing; writes nothing)*/
+/*member: Class.:SideEffects(reads nothing; writes nothing)*/
 class Class {
   /// Instance field used in tests below.
   var field;
 
   /// Instance getter with no side effects. Used in tests below.
-  /*element: Class.emptyGetter:SideEffects(reads nothing; writes nothing)*/
+  /*member: Class.emptyGetter:SideEffects(reads nothing; writes nothing)*/
   get emptyGetter => null;
 
   /// Instance getter with a single side effect of reading a static. Used in
   /// tests below.
-  /*element: Class.nonEmptyGetter:SideEffects(reads field; writes nothing)*/
+  /*member: Class.nonEmptyGetter:SideEffects(reads field; writes nothing)*/
   get nonEmptyGetter => field;
 
   /// Instance method with no side effects. Used in tests below.
-  /*element: Class.emptyMethod:SideEffects(reads nothing; writes nothing)*/
+  /*member: Class.emptyMethod:SideEffects(reads nothing; writes nothing)*/
   emptyMethod() {}
 
   /// Instance method with a single side effect of reading a static. Used in
   /// tests below.
-  /*element: Class.nonEmptyMethod:SideEffects(reads field; writes nothing)*/
+  /*member: Class.nonEmptyMethod:SideEffects(reads field; writes nothing)*/
   nonEmptyMethod() => field;
 }
 
 /// Call an empty instance method. This propagates the side effects of the
 /// instance method; here none.
-/*element: callEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: callEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
 callEmptyInstanceMethod(c) => c.emptyMethod();
 
 /// Call an empty instance getter. This marks the method as having all side
 /// effects.
-/*element: callEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
+/*member: callEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
 callEmptyInstanceGetter(c) => c.emptyGetter();
 
 /// Call a non-empty instance method. This propagates the side effects of the
 /// instance method; here dependency of static properties.
-/*element: callNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
+/*member: callNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
 callNonEmptyInstanceMethod(c) => c.nonEmptyMethod();
 
 /// Call a non-empty instance getter. This marks the method as having all side
 /// effects.
-/*element: callNonEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
+/*member: callNonEmptyInstanceGetter:SideEffects(reads anything; writes anything)*/
 callNonEmptyInstanceGetter(c) => c.nonEmptyGetter();
 
 /// Read an empty instance method. This propagates the side effects of the
 /// instance method; here none.
-/*element: readEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyInstanceMethod:SideEffects(reads nothing; writes nothing)*/
 readEmptyInstanceMethod(c) => c.emptyMethod;
 
 /// Read an empty instance getter. This propagates the side effects of the
 /// instance getter; here none.
-/*element: readEmptyInstanceGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyInstanceGetter:SideEffects(reads nothing; writes nothing)*/
 readEmptyInstanceGetter(c) => c.emptyGetter;
 
 /// Read a non-empty instance method. This propagates the side effects of the
 /// instance method; here dependency of static properties.
-/*element: readNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
+/*member: readNonEmptyInstanceMethod:SideEffects(reads field; writes nothing)*/
 readNonEmptyInstanceMethod(c) => c.nonEmptyMethod;
 
 /// Read a non-empty instance getter. This propagates the side effects of the
 /// instance getter; here dependency of static properties.
-/*element: readNonEmptyInstanceGetter:SideEffects(reads field; writes nothing)*/
+/*member: readNonEmptyInstanceGetter:SideEffects(reads field; writes nothing)*/
 readNonEmptyInstanceGetter(c) => c.nonEmptyGetter;
 
 /// Read an instance field. This adds dependency of instance properties to the
 /// side effects of the method.
-/*element: readInstanceField:SideEffects(reads field; writes nothing)*/
+/*member: readInstanceField:SideEffects(reads field; writes nothing)*/
 readInstanceField(c) => c.field;
 
 /// Write to an instance field. This adds change of instance properties to the
 /// side effects of the method.
-/*element: writeInstanceField:SideEffects(reads nothing; writes field)*/
+/*member: writeInstanceField:SideEffects(reads nothing; writes field)*/
 writeInstanceField(c) => c.field = 42;
 
 /// Call an instance field. This marks the method as having all side effects.
-/*element: callInstanceField:SideEffects(reads anything; writes anything)*/
+/*member: callInstanceField:SideEffects(reads anything; writes anything)*/
 callInstanceField(c) => c.field();
 
 /// Read a static field. This adds dependency of static properties to the
 /// side effects of the method.
-/*element: readStaticField:SideEffects(reads static; writes nothing)*/
+/*member: readStaticField:SideEffects(reads static; writes nothing)*/
 readStaticField() => field;
 
 /// Write to a static field. This adds change of static properties to the
 /// side effects of the method.
-/*element: writeStaticField:SideEffects(reads nothing; writes static)*/
+/*member: writeStaticField:SideEffects(reads nothing; writes static)*/
 writeStaticField() => field = 42;
 
 /// Call a static field. This marks the method as having all side effects.
-/*element: callStaticField:SideEffects(reads anything; writes anything)*/
+/*member: callStaticField:SideEffects(reads anything; writes anything)*/
 callStaticField() => field();
 
 /// Read and write of a static field. This adds dependency of static properties
 /// and change of static properties to the side effects of the method.
-/*element: readAndWriteStaticField:SideEffects(reads static; writes static)*/
+/*member: readAndWriteStaticField:SideEffects(reads static; writes static)*/
 readAndWriteStaticField() {
   field = field;
 }
 
 /// Call an empty static method. This propagates the side effects of the
 /// instance method; here none.
-/*element: callEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: callEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
 callEmptyStaticMethod() => emptyMethod();
 
 /// Call an empty static getter. This marks the method as having all side
 /// effects.
-/*element: callEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
+/*member: callEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
 callEmptyStaticGetter() => emptyGetter();
 
 /// Call a non-empty static method. This propagates the side effects of the
 /// instance method; here dependency of static properties.
-/*element: callNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
+/*member: callNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
 callNonEmptyStaticMethod() => nonEmptyMethod();
 
 /// Call a non-empty static getter. This marks the method as having all side
 /// effects.
-/*element: callNonEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
+/*member: callNonEmptyStaticGetter:SideEffects(reads anything; writes anything)*/
 callNonEmptyStaticGetter() => nonEmptyGetter();
 
 /// Read an empty static method. This propagates the side effects of the
 /// static method; here none.
-/*element: readEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyStaticMethod:SideEffects(reads nothing; writes nothing)*/
 readEmptyStaticMethod() => emptyMethod;
 
 /// Read an empty static getter. This propagates the side effects of the
 /// static getter; here none.
-/*element: readEmptyStaticGetter:SideEffects(reads nothing; writes nothing)*/
+/*member: readEmptyStaticGetter:SideEffects(reads nothing; writes nothing)*/
 readEmptyStaticGetter() => emptyGetter;
 
 /// Read a non-empty static method. This propagates the side effects of the
 /// static method; here dependency of static properties.
-/*element: readNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
+/*member: readNonEmptyStaticMethod:SideEffects(reads static; writes nothing)*/
 readNonEmptyStaticMethod() => nonEmptyMethod;
 
 /// Read a non-empty static getter. This propagates the side effects of the
 /// static getter; here dependency of static properties.
-/*element: readNonEmptyStaticGetter:SideEffects(reads static; writes nothing)*/
+/*member: readNonEmptyStaticGetter:SideEffects(reads static; writes nothing)*/
 readNonEmptyStaticGetter() => nonEmptyGetter;
 
 /// Call a static method that reads an instance field. This propagates the side
 /// effects of the static method; here dependency of instance properties.
-/*element: callingReadInstanceField:SideEffects(reads field; writes nothing)*/
+/*member: callingReadInstanceField:SideEffects(reads field; writes nothing)*/
 callingReadInstanceField(c) => readInstanceField(c);
 
 /// Call a static method that writes to an instance field. This propagates the
 /// side effects of the static method; here change of instance properties.
-/*element: callingWriteInstanceField:SideEffects(reads nothing; writes field)*/
+/*member: callingWriteInstanceField:SideEffects(reads nothing; writes field)*/
 callingWriteInstanceField(c) => writeInstanceField(c);
 
 /// Call a static method that calls an instance field. This propagates the side
 /// effects of the static method; here all side-effects.
-/*element: callingCallInstanceField:SideEffects(reads anything; writes anything)*/
+/*member: callingCallInstanceField:SideEffects(reads anything; writes anything)*/
 callingCallInstanceField(c) => callInstanceField(c);
 
 /// Call a static method that reads a static field. This propagates the side
 /// effects of the static method; here dependency of static properties.
-/*element: callingReadStaticField:SideEffects(reads static; writes nothing)*/
+/*member: callingReadStaticField:SideEffects(reads static; writes nothing)*/
 callingReadStaticField() => readStaticField();
 
 /// Call a static method that writes to a static field. This propagates the
 /// side effects of the static method; here change of static properties.
-/*element: callingWriteStaticField:SideEffects(reads nothing; writes static)*/
+/*member: callingWriteStaticField:SideEffects(reads nothing; writes static)*/
 callingWriteStaticField() => writeStaticField();
 
 /// Call a static method that calls a static field. This propagates the side
 /// effects of the static method; here all side-effects.
-/*element: callingCallStaticField:SideEffects(reads anything; writes anything)*/
+/*member: callingCallStaticField:SideEffects(reads anything; writes anything)*/
 callingCallStaticField() => callStaticField();
 
-/*element: main:SideEffects(reads anything; writes anything)*/
+/*member: main:SideEffects(reads anything; writes anything)*/
 main() {
   var c = new Class();
 
diff --git a/tests/compiler/dart2js/inference/side_effects/out_of_order.dart b/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
index dd4cebb..c8501e3 100644
--- a/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
+++ b/tests/compiler/dart2js/inference/side_effects/out_of_order.dart
@@ -14,21 +14,21 @@
 // The new computation, based on [SideEffectsBuilder], computes the precise
 // result regardless of computation order.
 
-/*element: _noSideEffects:SideEffects(reads nothing; writes nothing)*/
+/*member: _noSideEffects:SideEffects(reads nothing; writes nothing)*/
 _noSideEffects() {}
 
-/*element: callCallNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
+/*member: callCallNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
 callCallNoSideEffectsManyTimes() {
   _callNoSideEffectsManyTimes();
 }
 
-/*element: main:SideEffects(reads nothing; writes nothing)*/
+/*member: main:SideEffects(reads nothing; writes nothing)*/
 main() {
   callCallNoSideEffectsManyTimes();
   callCallNoSideEffectsManyTimes();
 }
 
-/*element: _callNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
+/*member: _callNoSideEffectsManyTimes:SideEffects(reads nothing; writes nothing)*/
 _callNoSideEffectsManyTimes() {
   _noSideEffects();
   _noSideEffects();
diff --git a/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart b/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
index 50a15cc..e85be1f 100644
--- a/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
+++ b/tests/compiler/dart2js/inference/side_effects/string_interpolation.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*element: stringInterpolation:SideEffects(reads nothing; writes anything)*/
+/*member: stringInterpolation:SideEffects(reads nothing; writes anything)*/
 stringInterpolation() => '${null}';
 
-/*element: main:SideEffects(reads nothing; writes anything)*/
+/*member: main:SideEffects(reads nothing; writes anything)*/
 main() {
   stringInterpolation();
 }
diff --git a/tests/compiler/dart2js/inlining/data/conditional.dart b/tests/compiler/dart2js/inlining/data/conditional.dart
index c8aa00f..c19404f 100644
--- a/tests/compiler/dart2js/inlining/data/conditional.dart
+++ b/tests/compiler/dart2js/inlining/data/conditional.dart
@@ -5,7 +5,7 @@
 // Tests for the heuristics on conditional expression whose condition is a
 // parameter for which the max, instead of the sum, of the branch sizes is used.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   conditionalField();
   conditionalParameter();
@@ -16,19 +16,19 @@
 // size of the condition is the sum of the nodes in the conditional expression.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[_conditionalField]*/
+/*member: _method1:[_conditionalField]*/
 _method1() => 42;
 
 bool _field1;
 
-/*element: _conditionalField:[]*/
+/*member: _conditionalField:[]*/
 _conditionalField() {
   return _field1
       ? _method1() + _method1() + _method1()
       : _method1() + _method1() + _method1();
 }
 
-/*element: conditionalField:[]*/
+/*member: conditionalField:[]*/
 @pragma('dart2js:noInline')
 conditionalField() {
   _field1 = false;
@@ -42,17 +42,17 @@
 // max of the branches + the condition itself.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method2:[conditionalParameter]*/
+/*member: _method2:[conditionalParameter]*/
 _method2() => 42;
 
-/*element: _conditionalParameter:[conditionalParameter]*/
+/*member: _conditionalParameter:[conditionalParameter]*/
 _conditionalParameter(bool o) {
   return o
       ? _method2() + _method2() + _method2()
       : _method2() + _method2() + _method2();
 }
 
-/*element: conditionalParameter:[]*/
+/*member: conditionalParameter:[]*/
 @pragma('dart2js:noInline')
 conditionalParameter() {
   _conditionalParameter(true);
diff --git a/tests/compiler/dart2js/inlining/data/constructor.dart b/tests/compiler/dart2js/inlining/data/constructor.dart
index bdd20c6..d60a569 100644
--- a/tests/compiler/dart2js/inlining/data/constructor.dart
+++ b/tests/compiler/dart2js/inlining/data/constructor.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   forceInlineConstructor();
   forceInlineConstructorBody();
@@ -15,12 +15,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.:[forceInlineConstructor:Class1]*/
+  /*member: Class1.:[forceInlineConstructor:Class1]*/
   @pragma('dart2js:tryInline')
   Class1();
 }
 
-/*element: forceInlineConstructor:[]*/
+/*member: forceInlineConstructor:[]*/
 @pragma('dart2js:noInline')
 forceInlineConstructor() {
   new Class1();
@@ -31,14 +31,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.:[forceInlineConstructorBody+,forceInlineConstructorBody:Class2]*/
+  /*member: Class2.:[forceInlineConstructorBody+,forceInlineConstructorBody:Class2]*/
   @pragma('dart2js:tryInline')
   Class2() {
     print('foo');
   }
 }
 
-/*element: forceInlineConstructorBody:[]*/
+/*member: forceInlineConstructorBody:[]*/
 @pragma('dart2js:noInline')
 forceInlineConstructorBody() {
   new Class2();
@@ -49,12 +49,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3<T> {
-  /*element: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
+  /*member: Class3.:[forceInlineGenericConstructor:Class3<int>]*/
   @pragma('dart2js:tryInline')
   Class3();
 }
 
-/*element: forceInlineGenericConstructor:[]*/
+/*member: forceInlineGenericConstructor:[]*/
 @pragma('dart2js:noInline')
 forceInlineGenericConstructor() {
   new Class3<int>();
@@ -65,18 +65,18 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class4a<T> implements Class4b<T> {
-  /*element: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
+  /*member: Class4a.:[forceInlineGenericFactory:Class4a<int>]*/
   @pragma('dart2js:tryInline')
   Class4a();
 }
 
 class Class4b<T> {
-  /*element: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
+  /*member: Class4b.:[forceInlineGenericFactory:Class4b<int>]*/
   @pragma('dart2js:tryInline')
   factory Class4b() => new Class4a<T>();
 }
 
-/*element: forceInlineGenericFactory:[]*/
+/*member: forceInlineGenericFactory:[]*/
 @pragma('dart2js:noInline')
 forceInlineGenericFactory() {
   new Class4b<int>();
diff --git a/tests/compiler/dart2js/inlining/data/dynamic.dart b/tests/compiler/dart2js/inlining/data/dynamic.dart
index 60bcb05..0810edd 100644
--- a/tests/compiler/dart2js/inlining/data/dynamic.dart
+++ b/tests/compiler/dart2js/inlining/data/dynamic.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   forceInlineDynamic();
   forceInlineOptional();
@@ -13,16 +13,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1 {
-  /*element: Class1.:[]*/
+  /*member: Class1.:[]*/
   @pragma('dart2js:noInline')
   Class1();
 
-  /*element: Class1.method:[forceInlineDynamic]*/
+  /*member: Class1.method:[forceInlineDynamic]*/
   @pragma('dart2js:tryInline')
   method() {}
 }
 
-/*element: forceInlineDynamic:[]*/
+/*member: forceInlineDynamic:[]*/
 @pragma('dart2js:noInline')
 forceInlineDynamic() {
   new Class1().method();
@@ -33,16 +33,16 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class2 {
-  /*element: Class2.:[]*/
+  /*member: Class2.:[]*/
   @pragma('dart2js:noInline')
   Class2();
 
-  /*element: Class2.method:[forceInlineOptional]*/
+  /*member: Class2.method:[forceInlineOptional]*/
   @pragma('dart2js:tryInline')
   method([x]) {}
 }
 
-/*element: forceInlineOptional:[]*/
+/*member: forceInlineOptional:[]*/
 @pragma('dart2js:noInline')
 forceInlineOptional() {
   new Class2().method();
diff --git a/tests/compiler/dart2js/inlining/data/external.dart b/tests/compiler/dart2js/inlining/data/external.dart
index b656ff4..e943165 100644
--- a/tests/compiler/dart2js/inlining/data/external.dart
+++ b/tests/compiler/dart2js/inlining/data/external.dart
@@ -7,17 +7,17 @@
 
 import 'package:js/js.dart';
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   externalFunction();
 }
 
-/*element: externalFunction:[]*/
+/*member: externalFunction:[]*/
 @pragma('dart2js:noInline')
 externalFunction() {
   _externalFunction();
 }
 
-/*element: _externalFunction:[]*/
+/*member: _externalFunction:[]*/
 @JS('externalFunction')
 external _externalFunction();
diff --git a/tests/compiler/dart2js/inlining/data/force_inline.dart b/tests/compiler/dart2js/inlining/data/force_inline.dart
index c7e0cf0..4bc1627 100644
--- a/tests/compiler/dart2js/inlining/data/force_inline.dart
+++ b/tests/compiler/dart2js/inlining/data/force_inline.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   forceInlineOnce();
   forceInlineTwice1();
@@ -15,11 +15,11 @@
 // Force inline a top level method once.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forceInlineOnce:[forceInlineOnce]*/
+/*member: _forceInlineOnce:[forceInlineOnce]*/
 @pragma('dart2js:tryInline')
 _forceInlineOnce() {}
 
-/*element: forceInlineOnce:[]*/
+/*member: forceInlineOnce:[]*/
 @pragma('dart2js:noInline')
 forceInlineOnce() {
   _forceInlineOnce();
@@ -29,17 +29,17 @@
 // Force inline a top level method twice.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forceInlineTwice:[forceInlineTwice1,forceInlineTwice2]*/
+/*member: _forceInlineTwice:[forceInlineTwice1,forceInlineTwice2]*/
 @pragma('dart2js:tryInline')
 _forceInlineTwice() {}
 
-/*element: forceInlineTwice1:[]*/
+/*member: forceInlineTwice1:[]*/
 @pragma('dart2js:noInline')
 forceInlineTwice1() {
   _forceInlineTwice();
 }
 
-/*element: forceInlineTwice2:[]*/
+/*member: forceInlineTwice2:[]*/
 @pragma('dart2js:noInline')
 forceInlineTwice2() {
   _forceInlineTwice();
@@ -49,17 +49,17 @@
 // Force inline nested top level methods.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forceInlineNested1:[forceInlineNested]*/
+/*member: _forceInlineNested1:[forceInlineNested]*/
 @pragma('dart2js:tryInline')
 _forceInlineNested1() {}
 
-/*element: _forceInlineNested2:[forceInlineNested]*/
+/*member: _forceInlineNested2:[forceInlineNested]*/
 @pragma('dart2js:tryInline')
 _forceInlineNested2() {
   _forceInlineNested1();
 }
 
-/*element: forceInlineNested:[]*/
+/*member: forceInlineNested:[]*/
 @pragma('dart2js:noInline')
 forceInlineNested() {
   _forceInlineNested2();
@@ -69,11 +69,11 @@
 // Force inline a top level method with optional argument.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forceInlineOptional:[forceInlineOptional]*/
+/*member: _forceInlineOptional:[forceInlineOptional]*/
 @pragma('dart2js:tryInline')
 _forceInlineOptional([x]) {}
 
-/*element: forceInlineOptional:[]*/
+/*member: forceInlineOptional:[]*/
 @pragma('dart2js:noInline')
 forceInlineOptional() {
   _forceInlineOptional();
diff --git a/tests/compiler/dart2js/inlining/data/force_inline_loops.dart b/tests/compiler/dart2js/inlining/data/force_inline_loops.dart
index 7927b0e..c9c09a7 100644
--- a/tests/compiler/dart2js/inlining/data/force_inline_loops.dart
+++ b/tests/compiler/dart2js/inlining/data/force_inline_loops.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   forceInlineLoops();
 }
@@ -10,7 +10,7 @@
 // Force inline a top level method with loops.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _forLoop:loop,[forceInlineLoops]*/
+/*member: _forLoop:loop,[forceInlineLoops]*/
 @pragma('dart2js:tryInline')
 _forLoop() {
   for (int i = 0; i < 10; i++) {
@@ -18,7 +18,7 @@
   }
 }
 
-/*element: _forInLoop:loop,[forceInlineLoops]*/
+/*member: _forInLoop:loop,[forceInlineLoops]*/
 @pragma('dart2js:tryInline')
 _forInLoop() {
   for (var e in [0, 1, 2]) {
@@ -26,7 +26,7 @@
   }
 }
 
-/*element: _whileLoop:loop,[forceInlineLoops]*/
+/*member: _whileLoop:loop,[forceInlineLoops]*/
 @pragma('dart2js:tryInline')
 _whileLoop() {
   int i = 0;
@@ -36,7 +36,7 @@
   }
 }
 
-/*element: _doLoop:loop,[forceInlineLoops]*/
+/*member: _doLoop:loop,[forceInlineLoops]*/
 @pragma('dart2js:tryInline')
 _doLoop() {
   int i = 0;
@@ -46,7 +46,7 @@
   } while (i < 10);
 }
 
-/*element: _hardLoop:loop,(allowLoops)code after return*/
+/*member: _hardLoop:loop,(allowLoops)code after return*/
 @pragma('dart2js:tryInline')
 _hardLoop() {
   for (int i = 0; i < 10; i++) {
@@ -56,7 +56,7 @@
   return 1;
 }
 
-/*element: forceInlineLoops:[]*/
+/*member: forceInlineLoops:[]*/
 @pragma('dart2js:noInline')
 forceInlineLoops() {
   _forLoop();
diff --git a/tests/compiler/dart2js/inlining/data/heuristics.dart b/tests/compiler/dart2js/inlining/data/heuristics.dart
index cd0bae7..d9f0c2c 100644
--- a/tests/compiler/dart2js/inlining/data/heuristics.dart
+++ b/tests/compiler/dart2js/inlining/data/heuristics.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   outsideLoopNoArgsCalledOnce();
   outsideLoopNoArgsCalledTwice();
@@ -19,10 +19,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method1:[outsideLoopNoArgsCalledOnce]*/
+/*member: _method1:[outsideLoopNoArgsCalledOnce]*/
 _method1() {}
 
-/*element: _outsideLoopNoArgsCalledOnce:[outsideLoopNoArgsCalledOnce]*/
+/*member: _outsideLoopNoArgsCalledOnce:[outsideLoopNoArgsCalledOnce]*/
 _outsideLoopNoArgsCalledOnce() {
   _method1();
   _method1();
@@ -32,7 +32,7 @@
   _method1();
 }
 
-/*element: outsideLoopNoArgsCalledOnce:[]*/
+/*member: outsideLoopNoArgsCalledOnce:[]*/
 @pragma('dart2js:noInline')
 outsideLoopNoArgsCalledOnce() {
   _outsideLoopNoArgsCalledOnce();
@@ -43,10 +43,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method2:[_outsideLoopNoArgs2,outsideLoopNoArgsCalledTwice]*/
+/*member: _method2:[_outsideLoopNoArgs2,outsideLoopNoArgsCalledTwice]*/
 _method2() {}
 
-/*element: _outsideLoopNoArgs1:[outsideLoopNoArgsCalledTwice]*/
+/*member: _outsideLoopNoArgs1:[outsideLoopNoArgsCalledTwice]*/
 _outsideLoopNoArgs1() {
   _method2();
   _method2();
@@ -54,7 +54,7 @@
   _method2();
 }
 
-/*element: _outsideLoopNoArgs2:[]*/
+/*member: _outsideLoopNoArgs2:[]*/
 _outsideLoopNoArgs2() {
   _method2();
   _method2();
@@ -64,7 +64,7 @@
   _method2();
 }
 
-/*element: outsideLoopNoArgsCalledTwice:[]*/
+/*member: outsideLoopNoArgsCalledTwice:[]*/
 @pragma('dart2js:noInline')
 outsideLoopNoArgsCalledTwice() {
   _outsideLoopNoArgs1();
@@ -78,10 +78,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method3:[outsideLoopOneArgCalledOnce]*/
+/*member: _method3:[outsideLoopOneArgCalledOnce]*/
 _method3() {}
 
-/*element: _outsideLoopOneArgCalledOnce:[outsideLoopOneArgCalledOnce]*/
+/*member: _outsideLoopOneArgCalledOnce:[outsideLoopOneArgCalledOnce]*/
 _outsideLoopOneArgCalledOnce(arg) {
   _method3();
   _method3();
@@ -102,7 +102,7 @@
   _method3();
 }
 
-/*element: outsideLoopOneArgCalledOnce:[]*/
+/*member: outsideLoopOneArgCalledOnce:[]*/
 @pragma('dart2js:noInline')
 outsideLoopOneArgCalledOnce() {
   _outsideLoopOneArgCalledOnce(0);
@@ -113,10 +113,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method4:[_outsideLoopOneArg2,outsideLoopOneArgCalledTwice]*/
+/*member: _method4:[_outsideLoopOneArg2,outsideLoopOneArgCalledTwice]*/
 _method4() {}
 
-/*element: _outsideLoopOneArg1:[outsideLoopOneArgCalledTwice]*/
+/*member: _outsideLoopOneArg1:[outsideLoopOneArgCalledTwice]*/
 _outsideLoopOneArg1(arg) {
   _method4();
   _method4();
@@ -126,7 +126,7 @@
   _method4();
 }
 
-/*element: _outsideLoopOneArg2:[]*/
+/*member: _outsideLoopOneArg2:[]*/
 _outsideLoopOneArg2(arg) {
   _method4();
   _method4();
@@ -138,7 +138,7 @@
   _method4();
 }
 
-/*element: outsideLoopOneArgCalledTwice:[]*/
+/*member: outsideLoopOneArgCalledTwice:[]*/
 @pragma('dart2js:noInline')
 outsideLoopOneArgCalledTwice() {
   _outsideLoopOneArg1(0);
@@ -152,10 +152,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method5:[insideLoopNoArgsCalledOnce]*/
+/*member: _method5:[insideLoopNoArgsCalledOnce]*/
 _method5() {}
 
-/*element: _insideLoopNoArgsCalledOnce:[insideLoopNoArgsCalledOnce]*/
+/*member: _insideLoopNoArgsCalledOnce:[insideLoopNoArgsCalledOnce]*/
 _insideLoopNoArgsCalledOnce() {
   _method5();
   _method5();
@@ -170,7 +170,7 @@
   _method5();
 }
 
-/*element: insideLoopNoArgsCalledOnce:loop*/
+/*member: insideLoopNoArgsCalledOnce:loop*/
 @pragma('dart2js:noInline')
 insideLoopNoArgsCalledOnce() {
   // ignore: UNUSED_LOCAL_VARIABLE
@@ -184,10 +184,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method6:[_insideLoopNoArgs2,insideLoopNoArgsCalledTwice]*/
+/*member: _method6:[_insideLoopNoArgs2,insideLoopNoArgsCalledTwice]*/
 _method6() {}
 
-/*element: _insideLoopNoArgs1:[insideLoopNoArgsCalledTwice]*/
+/*member: _insideLoopNoArgs1:[insideLoopNoArgsCalledTwice]*/
 _insideLoopNoArgs1() {
   _method6();
   _method6();
@@ -201,7 +201,7 @@
   _method6();
 }
 
-/*element: _insideLoopNoArgs2:[]*/
+/*member: _insideLoopNoArgs2:[]*/
 _insideLoopNoArgs2() {
   _method6();
   _method6();
@@ -219,7 +219,7 @@
   _method6();
 }
 
-/*element: insideLoopNoArgsCalledTwice:loop*/
+/*member: insideLoopNoArgsCalledTwice:loop*/
 @pragma('dart2js:noInline')
 insideLoopNoArgsCalledTwice() {
   // ignore: UNUSED_LOCAL_VARIABLE
@@ -236,10 +236,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method7:[insideLoopOneArgCalledOnce]*/
+/*member: _method7:[insideLoopOneArgCalledOnce]*/
 _method7() {}
 
-/*element: _insideLoopOneArgCalledOnce:[insideLoopOneArgCalledOnce]*/
+/*member: _insideLoopOneArgCalledOnce:[insideLoopOneArgCalledOnce]*/
 _insideLoopOneArgCalledOnce(arg) {
   _method7();
   _method7();
@@ -260,7 +260,7 @@
   _method7();
 }
 
-/*element: insideLoopOneArgCalledOnce:loop*/
+/*member: insideLoopOneArgCalledOnce:loop*/
 @pragma('dart2js:noInline')
 insideLoopOneArgCalledOnce() {
   for (var e in [1, 2, 3, 4]) {
@@ -273,10 +273,10 @@
 // static no-arg calls in its body.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _method8:[_insideLoopOneArg2,insideLoopOneArgCalledTwice]*/
+/*member: _method8:[_insideLoopOneArg2,insideLoopOneArgCalledTwice]*/
 _method8() {}
 
-/*element: _insideLoopOneArg1:[insideLoopOneArgCalledTwice]*/
+/*member: _insideLoopOneArg1:[insideLoopOneArgCalledTwice]*/
 _insideLoopOneArg1(arg) {
   _method8();
   _method8();
@@ -292,7 +292,7 @@
   _method8();
 }
 
-/*element: _insideLoopOneArg2:[]*/
+/*member: _insideLoopOneArg2:[]*/
 _insideLoopOneArg2(arg) {
   _method8();
   _method8();
@@ -310,7 +310,7 @@
   _method8();
 }
 
-/*element: insideLoopOneArgCalledTwice:loop*/
+/*member: insideLoopOneArgCalledTwice:loop*/
 @pragma('dart2js:noInline')
 insideLoopOneArgCalledTwice() {
   for (var e in [1, 2, 3, 4]) {
diff --git a/tests/compiler/dart2js/inlining/data/map.dart b/tests/compiler/dart2js/inlining/data/map.dart
index 1d4589e..9063caa 100644
--- a/tests/compiler/dart2js/inlining/data/map.dart
+++ b/tests/compiler/dart2js/inlining/data/map.dart
@@ -2,17 +2,17 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   passMapToNull();
 }
 
-/*element: _passMapToNull:[passMapToNull]*/
+/*member: _passMapToNull:[passMapToNull]*/
 _passMapToNull(f) {
   f({});
 }
 
-/*element: passMapToNull:[]*/
+/*member: passMapToNull:[]*/
 @pragma('dart2js:noInline')
 passMapToNull() {
   _passMapToNull(null);
diff --git a/tests/compiler/dart2js/inlining/data/meta.dart b/tests/compiler/dart2js/inlining/data/meta.dart
index 6dc7f22..fe47d1d 100644
--- a/tests/compiler/dart2js/inlining/data/meta.dart
+++ b/tests/compiler/dart2js/inlining/data/meta.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   tryInlineOnce();
   tryInlineTwice1();
@@ -13,11 +13,11 @@
 // Use `tryInline` to inline a top level method once.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryInlineOnce:[tryInlineOnce]*/
+/*member: _tryInlineOnce:[tryInlineOnce]*/
 @pragma('dart2js:tryInline')
 _tryInlineOnce() {}
 
-/*element: tryInlineOnce:[]*/
+/*member: tryInlineOnce:[]*/
 @pragma('dart2js:noInline')
 tryInlineOnce() {
   _tryInlineOnce();
@@ -27,17 +27,17 @@
 // Use `tryInline`to inline a top level method twice.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: _tryInlineTwice:[tryInlineTwice1,tryInlineTwice2]*/
+/*member: _tryInlineTwice:[tryInlineTwice1,tryInlineTwice2]*/
 @pragma('dart2js:tryInline')
 _tryInlineTwice() {}
 
-/*element: tryInlineTwice1:[]*/
+/*member: tryInlineTwice1:[]*/
 @pragma('dart2js:noInline')
 tryInlineTwice1() {
   _tryInlineTwice();
 }
 
-/*element: tryInlineTwice2:[]*/
+/*member: tryInlineTwice2:[]*/
 @pragma('dart2js:noInline')
 tryInlineTwice2() {
   _tryInlineTwice();
diff --git a/tests/compiler/dart2js/inlining/data/native.dart b/tests/compiler/dart2js/inlining/data/native.dart
index 6492328..8b4c1cff 100644
--- a/tests/compiler/dart2js/inlining/data/native.dart
+++ b/tests/compiler/dart2js/inlining/data/native.dart
@@ -4,7 +4,7 @@
 
 import 'dart:html';
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   document.createElement(CustomElement.tag);
   newCustom();
@@ -18,13 +18,13 @@
 // constructor isn't.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: newCustom:[]*/
+/*member: newCustom:[]*/
 @pragma('dart2js:noInline')
 newCustom() {
   new CustomElement();
 }
 
-/*element: newCustomCreated:[]*/
+/*member: newCustomCreated:[]*/
 @pragma('dart2js:noInline')
 newCustomCreated() {
   new CustomElement.created();
@@ -33,10 +33,10 @@
 class CustomElement extends HtmlElement {
   static final tag = 'x-foo';
 
-  /*element: CustomElement.:[newCustom:CustomElement]*/
+  /*member: CustomElement.:[newCustom:CustomElement]*/
   factory CustomElement() => new Element.tag(tag);
 
-  /*element: CustomElement.created:[]*/
+  /*member: CustomElement.created:[]*/
   CustomElement.created() : super.created() {
     print('boo');
   }
@@ -47,23 +47,23 @@
 // the generative constructor are inlined.
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: newNormal:[]*/
+/*member: newNormal:[]*/
 @pragma('dart2js:noInline')
 newNormal() {
   new NormalElement();
 }
 
-/*element: newNormalCreated:[]*/
+/*member: newNormalCreated:[]*/
 @pragma('dart2js:noInline')
 newNormalCreated() {
   new NormalElement.created();
 }
 
 class NormalElement {
-  /*element: NormalElement.:[newNormal:NormalElement]*/
+  /*member: NormalElement.:[newNormal:NormalElement]*/
   factory NormalElement() => null;
 
-  /*element: NormalElement.created:[newNormalCreated+,newNormalCreated:NormalElement]*/
+  /*member: NormalElement.created:[newNormalCreated+,newNormalCreated:NormalElement]*/
   NormalElement.created() {
     print('foo');
   }
diff --git a/tests/compiler/dart2js/inlining/data/nested.dart b/tests/compiler/dart2js/inlining/data/nested.dart
index e85ab5c..0c98ef2 100644
--- a/tests/compiler/dart2js/inlining/data/nested.dart
+++ b/tests/compiler/dart2js/inlining/data/nested.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   nestedGenericInlining();
   nestedGenericFactoryInlining();
@@ -13,11 +13,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class1<T> {
-  /*element: Class1.:[nestedGenericInlining:Class1<int>]*/
+  /*member: Class1.:[nestedGenericInlining:Class1<int>]*/
   @pragma('dart2js:tryInline')
   Class1();
 
-  /*element: Class1.method:[nestedGenericInlining]*/
+  /*member: Class1.method:[nestedGenericInlining]*/
   @pragma('dart2js:tryInline')
   method() {
     new Class2<List<T>>().method();
@@ -27,16 +27,16 @@
 class Class2<T> {
   // TODO(johnniwinther): Should the type have been Class<List<int>>?
   // Similarly below.
-  /*element: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
+  /*member: Class2.:[nestedGenericInlining:Class2<List<Class1.T>>]*/
   @pragma('dart2js:tryInline')
   Class2();
 
-  /*element: Class2.method:[nestedGenericInlining]*/
+  /*member: Class2.method:[nestedGenericInlining]*/
   @pragma('dart2js:tryInline')
   method() {}
 }
 
-/*element: nestedGenericInlining:[]*/
+/*member: nestedGenericInlining:[]*/
 @pragma('dart2js:noInline')
 nestedGenericInlining() {
   new Class1<int>().method();
@@ -47,11 +47,11 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 class Class3a<T> implements Class3b<T> {
-  /*element: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
+  /*member: Class3a.:[nestedGenericFactoryInlining:Class3a<int>]*/
   @pragma('dart2js:tryInline')
   Class3a();
 
-  /*element: Class3a.method:[nestedGenericFactoryInlining]*/
+  /*member: Class3a.method:[nestedGenericFactoryInlining]*/
   @pragma('dart2js:tryInline')
   method() {
     new Class4b<List<T>>().method();
@@ -59,7 +59,7 @@
 }
 
 abstract class Class3b<T> {
-  /*element: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
+  /*member: Class3b.:[nestedGenericFactoryInlining:Class3b<int>]*/
   @pragma('dart2js:tryInline')
   factory Class3b() => new Class3a<T>();
 
@@ -67,24 +67,24 @@
 }
 
 class Class4a<T> implements Class4b<T> {
-  /*element: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
+  /*member: Class4a.:[nestedGenericFactoryInlining:Class4a<Class4b.T>]*/
   @pragma('dart2js:tryInline')
   Class4a();
 
-  /*element: Class4a.method:[nestedGenericFactoryInlining]*/
+  /*member: Class4a.method:[nestedGenericFactoryInlining]*/
   @pragma('dart2js:tryInline')
   method() {}
 }
 
 abstract class Class4b<T> {
-  /*element: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
+  /*member: Class4b.:[nestedGenericFactoryInlining:Class4b<List<Class3a.T>>]*/
   @pragma('dart2js:tryInline')
   factory Class4b() => new Class4a<T>();
 
   method();
 }
 
-/*element: nestedGenericFactoryInlining:[]*/
+/*member: nestedGenericFactoryInlining:[]*/
 @pragma('dart2js:noInline')
 nestedGenericFactoryInlining() {
   new Class3b<int>().method();
diff --git a/tests/compiler/dart2js/inlining/data/setter.dart b/tests/compiler/dart2js/inlining/data/setter.dart
index 346568f..2c255fba 100644
--- a/tests/compiler/dart2js/inlining/data/setter.dart
+++ b/tests/compiler/dart2js/inlining/data/setter.dart
@@ -2,23 +2,23 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   inlineSetter();
 }
 
 class Class1 {
   var field;
-/*element: Class1.:[]*/
+/*member: Class1.:[]*/
   @pragma('dart2js:noInline')
   Class1();
-  /*element: Class1.setter=:[inlineSetter]*/
+  /*member: Class1.setter=:[inlineSetter]*/
   set setter(value) {
     field = value;
   }
 }
 
-/*element: inlineSetter:[]*/
+/*member: inlineSetter:[]*/
 @pragma('dart2js:noInline')
 inlineSetter() {
   Class1 c = new Class1();
diff --git a/tests/compiler/dart2js/inlining/data/static_initializer.dart b/tests/compiler/dart2js/inlining/data/static_initializer.dart
index 11838285..9c812c3 100644
--- a/tests/compiler/dart2js/inlining/data/static_initializer.dart
+++ b/tests/compiler/dart2js/inlining/data/static_initializer.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   _var1;
   _var2;
@@ -12,11 +12,11 @@
 var _var1 = <String>[_shortString(), _longStringMany()];
 var _var2 = <String>[_shortString(), _longStringMany(), _longStringOnce()];
 
-/*element: _shortString:[_var1,_var2]*/
+/*member: _shortString:[_var1,_var2]*/
 String _shortString() => r"""
 hello""";
 
-/*element: _longStringMany:[]*/
+/*member: _longStringMany:[]*/
 String _longStringMany() => r"""
 I wandered lonely as a cloud
 That floats on high o'er vales and hills,
@@ -26,7 +26,7 @@
 Fluttering and dancing in the breeze.
 """;
 
-/*element: _longStringOnce:[_var2]*/
+/*member: _longStringOnce:[_var2]*/
 String _longStringOnce() => r"""
 Continuous as the stars that shine
 And twinkle on the milky way,
@@ -38,13 +38,13 @@
 
 var _var3 = <int>[Foo().a, (Foo()..a).a];
 
-/*element: Foo.:[]*/
+/*member: Foo.:[]*/
 class Foo {
   int z = 99;
-  /*element: Foo.a:[_var3]*/
+  /*member: Foo.a:[_var3]*/
   get a => b;
-  /*element: Foo.b:[_var3]*/
+  /*member: Foo.b:[_var3]*/
   get b => c;
-  /*element: Foo.c:[]*/
+  /*member: Foo.c:[]*/
   get c => z++;
 }
diff --git a/tests/compiler/dart2js/inlining/data/switch.dart b/tests/compiler/dart2js/inlining/data/switch.dart
index cf9d938..37a0c3d 100644
--- a/tests/compiler/dart2js/inlining/data/switch.dart
+++ b/tests/compiler/dart2js/inlining/data/switch.dart
@@ -2,12 +2,12 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   switchThrowing();
 }
 
-/*element: switchThrowing:[]*/
+/*member: switchThrowing:[]*/
 @pragma('dart2js:noInline')
 switchThrowing() {
   switch (0) {
@@ -19,7 +19,7 @@
   }
 }
 
-/*element: _switchThrowing:[]*/
+/*member: _switchThrowing:[]*/
 _switchThrowing() {
   throw '';
 }
diff --git a/tests/compiler/dart2js/inlining/data/too_difficult.dart b/tests/compiler/dart2js/inlining/data/too_difficult.dart
index 4a0b262..b545095 100644
--- a/tests/compiler/dart2js/inlining/data/too_difficult.dart
+++ b/tests/compiler/dart2js/inlining/data/too_difficult.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   asyncMethod();
   asyncStarMethod();
@@ -27,7 +27,7 @@
   closureInInitializer();
 }
 
-/*element: _multipleReturns:code after return*/
+/*member: _multipleReturns:code after return*/
 _multipleReturns(c) {
   if (c)
     return;
@@ -35,27 +35,27 @@
     return;
 }
 
-/*element: multipleReturns:[]*/
+/*member: multipleReturns:[]*/
 @pragma('dart2js:noInline')
 multipleReturns() {
   _multipleReturns(true);
   _multipleReturns(false);
 }
 
-/*element: _codeAfterReturn:code after return*/
+/*member: _codeAfterReturn:code after return*/
 _codeAfterReturn(c) {
   if (c) return;
   print(c);
 }
 
-/*element: codeAfterReturn:[]*/
+/*member: codeAfterReturn:[]*/
 @pragma('dart2js:noInline')
 codeAfterReturn() {
   _codeAfterReturn(true);
   _codeAfterReturn(false);
 }
 
-/*element: _multipleThrows:[]*/
+/*member: _multipleThrows:[]*/
 _multipleThrows(c) {
   if (c)
     throw '';
@@ -63,14 +63,14 @@
     throw '';
 }
 
-/*element: multipleThrows:[]*/
+/*member: multipleThrows:[]*/
 @pragma('dart2js:noInline')
 multipleThrows() {
   _multipleThrows(true);
   _multipleThrows(false);
 }
 
-/*element: _returnAndThrow:code after return*/
+/*member: _returnAndThrow:code after return*/
 _returnAndThrow(c) {
   if (c)
     return;
@@ -78,65 +78,65 @@
     throw '';
 }
 
-/*element: returnAndThrow:[]*/
+/*member: returnAndThrow:[]*/
 @pragma('dart2js:noInline')
 returnAndThrow() {
   _returnAndThrow(true);
   _returnAndThrow(false);
 }
 
-/*element: asyncMethod:async/await*/
+/*member: asyncMethod:async/await*/
 asyncMethod() async {}
 
-/*element: asyncStarMethod:async/await*/
+/*member: asyncStarMethod:async/await*/
 asyncStarMethod() async* {}
 
-/*element: syncStarMethod:async/await*/
+/*member: syncStarMethod:async/await*/
 syncStarMethod() sync* {}
 
-/*element: localFunction:closure*/
+/*member: localFunction:closure*/
 localFunction() {
   // ignore: UNUSED_ELEMENT
   /*[]*/ local() {}
 }
 
-/*element: anonymousFunction:closure*/
+/*member: anonymousFunction:closure*/
 anonymousFunction() {
   /*[]*/ () {};
 }
 
-/*element: tryCatch:try*/
+/*member: tryCatch:try*/
 tryCatch() {
   try {} catch (e) {}
 }
 
-/*element: tryFinally:try*/
+/*member: tryFinally:try*/
 tryFinally() {
   try {} finally {}
 }
 
-/*element: tryWithRethrow:try*/
+/*member: tryWithRethrow:try*/
 tryWithRethrow() {
   try {} catch (e) {
     rethrow;
   }
 }
 
-/*element: forLoop:loop*/
+/*member: forLoop:loop*/
 forLoop() {
   for (int i = 0; i < 10; i++) {
     print(i);
   }
 }
 
-/*element: forInLoop:loop*/
+/*member: forInLoop:loop*/
 forInLoop() {
   for (var e in [0, 1, 2]) {
     print(e);
   }
 }
 
-/*element: whileLoop:loop*/
+/*member: whileLoop:loop*/
 whileLoop() {
   int i = 0;
   while (i < 10) {
@@ -145,7 +145,7 @@
   }
 }
 
-/*element: doLoop:loop*/
+/*member: doLoop:loop*/
 doLoop() {
   int i = 0;
   do {
@@ -154,12 +154,12 @@
   } while (i < 10);
 }
 
-/*element: returnClosure:closure*/
+/*member: returnClosure:closure*/
 returnClosure() {
   return /*[]*/ () {};
 }
 
-/*element: throwClosure:closure*/
+/*member: throwClosure:closure*/
 throwClosure() {
   throw /*[]*/ () {};
 }
@@ -167,13 +167,13 @@
 class Class1 {
   var f;
 
-  /*element: Class1.:closure*/
+  /*member: Class1.:closure*/
   Class1() : f = (/*[]*/ () {}) {
     print(f);
   }
 }
 
-/*element: closureInInitializer:[]*/
+/*member: closureInInitializer:[]*/
 @pragma('dart2js:noInline')
 closureInInitializer() {
   new Class1();
diff --git a/tests/compiler/dart2js/inlining/data/type_variables.dart b/tests/compiler/dart2js/inlining/data/type_variables.dart
index 4641443..93c0c21 100644
--- a/tests/compiler/dart2js/inlining/data/type_variables.dart
+++ b/tests/compiler/dart2js/inlining/data/type_variables.dart
@@ -2,23 +2,23 @@
 // 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.
 
-/*element: main:[]*/
+/*member: main:[]*/
 main() {
   inlineTypeTests();
 }
 
-/*element: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
+/*member: Mixin1.:[inlineTypeTests:Mixin1<int>]*/
 class Mixin1<S> {
   var field = /*[]*/ (S s) => null;
 }
 
-/*element: Class1.:[inlineTypeTests:Class1<int>]*/
+/*member: Class1.:[inlineTypeTests:Class1<int>]*/
 class Class1<T> extends Object with Mixin1<T> {}
 
-/*element: _inlineTypeTests:[inlineTypeTests]*/
+/*member: _inlineTypeTests:[inlineTypeTests]*/
 _inlineTypeTests(o) => o.field is dynamic Function(int);
 
-/*element: inlineTypeTests:[]*/
+/*member: inlineTypeTests:[]*/
 @pragma('dart2js:noInline')
 void inlineTypeTests() {
   _inlineTypeTests(new Mixin1<int>());
diff --git a/tests/compiler/dart2js/jumps/jump_test.dart b/tests/compiler/dart2js/jumps/jump_test.dart
index 5ea39a1..04d8988 100644
--- a/tests/compiler/dart2js/jumps/jump_test.dart
+++ b/tests/compiler/dart2js/jumps/jump_test.dart
@@ -102,7 +102,8 @@
         needsComma = true;
       }
       String value = sb.toString();
-      registerValue(data.sourceSpan, data.id, value, target);
+      registerValue(
+          data.sourceSpan.uri, data.sourceSpan.begin, data.id, value, target);
     });
     gotos.forEach((GotoData data) {
       StringBuffer sb = new StringBuffer();
@@ -111,7 +112,8 @@
       assert(targetData != null, "No TargetData for ${data.target}");
       sb.write(targetData.index);
       String value = sb.toString();
-      registerValue(data.sourceSpan, data.id, value, data);
+      registerValue(
+          data.sourceSpan.uri, data.sourceSpan.begin, data.id, value, data);
     });
   }
 
diff --git a/tests/compiler/dart2js/member_usage/data/constant_folding.dart b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
index 0225146..195684c 100644
--- a/tests/compiler/dart2js/member_usage/data/constant_folding.dart
+++ b/tests/compiler/dart2js/member_usage/data/constant_folding.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 void main() {
   const BitNot(42, 4294967253).check();
   const BitNot(4294967253, 42).check();
@@ -17,7 +17,7 @@
   const BitNot(0x12121212121212, 0xEDEDEDED).check();
 }
 
-/*element: jsEquals:invoke*/
+/*member: jsEquals:invoke*/
 void jsEquals(expected, actual, [String reason = null]) {
   if (expected is num && actual is num) {
     if (expected.isNaN && actual.isNaN) return;
@@ -36,16 +36,16 @@
 }
 
 abstract class TestOp {
-  /*element: TestOp.expected:init,read*/
+  /*member: TestOp.expected:init,read*/
   final expected;
 
-  /*element: TestOp.result:init,read*/
+  /*member: TestOp.result:init,read*/
   final result;
 
-  /*strong.element: TestOp.:invoke*/
+  /*strong.member: TestOp.:invoke*/
   const TestOp(this.expected, this.result);
 
-  /*element: TestOp.checkAll:invoke*/
+  /*member: TestOp.checkAll:invoke*/
   @pragma('dart2js:noInline')
   checkAll(evalResult) {
     jsEquals(expected, result,
@@ -59,17 +59,17 @@
 }
 
 class BitNot extends TestOp {
-  /*element: BitNot.arg:init,read*/
+  /*member: BitNot.arg:init,read*/
   final arg;
 
-  /*strong.element: BitNot.:invoke*/
+  /*strong.member: BitNot.:invoke*/
   const BitNot(this.arg, expected) : super(expected, ~arg);
 
-  /*element: BitNot.check:invoke*/
+  /*member: BitNot.check:invoke*/
   @pragma('dart2js:tryInline')
   check() => checkAll(eval());
 
-  /*element: BitNot.eval:invoke*/
+  /*member: BitNot.eval:invoke*/
   @override
   @pragma('dart2js:tryInline')
   eval() => ~arg;
diff --git a/tests/compiler/dart2js/member_usage/data/constructors.dart b/tests/compiler/dart2js/member_usage/data/constructors.dart
index c53d93c..39d4566 100644
--- a/tests/compiler/dart2js/member_usage/data/constructors.dart
+++ b/tests/compiler/dart2js/member_usage/data/constructors.dart
@@ -3,73 +3,73 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Class {
-  /*element: Class.constructor1:invoke*/
+  /*member: Class.constructor1:invoke*/
   Class.constructor1() {}
 
-  /*element: Class.constructor2a:invoke=(0)*/
+  /*member: Class.constructor2a:invoke=(0)*/
   Class.constructor2a([a]) {}
 
-  /*element: Class.constructor2b:invoke*/
+  /*member: Class.constructor2b:invoke*/
   Class.constructor2b([a]) {}
 
-  /*element: Class.constructor2c:invoke*/
+  /*member: Class.constructor2c:invoke*/
   Class.constructor2c([a]) {}
 
-  /*element: Class.constructor3a:invoke=(0)*/
+  /*member: Class.constructor3a:invoke=(0)*/
   Class.constructor3a([a, b]) {}
 
-  /*element: Class.constructor3b:invoke=(1)*/
+  /*member: Class.constructor3b:invoke=(1)*/
   Class.constructor3b([a, b]) {}
 
-  /*element: Class.constructor3c:invoke*/
+  /*member: Class.constructor3c:invoke*/
   Class.constructor3c([a, b]) {}
 
-  /*element: Class.constructor4a:invoke=(0)*/
+  /*member: Class.constructor4a:invoke=(0)*/
   Class.constructor4a({a}) {}
 
-  /*element: Class.constructor4b:invoke*/
+  /*member: Class.constructor4b:invoke*/
   Class.constructor4b({a}) {}
 
-  /*element: Class.constructor4c:invoke*/
+  /*member: Class.constructor4c:invoke*/
   Class.constructor4c({a}) {}
 
-  /*element: Class.constructor5a:invoke=(0)*/
+  /*member: Class.constructor5a:invoke=(0)*/
   Class.constructor5a({a, b}) {}
 
-  /*element: Class.constructor5b:invoke=(0,a)*/
+  /*member: Class.constructor5b:invoke=(0,a)*/
   Class.constructor5b({a, b}) {}
 
-  /*element: Class.constructor5c:invoke=(0,b)*/
+  /*member: Class.constructor5c:invoke=(0,b)*/
   Class.constructor5c({a, b}) {}
 
-  /*element: Class.constructor6a:invoke=(1)*/
+  /*member: Class.constructor6a:invoke=(1)*/
   Class.constructor6a(a, [b, c]) {}
 
-  /*element: Class.constructor6b:invoke=(2)*/
+  /*member: Class.constructor6b:invoke=(2)*/
   Class.constructor6b(a, [b, c]) {}
 
-  /*element: Class.constructor6c:invoke*/
+  /*member: Class.constructor6c:invoke*/
   Class.constructor6c(a, [b, c]) {}
 
-  /*element: Class.constructor7a:invoke=(1)*/
+  /*member: Class.constructor7a:invoke=(1)*/
   Class.constructor7a(a, {b, c}) {}
 
-  /*element: Class.constructor7b:invoke=(1,b)*/
+  /*member: Class.constructor7b:invoke=(1,b)*/
   Class.constructor7b(a, {b, c}) {}
 
-  /*element: Class.constructor7c:invoke=(1,c)*/
+  /*member: Class.constructor7c:invoke=(1,c)*/
   Class.constructor7c(a, {b, c}) {}
 
-  /*element: Class.constructor8a:invoke=(0)*/
+  /*member: Class.constructor8a:invoke=(0)*/
   @pragma('dart2js:noElision')
   Class.constructor8a([a, b]) {}
 
-  /*element: Class.constructor8b:invoke=(0)*/
+  /*member: Class.constructor8b:invoke=(0)*/
   @pragma('dart2js:noElision')
   Class.constructor8b({a, b}) {}
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   new Class.constructor1();
 
diff --git a/tests/compiler/dart2js/member_usage/data/fields.dart b/tests/compiler/dart2js/member_usage/data/fields.dart
index 6b40661..9bdacad 100644
--- a/tests/compiler/dart2js/member_usage/data/fields.dart
+++ b/tests/compiler/dart2js/member_usage/data/fields.dart
@@ -2,89 +2,89 @@
 // 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.
 
-/*element: field1a:init,read*/
+/*member: field1a:init,read*/
 var field1a;
 
-/*element: field1b:init,write*/
+/*member: field1b:init,write*/
 var field1b;
 
-/*element: field1c:init,read,write*/
+/*member: field1c:init,read,write*/
 var field1c;
 
 // Invocations of static/top level fields are converted into 'field1d.call(...)`
 // so we don't have an invocation of the field but instead an additional dynamic
 // call to 'call'.
-/*element: field1d:init,read*/
+/*member: field1d:init,read*/
 var field1d;
 
-/*element: field2a:read*/
+/*member: field2a:read*/
 get field2a => 42;
 
 set field2a(_) {}
 
 get field2b => 42;
 
-/*element: field2b=:write*/
+/*member: field2b=:write*/
 set field2b(_) {}
 
-/*element: field2c:read*/
+/*member: field2c:read*/
 get field2c => 42;
 
-/*element: field2c=:write*/
+/*member: field2c=:write*/
 set field2c(_) {}
 
 // Invocations of static/top level getters are converted into
 // 'field2d.call(...)` so we don't have an invocation of the field but instead
 // an additional dynamic call to 'call'.
-/*element: field2d:read*/
+/*member: field2d:read*/
 get field2d => 42;
 
 set field2d(_) {}
 
 class Class {
-  /*element: Class.field1a:init,read*/
+  /*member: Class.field1a:init,read*/
   var field1a;
 
-  /*element: Class.field1b:init,write*/
+  /*member: Class.field1b:init,write*/
   var field1b;
 
-  /*element: Class.field1c:init,read,write*/
+  /*member: Class.field1c:init,read,write*/
   var field1c;
 
-  /*element: Class.field1d:init,invoke,read=static*/
+  /*member: Class.field1d:init,invoke,read=static*/
   var field1d;
 
-  /*element: Class.field2a:read*/
+  /*member: Class.field2a:read*/
   get field2a => 42;
 
   set field2a(_) {}
 
   get field2b => 42;
 
-  /*element: Class.field2b=:write*/
+  /*member: Class.field2b=:write*/
   set field2b(_) {}
 
-  /*element: Class.field2c:read*/
+  /*member: Class.field2c:read*/
   get field2c => 42;
 
-  /*element: Class.field2c=:write*/
+  /*member: Class.field2c=:write*/
   set field2c(_) {}
 
-  /*element: Class.field2d:invoke,read=static*/
+  /*member: Class.field2d:invoke,read=static*/
   get field2d => null;
 
   set field2d(_) {}
 
-  /*element: Class.field3a:init*/
+  /*member: Class.field3a:init*/
   var field3a = 0;
 
-  /*element: Class.field3b:init*/
+  /*member: Class.field3b:init*/
   var field3b;
 
-  /*element: Class.:invoke=(0)*/
+  /*member: Class.:invoke=(0)*/
   Class([this.field3b]);
 
-  /*element: Class.test:invoke*/
+  /*member: Class.test:invoke*/
   test() {
     field1a;
     field1b = 42;
@@ -98,7 +98,7 @@
   }
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   field1a;
   field1b = 42;
diff --git a/tests/compiler/dart2js/member_usage/data/general.dart b/tests/compiler/dart2js/member_usage/data/general.dart
index 9954b67..8e86d99 100644
--- a/tests/compiler/dart2js/member_usage/data/general.dart
+++ b/tests/compiler/dart2js/member_usage/data/general.dart
@@ -2,49 +2,49 @@
 // 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.
 
-/*element: A.:invoke*/
+/*member: A.:invoke*/
 class A {
-  /*element: A.method1:invoke*/
+  /*member: A.method1:invoke*/
   method1() {}
 
   method2() {}
 
-  /*element: A.method4:invoke*/
+  /*member: A.method4:invoke*/
   method4() {}
 
-  /*element: A.getter:read*/
+  /*member: A.getter:read*/
   get getter => 42;
 
   set setter(_) {}
 }
 
-/*element: B.:invoke*/
+/*member: B.:invoke*/
 class B {
   method1() {}
   method2() {}
 
-  /*element: B.method5:invoke*/
+  /*member: B.method5:invoke*/
   method5() {}
   get getter => 42;
 
-  /*element: B.setter=:write*/
+  /*member: B.setter=:write*/
   set setter(_) {}
 }
 
-/*element: C.:invoke*/
+/*member: C.:invoke*/
 class C extends A {
-  /*element: C.method1:invoke*/
+  /*member: C.method1:invoke*/
   @override
   method1() {}
 
-  /*element: B.method2:invoke*/
+  /*member: B.method2:invoke*/
   @override
   method2() {}
 
   @override
   method4() {}
 
-  /*element: C.getter:read*/
+  /*member: C.getter:read*/
   @override
   get getter => 42;
 
@@ -52,12 +52,12 @@
   set setter(_) {}
 }
 
-/*element: D.:invoke*/
+/*member: D.:invoke*/
 class D implements B {
   @override
   method1() {}
 
-  /*element: D.method2:invoke*/
+  /*member: D.method2:invoke*/
   @override
   method2() {}
 
@@ -67,7 +67,7 @@
   @override
   get getter => 42;
 
-  /*element: D.setter=:write*/
+  /*member: D.setter=:write*/
   @override
   set setter(_) {}
 }
@@ -107,40 +107,40 @@
 }
 
 class G {
-  /*element: G.method1:invoke*/
+  /*member: G.method1:invoke*/
   method1() {}
   method2() {}
   method4() {}
 
-  /*element: G.getter:read*/
+  /*member: G.getter:read*/
   get getter => 42;
   set setter(_) {}
 }
 
-/*element: H.:invoke*/
+/*member: H.:invoke*/
 class H extends Object with G implements A {}
 
-/*element: I.:invoke*/
+/*member: I.:invoke*/
 class I {
-  /*element: I.method1:invoke*/
+  /*member: I.method1:invoke*/
   method1() {}
   method2() {}
   method4() {}
 
-  /*element: I.getter:read*/
+  /*member: I.getter:read*/
   get getter => 42;
   set setter(_) {}
 }
 
-/*element: J.:invoke*/
+/*member: J.:invoke*/
 class J extends I implements A {}
 
 class K {
-  /*element: K.method1:invoke*/
+  /*member: K.method1:invoke*/
   method1() {}
   method2() {}
 
-  /*element: K.getter:read*/
+  /*member: K.getter:read*/
   get getter => 42;
   set setter(_) {}
 }
@@ -148,13 +148,13 @@
 class L = Object with K;
 class L2 = Object with L;
 
-/*element: M.:invoke*/
+/*member: M.:invoke*/
 class M extends L {}
 
-/*element: M2.:invoke*/
+/*member: M2.:invoke*/
 class M2 extends L2 {}
 
-/*element: N.:invoke*/
+/*member: N.:invoke*/
 class N {
   method1() {}
   get getter => 42;
@@ -163,54 +163,54 @@
 
 abstract class O extends N {}
 
-/*element: P.:invoke*/
+/*member: P.:invoke*/
 class P implements O {
-  /*element: P.method1:invoke*/
+  /*member: P.method1:invoke*/
   @override
   method1() {}
 
-  /*element: P.getter:read*/
+  /*member: P.getter:read*/
   @override
   get getter => 42;
 
-  /*element: P.setter=:write*/
+  /*member: P.setter=:write*/
   @override
   set setter(_) {}
 }
 
-/*element: Q.:invoke*/
+/*member: Q.:invoke*/
 class Q {
-  /*element: Q.method3:invoke*/
+  /*member: Q.method3:invoke*/
   method3() {}
 }
 
-/*element: R.:invoke*/
+/*member: R.:invoke*/
 class R extends Q {}
 
-/*element: Class1a.:invoke*/
+/*member: Class1a.:invoke*/
 class Class1a {
-  /*element: Class1a.call:invoke*/
+  /*member: Class1a.call:invoke*/
   call(a, b, c) {} // Call structure only used in Class1a and Class2b.
 }
 
-/*element: Class1b.:invoke*/
+/*member: Class1b.:invoke*/
 class Class1b {
   call(a, b, c) {}
 }
 
-/*element: Class2.:invoke*/
+/*member: Class2.:invoke*/
 class Class2 {
-  /*element: Class2.c:init,invoke,read=static*/
+  /*member: Class2.c:init,invoke,read=static*/
   Class1a c;
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   method1();
   method2();
 }
 
-/*element: method1:invoke*/
+/*member: method1:invoke*/
 @pragma('dart2js:disableFinal')
 method1() {
   A a = new A();
@@ -238,7 +238,7 @@
   new Class2().c(0, 1, 2);
 }
 
-/*element: method2:invoke*/
+/*member: method2:invoke*/
 method2() {
   A a = new A();
   B b = new B();
diff --git a/tests/compiler/dart2js/member_usage/data/generic.dart b/tests/compiler/dart2js/member_usage/data/generic.dart
index 9cf10de..7ae48a3 100644
--- a/tests/compiler/dart2js/member_usage/data/generic.dart
+++ b/tests/compiler/dart2js/member_usage/data/generic.dart
@@ -2,29 +2,29 @@
 // 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.
 
-/*element: Class.:invoke*/
+/*member: Class.:invoke*/
 class Class {
   // The type parameter is never provided but needed nonetheless.
-  /*element: Class.method1:invoke=(0)*/
+  /*member: Class.method1:invoke=(0)*/
   method1<S>([a]) => S;
 
-  /*element: Class.method2:invoke=<1>(0)*/
+  /*member: Class.method2:invoke=<1>(0)*/
   method2<S>([a]) => S;
 
-  /*element: Class.method3:invoke=<1>(0)*/
+  /*member: Class.method3:invoke=<1>(0)*/
   method3<S>([a]) => S;
 
-  /*element: Class.method4:invoke=(1)*/
+  /*member: Class.method4:invoke=(1)*/
   method4<S>([a]) => S;
 
-  /*element: Class.method5:invoke*/
+  /*member: Class.method5:invoke*/
   method5<S>([a]) => S;
 
-  /*element: Class.method6:invoke*/
+  /*member: Class.method6:invoke*/
   method6<S>([a]) => S;
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   dynamic c = new Class();
   c.method1();
diff --git a/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
index 44aa24e..0e9ad65 100644
--- a/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
+++ b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
@@ -2,98 +2,98 @@
 // 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.
 
-/*element: Class.:invoke*/
+/*member: Class.:invoke*/
 class Class {
-  /*element: Class.method1:invoke*/
+  /*member: Class.method1:invoke*/
   method1() {}
 
-  /*element: Class.method2a:invoke=(0)*/
+  /*member: Class.method2a:invoke=(0)*/
   method2a([a]) {}
 
-  /*element: Class.method2b:invoke*/
+  /*member: Class.method2b:invoke*/
   method2b([a]) {}
 
-  /*element: Class.method2c:invoke*/
+  /*member: Class.method2c:invoke*/
   method2c([a]) {}
 
-  /*element: Class.method2d:invoke,read*/
+  /*member: Class.method2d:invoke,read*/
   method2d([a]) {}
 
-  /*element: Class.method3a:invoke=(0)*/
+  /*member: Class.method3a:invoke=(0)*/
   method3a([a, b]) {}
 
-  /*element: Class.method3b:invoke=(1)*/
+  /*member: Class.method3b:invoke=(1)*/
   method3b([a, b]) {}
 
-  /*element: Class.method3c:invoke*/
+  /*member: Class.method3c:invoke*/
   method3c([a, b]) {}
 
-  /*element: Class.method3d:invoke,read*/
+  /*member: Class.method3d:invoke,read*/
   method3d([a, b]) {}
 
-  /*element: Class.method4a:invoke=(0)*/
+  /*member: Class.method4a:invoke=(0)*/
   method4a({a}) {}
 
-  /*element: Class.method4b:invoke*/
+  /*member: Class.method4b:invoke*/
   method4b({a}) {}
 
-  /*element: Class.method4c:invoke*/
+  /*member: Class.method4c:invoke*/
   method4c({a}) {}
 
-  /*element: Class.method4d:invoke,read*/
+  /*member: Class.method4d:invoke,read*/
   method4d({a}) {}
 
-  /*element: Class.method5a:invoke=(0)*/
+  /*member: Class.method5a:invoke=(0)*/
   method5a({a, b}) {}
 
-  /*element: Class.method5b:invoke=(0,a)*/
+  /*member: Class.method5b:invoke=(0,a)*/
   method5b({a, b}) {}
 
-  /*element: Class.method5c:invoke=(0,b)*/
+  /*member: Class.method5c:invoke=(0,b)*/
   method5c({a, b}) {}
 
-  /*element: Class.method5d:invoke,read*/
+  /*member: Class.method5d:invoke,read*/
   method5d({a, b}) {}
 
-  /*element: Class.method6a:invoke*/
+  /*member: Class.method6a:invoke*/
   method6a<T>() {}
 
-  /*element: Class.method6b:invoke,read*/
+  /*member: Class.method6b:invoke,read*/
   method6b<T>() {}
 
-  /*element: Class.method7a:invoke=(1)*/
+  /*member: Class.method7a:invoke=(1)*/
   method7a(a, [b, c]) {}
 
-  /*element: Class.method7b:invoke=(2)*/
+  /*member: Class.method7b:invoke=(2)*/
   method7b(a, [b, c]) {}
 
-  /*element: Class.method7c:invoke*/
+  /*member: Class.method7c:invoke*/
   method7c(a, [b, c]) {}
 
-  /*element: Class.method7d:invoke,read*/
+  /*member: Class.method7d:invoke,read*/
   method7d(a, [b, c]) {}
 
-  /*element: Class.method8a:invoke=(1)*/
+  /*member: Class.method8a:invoke=(1)*/
   method8a(a, {b, c}) {}
 
-  /*element: Class.method8b:invoke=(1,b)*/
+  /*member: Class.method8b:invoke=(1,b)*/
   method8b(a, {b, c}) {}
 
-  /*element: Class.method8c:invoke=(1,c)*/
+  /*member: Class.method8c:invoke=(1,c)*/
   method8c(a, {b, c}) {}
 
-  /*element: Class.method8d:invoke,read*/
+  /*member: Class.method8d:invoke,read*/
   method8d(a, {b, c}) {}
 
-  /*element: Class.method9a:invoke=(0)*/
+  /*member: Class.method9a:invoke=(0)*/
   @pragma('dart2js:noElision')
   method9a([a, b]) {}
 
-  /*element: Class.method9b:invoke=(0)*/
+  /*member: Class.method9b:invoke=(0)*/
   @pragma('dart2js:noElision')
   method9b({a, b}) {}
 
-  /*element: Class.test:invoke*/
+  /*member: Class.test:invoke*/
   test() {
     method1();
 
@@ -139,7 +139,7 @@
   }
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   new Class().test();
 }
diff --git a/tests/compiler/dart2js/member_usage/data/native.dart b/tests/compiler/dart2js/member_usage/data/native.dart
index a787af4..691562b 100644
--- a/tests/compiler/dart2js/member_usage/data/native.dart
+++ b/tests/compiler/dart2js/member_usage/data/native.dart
@@ -5,7 +5,7 @@
 // ignore: import_internal_library
 import 'dart:_js_helper';
 
-/*element: field2a:read*/
+/*member: field2a:read*/
 @JSName('field2a')
 get field2a => 42;
 
@@ -15,54 +15,54 @@
 @JSName('field2b')
 get field2b => 42;
 
-/*element: field2b=:write*/
+/*member: field2b=:write*/
 @JSName('field2b')
 set field2b(_) {}
 
-/*element: field2c:read*/
+/*member: field2c:read*/
 @JSName('field2c')
 get field2c => 42;
 
-/*element: field2c=:write*/
+/*member: field2c=:write*/
 @JSName('field2c')
 set field2c(_) {}
 
 @Native('Class')
 class Class {
-  /*element: Class.field1a:read*/
+  /*member: Class.field1a:read*/
   var field1a;
 
-  /*element: Class.field1b:write*/
+  /*member: Class.field1b:write*/
   var field1b;
 
-  /*element: Class.field1c:read,write*/
+  /*member: Class.field1c:read,write*/
   var field1c;
 
-  /*element: Class.field2a:read*/
+  /*member: Class.field2a:read*/
   get field2a => 42;
 
   set field2a(_) {}
 
   get field2b => 42;
 
-  /*element: Class.field2b=:write*/
+  /*member: Class.field2b=:write*/
   set field2b(_) {}
 
-  /*element: Class.field2c:read*/
+  /*member: Class.field2c:read*/
   get field2c => 42;
 
-  /*element: Class.field2c=:write*/
+  /*member: Class.field2c=:write*/
   set field2c(_) {}
 
   var field3a = 0;
 
-  /*element: Class.field3b:init*/
+  /*member: Class.field3b:init*/
   var field3b;
 
-  /*element: Class.:invoke=(0)*/
+  /*member: Class.:invoke=(0)*/
   Class([this.field3b]);
 
-  /*element: Class.test:invoke*/
+  /*member: Class.test:invoke*/
   test() {
     field1a;
     field1b = 42;
@@ -74,7 +74,7 @@
   }
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   field2a;
   field2b = 42;
diff --git a/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
index 936c819..5548810 100644
--- a/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
+++ b/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
@@ -2,96 +2,96 @@
 // 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.
 
-/*element: method1:invoke*/
+/*member: method1:invoke*/
 method1() {}
 
-/*element: method2a:invoke=(0)*/
+/*member: method2a:invoke=(0)*/
 method2a([a]) {}
 
-/*element: method2b:invoke*/
+/*member: method2b:invoke*/
 method2b([a]) {}
 
-/*element: method2c:invoke*/
+/*member: method2c:invoke*/
 method2c([a]) {}
 
-/*element: method2d:invoke,read*/
+/*member: method2d:invoke,read*/
 method2d([a]) {}
 
-/*element: method3a:invoke=(0)*/
+/*member: method3a:invoke=(0)*/
 method3a([a, b]) {}
 
-/*element: method3b:invoke=(1)*/
+/*member: method3b:invoke=(1)*/
 method3b([a, b]) {}
 
-/*element: method3c:invoke*/
+/*member: method3c:invoke*/
 method3c([a, b]) {}
 
-/*element: method3d:invoke,read*/
+/*member: method3d:invoke,read*/
 method3d([a, b]) {}
 
-/*element: method4a:invoke=(0)*/
+/*member: method4a:invoke=(0)*/
 method4a({a}) {}
 
-/*element: method4b:invoke*/
+/*member: method4b:invoke*/
 method4b({a}) {}
 
-/*element: method4c:invoke*/
+/*member: method4c:invoke*/
 method4c({a}) {}
 
-/*element: method4d:invoke,read*/
+/*member: method4d:invoke,read*/
 method4d({a}) {}
 
-/*element: method5a:invoke=(0)*/
+/*member: method5a:invoke=(0)*/
 method5a({a, b}) {}
 
-/*element: method5b:invoke=(0,a)*/
+/*member: method5b:invoke=(0,a)*/
 method5b({a, b}) {}
 
-/*element: method5c:invoke=(0,b)*/
+/*member: method5c:invoke=(0,b)*/
 method5c({a, b}) {}
 
-/*element: method5d:invoke,read*/
+/*member: method5d:invoke,read*/
 method5d({a, b}) {}
 
-/*element: method6a:invoke*/
+/*member: method6a:invoke*/
 method6a<T>() {}
 
-/*element: method6b:invoke,read*/
+/*member: method6b:invoke,read*/
 method6b<T>() {}
 
-/*element: method7a:invoke=(1)*/
+/*member: method7a:invoke=(1)*/
 method7a(a, [b, c]) {}
 
-/*element: method7b:invoke=(2)*/
+/*member: method7b:invoke=(2)*/
 method7b(a, [b, c]) {}
 
-/*element: method7c:invoke*/
+/*member: method7c:invoke*/
 method7c(a, [b, c]) {}
 
-/*element: method7d:invoke,read*/
+/*member: method7d:invoke,read*/
 method7d(a, [b, c]) {}
 
-/*element: method8a:invoke=(1)*/
+/*member: method8a:invoke=(1)*/
 method8a(a, {b, c}) {}
 
-/*element: method8b:invoke=(1,b)*/
+/*member: method8b:invoke=(1,b)*/
 method8b(a, {b, c}) {}
 
-/*element: method8c:invoke=(1,c)*/
+/*member: method8c:invoke=(1,c)*/
 method8c(a, {b, c}) {}
 
-/*element: method8d:invoke,read*/
+/*member: method8d:invoke,read*/
 method8d(a, {b, c}) {}
 
-/*element: method9a:invoke=(0)*/
+/*member: method9a:invoke=(0)*/
 @pragma('dart2js:noElision')
 method9a([a, b]) {}
 
-/*element: method9b:invoke=(0)*/
+/*member: method9b:invoke=(0)*/
 @pragma('dart2js:noElision')
 method9b({a, b}) {}
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 main() {
   method1();
 
diff --git a/tests/compiler/dart2js/member_usage/data/super.dart b/tests/compiler/dart2js/member_usage/data/super.dart
index 5b3b775..50e3547 100644
--- a/tests/compiler/dart2js/member_usage/data/super.dart
+++ b/tests/compiler/dart2js/member_usage/data/super.dart
@@ -3,108 +3,108 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class Super {
-  /*element: Super.field1:init,read=super*/
+  /*member: Super.field1:init,read=super*/
   var field1;
 
-  /*element: Super.field2:init,write=super*/
+  /*member: Super.field2:init,write=super*/
   var field2;
 
-  /*element: Super.field3:init,read=super*/
+  /*member: Super.field3:init,read=super*/
   var field3;
 
-  /*element: Super.field4:init,read=super*/
+  /*member: Super.field4:init,read=super*/
   final field4;
 
-  /*element: Super.field5:init,read=super*/
+  /*member: Super.field5:init,read=super*/
   final field5;
 
-  /*element: Super.constructor1:invoke*/
+  /*member: Super.constructor1:invoke*/
   Super.constructor1(this.field4, this.field5);
 
-  /*element: Super.constructor2:invoke=(0)*/
+  /*member: Super.constructor2:invoke=(0)*/
   Super.constructor2([this.field4, this.field5]);
 
-  /*element: Super.constructor3:invoke=(1)*/
+  /*member: Super.constructor3:invoke=(1)*/
   Super.constructor3([this.field4, this.field5]);
 
-  /*element: Super.method1:invoke=(1):super*/
+  /*member: Super.method1:invoke=(1):super*/
   method1([a, b]) {}
 
-  /*element: Super.method2:invoke,read=super*/
+  /*member: Super.method2:invoke,read=super*/
   method2([a, b]) {}
 
-  /*element: Super.getter1:read=super*/
+  /*member: Super.getter1:read=super*/
   get getter1 => null;
 
-  /*element: Super.getter2:read=super*/
+  /*member: Super.getter2:read=super*/
   get getter2 => null;
 
-  /*element: Super.setter1=:write=super*/
+  /*member: Super.setter1=:write=super*/
   set setter1(_) {}
 
-  /*element: Super.call:invoke=(0,a,b,c)*/
+  /*member: Super.call:invoke=(0,a,b,c)*/
   void call({a, b, c, d}) {}
 }
 
 class Sub extends Super {
-  /*element: Sub.constructor1:invoke=(1)*/
+  /*member: Sub.constructor1:invoke=(1)*/
   Sub.constructor1([field4, field5]) : super.constructor1(field4, field5);
 
-  /*element: Sub.constructor2:invoke*/
+  /*member: Sub.constructor2:invoke*/
   Sub.constructor2() : super.constructor2();
 
-  /*element: Sub.readSuperField:invoke*/
+  /*member: Sub.readSuperField:invoke*/
   readSuperField() {
     return super.field1;
   }
 
-  /*element: Sub.writeSuperField:invoke*/
+  /*member: Sub.writeSuperField:invoke*/
   writeSuperField() {
     super.field2 = null;
   }
 
-  /*element: Sub.invokeSuperField:invoke*/
+  /*member: Sub.invokeSuperField:invoke*/
   invokeSuperField() {
     super.field3(a: 0);
   }
 
-  /*element: Sub.readSuperFinalField:invoke*/
+  /*member: Sub.readSuperFinalField:invoke*/
   readSuperFinalField() {
     return super.field4;
   }
 
-  /*element: Sub.invokeSuperFinalField:invoke*/
+  /*member: Sub.invokeSuperFinalField:invoke*/
   invokeSuperFinalField() {
     super.field5(b: 0);
   }
 
-  /*element: Sub.invokeSuperMethod:invoke*/
+  /*member: Sub.invokeSuperMethod:invoke*/
   invokeSuperMethod() {
     super.method1(0);
   }
 
-  /*element: Sub.readSuperMethod:invoke*/
+  /*member: Sub.readSuperMethod:invoke*/
   readSuperMethod() {
     return super.method2;
   }
 
-  /*element: Sub.readSuperGetter:invoke*/
+  /*member: Sub.readSuperGetter:invoke*/
   readSuperGetter() {
     return super.getter1;
   }
 
-  /*element: Sub.invokeSuperGetter:invoke*/
+  /*member: Sub.invokeSuperGetter:invoke*/
   invokeSuperGetter() {
     return super.getter2(c: 0);
   }
 
-  /*element: Sub.writeSuperSetter:invoke*/
+  /*member: Sub.writeSuperSetter:invoke*/
   writeSuperSetter() {
     super.setter1 = null;
   }
 }
 
-/*element: main:invoke*/
+/*member: main:invoke*/
 void main() {
   new Super.constructor3(null);
   new Sub.constructor1(null);
diff --git a/tests/compiler/dart2js/member_usage/member_usage_test.dart b/tests/compiler/dart2js/member_usage/member_usage_test.dart
index 1a5dd51..fdccf53 100644
--- a/tests/compiler/dart2js/member_usage/member_usage_test.dart
+++ b/tests/compiler/dart2js/member_usage/member_usage_test.dart
@@ -7,7 +7,6 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/enqueue.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/universe/member_usage.dart';
 import 'package:compiler/src/universe/resolution_world_builder.dart';
@@ -108,8 +107,9 @@
       }
     }
     Id id = computeEntityId(node);
-    actualMap[id] = new ActualData<Features>(
-        id, features, computeSourceSpanFromTreeNode(node), member);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    actualMap[id] = new ActualData<Features>(id, features,
+        nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset, member);
   }
 
   @override
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
index 1ed2501..8eb6746 100644
--- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -493,7 +493,47 @@
         'const C2<A>(id)',
         'ConstructedConstant(C2<A>(a='
             'InstantiationConstant([A],FunctionConstant(id))))'),
-  ])
+  ]),
+  const TestData('unused-arguments', '''
+class A {
+  const A();
+
+  A operator -() => this;
+}
+class B implements A {
+  const B();
+
+  B operator -() => this;
+}
+class C implements A {
+  const C();
+
+  C operator -() => this;
+}
+class Class<T extends A> {
+  const Class(T t);
+  const Class.redirect(dynamic t) : this(t);
+  const Class.method(T t) : this(-t);
+}
+class Subclass<T extends A> extends Class<T> {
+  const Subclass(dynamic t) : super(t);
+}
+''', const <ConstantData>[
+    const ConstantData(
+        'const Class<A>(const A())', 'ConstructedConstant(Class<A>())'),
+    const ConstantData('const Class<B>.redirect(const B())',
+        'ConstructedConstant(Class<B>())'),
+    const ConstantData('const Class<B>.redirect(const C())', 'NonConstant',
+        expectedErrors: 'ConstEvalInvalidType'),
+    const ConstantData('const Class<A>.method(const A())', 'NonConstant',
+        expectedErrors: 'ConstEvalInvalidMethodInvocation'),
+    const ConstantData(
+        'const Subclass<A>(const A())', 'ConstructedConstant(Subclass<A>())'),
+    const ConstantData(
+        'const Subclass<B>(const B())', 'ConstructedConstant(Subclass<B>())'),
+    const ConstantData('const Subclass<B>(const C())', 'NonConstant',
+        expectedErrors: 'ConstEvalInvalidType'),
+  ]),
 ];
 
 main(List<String> args) {
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic.dart b/tests/compiler/dart2js/optimization/data/arithmetic.dart
index 3ec5b39..cd984e6 100644
--- a/tests/compiler/dart2js/optimization/data/arithmetic.dart
+++ b/tests/compiler/dart2js/optimization/data/arithmetic.dart
@@ -118,25 +118,25 @@
 // Negation
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: negate:Specializer=[Negate],PrimitiveCheck=[]*/
+/*member: negate:Specializer=[Negate],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 negate(o) {
   return -o;
 }
 
-/*element: negateNum:Specializer=[Negate],PrimitiveCheck=[]*/
+/*member: negateNum:Specializer=[Negate],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 negateNum(o) {
   return -o;
 }
 
-/*element: negateNull:Specializer=[Negate],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: negateNull:Specializer=[Negate],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 negateNull(o) {
   return -o;
 }
 
-/*element: negateString:Specializer=[!Negate]*/
+/*member: negateString:Specializer=[!Negate]*/
 @pragma('dart2js:noInline')
 negateString(o) {
   return -o;
@@ -146,49 +146,49 @@
 // Addition
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: add:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: add:Specializer=[Add],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 add(a, b) {
   return a + b;
 }
 
-/*element: addNumInt:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addNumInt:Specializer=[Add],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 addNumInt(a, b) {
   return a + b;
 }
 
-/*element: addIntNum:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addIntNum:Specializer=[Add],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 addIntNum(a, b) {
   return a + b;
 }
 
-/*element: addNumNum:Specializer=[Add],PrimitiveCheck=[]*/
+/*member: addNumNum:Specializer=[Add],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 addNumNum(a, b) {
   return a + b;
 }
 
-/*element: addNullInt:Specializer=[Add],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: addNullInt:Specializer=[Add],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 addNullInt(a, b) {
   return a + b;
 }
 
-/*element: addIntNull:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: addIntNull:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 addIntNull(a, b) {
   return a + b;
 }
 
-/*element: addStringInt:Specializer=[!Add]*/
+/*member: addStringInt:Specializer=[!Add]*/
 @pragma('dart2js:noInline')
 addStringInt(a, b) {
   return a + b;
 }
 
-/*element: addIntString:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: addIntString:Specializer=[Add],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 addIntString(a, b) {
   return a + b;
@@ -198,49 +198,49 @@
 // Subtraction
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: subtract:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtract:Specializer=[Subtract],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 subtract(a, b) {
   return a - b;
 }
 
-/*element: subtractNumInt:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractNumInt:Specializer=[Subtract],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 subtractNumInt(a, b) {
   return a - b;
 }
 
-/*element: subtractIntNum:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractIntNum:Specializer=[Subtract],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 subtractIntNum(a, b) {
   return a - b;
 }
 
-/*element: subtractNumNum:Specializer=[Subtract],PrimitiveCheck=[]*/
+/*member: subtractNumNum:Specializer=[Subtract],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 subtractNumNum(a, b) {
   return a - b;
 }
 
-/*element: subtractNullInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: subtractNullInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 subtractNullInt(a, b) {
   return a - b;
 }
 
-/*element: subtractIntNull:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: subtractIntNull:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 subtractIntNull(a, b) {
   return a - b;
 }
 
-/*element: subtractStringInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: subtractStringInt:Specializer=[Subtract],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 subtractStringInt(a, b) {
   return a - b;
 }
 
-/*element: subtractIntString:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: subtractIntString:Specializer=[Subtract],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 subtractIntString(a, b) {
   return a - b;
@@ -250,49 +250,49 @@
 // Multiplication
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: multiply:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiply:Specializer=[Multiply],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 multiply(a, b) {
   return a * b;
 }
 
-/*element: multiplyNumInt:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyNumInt:Specializer=[Multiply],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 multiplyNumInt(a, b) {
   return a * b;
 }
 
-/*element: multiplyIntNum:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyIntNum:Specializer=[Multiply],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 multiplyIntNum(a, b) {
   return a * b;
 }
 
-/*element: multiplyNumNum:Specializer=[Multiply],PrimitiveCheck=[]*/
+/*member: multiplyNumNum:Specializer=[Multiply],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 multiplyNumNum(a, b) {
   return a * b;
 }
 
-/*element: multiplyNullInt:Specializer=[Multiply],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: multiplyNullInt:Specializer=[Multiply],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 multiplyNullInt(a, b) {
   return a * b;
 }
 
-/*element: multiplyIntNull:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: multiplyIntNull:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 multiplyIntNull(a, b) {
   return a * b;
 }
 
-/*element: multiplyStringInt:Specializer=[!Multiply]*/
+/*member: multiplyStringInt:Specializer=[!Multiply]*/
 @pragma('dart2js:noInline')
 multiplyStringInt(a, b) {
   return a * b;
 }
 
-/*element: multiplyIntString:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: multiplyIntString:Specializer=[Multiply],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 multiplyIntString(a, b) {
   return a * b;
@@ -302,55 +302,55 @@
 // Division
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: divide:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divide:Specializer=[Divide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 divide(a, b) {
   return a / b;
 }
 
-/*element: divideZero:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideZero:Specializer=[Divide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 divideZero(a) {
   return a / 0;
 }
 
-/*element: divideNumInt:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideNumInt:Specializer=[Divide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 divideNumInt(a, b) {
   return a / b;
 }
 
-/*element: divideIntNum:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideIntNum:Specializer=[Divide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 divideIntNum(a, b) {
   return a / b;
 }
 
-/*element: divideNumNum:Specializer=[Divide],PrimitiveCheck=[]*/
+/*member: divideNumNum:Specializer=[Divide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 divideNumNum(a, b) {
   return a / b;
 }
 
-/*element: divideNullInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: divideNullInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 divideNullInt(a, b) {
   return a / b;
 }
 
-/*element: divideIntNull:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: divideIntNull:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 divideIntNull(a, b) {
   return a / b;
 }
 
-/*element: divideStringInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: divideStringInt:Specializer=[Divide],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 divideStringInt(a, b) {
   return a / b;
 }
 
-/*element: divideIntString:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: divideIntString:Specializer=[Divide],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 divideIntString(a, b) {
   return a / b;
@@ -360,73 +360,73 @@
 // Truncating division
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: truncatingDivide:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivide:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 truncatingDivide(a, b) {
   return a ~/ 2;
 }
 
-/*element: truncatingDivideZero:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideZero:Specializer=[!TruncatingDivide]*/
 @pragma('dart2js:noInline')
 truncatingDivideZero(a) {
   return a ~/ 0;
 }
 
-/*element: truncatingDivideIntNonZero1:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivideIntNonZero1:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 truncatingDivideIntNonZero1(a) {
   return a ~/ 1;
 }
 
-/*element: truncatingDivideIntNonZero2:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
+/*member: truncatingDivideIntNonZero2:Specializer=[TruncatingDivide],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 truncatingDivideIntNonZero2(a) {
   return a ~/ 2;
 }
 
-/*element: truncatingDivideNumInt:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideNumInt:Specializer=[!TruncatingDivide]*/
 @pragma('dart2js:noInline')
 truncatingDivideNumInt(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideNumNonZero:Specializer=[TruncatingDivide._tdivFast],PrimitiveCheck=[]*/
+/*member: truncatingDivideNumNonZero:Specializer=[TruncatingDivide._tdivFast],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 truncatingDivideNumNonZero(a) {
   return a ~/ 2;
 }
 
-/*element: truncatingDivideIntNum:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideIntNum:Specializer=[!TruncatingDivide]*/
 @pragma('dart2js:noInline')
 truncatingDivideIntNum(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideNumNum:Specializer=[!TruncatingDivide]*/
+/*member: truncatingDivideNumNum:Specializer=[!TruncatingDivide]*/
 @pragma('dart2js:noInline')
 truncatingDivideNumNum(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideNullInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: truncatingDivideNullInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 truncatingDivideNullInt(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideIntNull:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: truncatingDivideIntNull:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 truncatingDivideIntNull(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideStringInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: truncatingDivideStringInt:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 truncatingDivideStringInt(a, b) {
   return a ~/ b;
 }
 
-/*element: truncatingDivideIntString:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: truncatingDivideIntString:Specializer=[!TruncatingDivide],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 truncatingDivideIntString(a, b) {
   return a ~/ b;
@@ -436,25 +436,25 @@
 // .abs()
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: abs:Specializer=[Abs]*/
+/*member: abs:Specializer=[Abs]*/
 @pragma('dart2js:noInline')
 abs(o) {
   return o.abs();
 }
 
-/*element: absNum:Specializer=[Abs]*/
+/*member: absNum:Specializer=[Abs]*/
 @pragma('dart2js:noInline')
 absNum(o) {
   return o.abs();
 }
 
-/*element: absNull:Specializer=[Abs]*/
+/*member: absNull:Specializer=[Abs]*/
 @pragma('dart2js:noInline')
 absNull(o) {
   return o.abs();
 }
 
-/*element: absString:Specializer=[!Abs]*/
+/*member: absString:Specializer=[!Abs]*/
 @pragma('dart2js:noInline')
 absString(o) {
   return o.abs();
@@ -464,25 +464,25 @@
 // .round()
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: round:Specializer=[Round]*/
+/*member: round:Specializer=[Round]*/
 @pragma('dart2js:noInline')
 round(o) {
   return o.round();
 }
 
-/*element: roundNum:Specializer=[Round]*/
+/*member: roundNum:Specializer=[Round]*/
 @pragma('dart2js:noInline')
 roundNum(o) {
   return o.round();
 }
 
-/*element: roundNull:Specializer=[Round]*/
+/*member: roundNull:Specializer=[Round]*/
 @pragma('dart2js:noInline')
 roundNull(o) {
   return o.round();
 }
 
-/*element: roundString:Specializer=[!Round]*/
+/*member: roundString:Specializer=[!Round]*/
 @pragma('dart2js:noInline')
 roundString(o) {
   return o.round();
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
index 6d5ccef..dad0dcc 100644
--- a/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
+++ b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
@@ -8,56 +8,56 @@
 @pragma('dart2js:noInline')
 int confuse(int x) => x;
 
-/*element: intPlusZero:Specializer=[Add,BitAnd]*/
+/*member: intPlusZero:Specializer=[Add,BitAnd]*/
 @pragma('dart2js:noInline')
 intPlusZero() {
   int x = confuse(0);
   return (x & 1) + 0;
 }
 
-/*element: zeroPlusInt:Specializer=[Add,BitAnd]*/
+/*member: zeroPlusInt:Specializer=[Add,BitAnd]*/
 @pragma('dart2js:noInline')
 zeroPlusInt() {
   int x = confuse(0);
   return 0 + (x & 1);
 }
 
-/*element: numPlusZero:Specializer=[Add]*/
+/*member: numPlusZero:Specializer=[Add]*/
 @pragma('dart2js:noInline')
 numPlusZero() {
   num x = confuse(0);
   return x + 0;
 }
 
-/*element: zeroPlusNum:Specializer=[Add]*/
+/*member: zeroPlusNum:Specializer=[Add]*/
 @pragma('dart2js:noInline')
 zeroPlusNum() {
   num x = confuse(0);
   return 0 + x;
 }
 
-/*element: intTimesOne:Specializer=[BitAnd,Multiply]*/
+/*member: intTimesOne:Specializer=[BitAnd,Multiply]*/
 @pragma('dart2js:noInline')
 intTimesOne() {
   int x = confuse(0);
   return (x & 1) * 1;
 }
 
-/*element: oneTimesInt:Specializer=[BitAnd,Multiply]*/
+/*member: oneTimesInt:Specializer=[BitAnd,Multiply]*/
 @pragma('dart2js:noInline')
 oneTimesInt() {
   int x = confuse(0);
   return 1 * (x & 1);
 }
 
-/*element: numTimesOne:Specializer=[Multiply]*/
+/*member: numTimesOne:Specializer=[Multiply]*/
 @pragma('dart2js:noInline')
 numTimesOne() {
   num x = confuse(0);
   return x * 1;
 }
 
-/*element: oneTimesNum:Specializer=[Multiply]*/
+/*member: oneTimesNum:Specializer=[Multiply]*/
 @pragma('dart2js:noInline')
 oneTimesNum() {
   num x = confuse(0);
diff --git a/tests/compiler/dart2js/optimization/data/bit.dart b/tests/compiler/dart2js/optimization/data/bit.dart
index 543a87d..49364cf 100644
--- a/tests/compiler/dart2js/optimization/data/bit.dart
+++ b/tests/compiler/dart2js/optimization/data/bit.dart
@@ -64,25 +64,25 @@
 // Bitwise not
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: bitNot:Specializer=[BitNot]*/
+/*member: bitNot:Specializer=[BitNot]*/
 @pragma('dart2js:noInline')
 bitNot(o) {
   return ~o;
 }
 
-/*element: bitNotNum:Specializer=[BitNot]*/
+/*member: bitNotNum:Specializer=[BitNot]*/
 @pragma('dart2js:noInline')
 bitNotNum(o) {
   return ~o;
 }
 
-/*element: bitNotNull:Specializer=[BitNot]*/
+/*member: bitNotNull:Specializer=[BitNot]*/
 @pragma('dart2js:noInline')
 bitNotNull(o) {
   return ~o;
 }
 
-/*element: bitNotString:Specializer=[!BitNot]*/
+/*member: bitNotString:Specializer=[!BitNot]*/
 @pragma('dart2js:noInline')
 bitNotString(o) {
   return ~o;
@@ -92,49 +92,49 @@
 // Bitwise and
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: bitAnd:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAnd:Specializer=[BitAnd],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitAnd(a, b) {
   return a & b;
 }
 
-/*element: bitAndNumInt:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndNumInt:Specializer=[BitAnd],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitAndNumInt(a, b) {
   return a & b;
 }
 
-/*element: bitAndIntNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndIntNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitAndIntNum(a, b) {
   return a & b;
 }
 
-/*element: bitAndNumNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
+/*member: bitAndNumNum:Specializer=[BitAnd],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitAndNumNum(a, b) {
   return a & b;
 }
 
-/*element: bitAndNullInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitAndNullInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitAndNullInt(a, b) {
   return a & b;
 }
 
-/*element: bitAndIntNull:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitAndIntNull:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitAndIntNull(a, b) {
   return a & b;
 }
 
-/*element: bitAndStringInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitAndStringInt:Specializer=[BitAnd],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitAndStringInt(a, b) {
   return a & b;
 }
 
-/*element: bitAndIntString:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitAndIntString:Specializer=[BitAnd],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitAndIntString(a, b) {
   return a & b;
@@ -144,49 +144,49 @@
 // Bitwise or
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: bitOr:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOr:Specializer=[BitOr],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitOr(a, b) {
   return a | b;
 }
 
-/*element: bitOrNumInt:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrNumInt:Specializer=[BitOr],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitOrNumInt(a, b) {
   return a | b;
 }
 
-/*element: bitOrIntNum:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrIntNum:Specializer=[BitOr],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitOrIntNum(a, b) {
   return a | b;
 }
 
-/*element: bitOrNumNum:Specializer=[BitOr],PrimitiveCheck=[]*/
+/*member: bitOrNumNum:Specializer=[BitOr],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitOrNumNum(a, b) {
   return a | b;
 }
 
-/*element: bitOrNullInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitOrNullInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitOrNullInt(a, b) {
   return a | b;
 }
 
-/*element: bitOrIntNull:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitOrIntNull:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitOrIntNull(a, b) {
   return a | b;
 }
 
-/*element: bitOrStringInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitOrStringInt:Specializer=[BitOr],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitOrStringInt(a, b) {
   return a | b;
 }
 
-/*element: bitOrIntString:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitOrIntString:Specializer=[BitOr],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitOrIntString(a, b) {
   return a | b;
@@ -196,49 +196,49 @@
 // Bitwise xor
 ////////////////////////////////////////////////////////////////////////////////
 
-/*element: bitXor:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXor:Specializer=[BitXor],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitXor(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorNumInt:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorNumInt:Specializer=[BitXor],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitXorNumInt(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorIntNum:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorIntNum:Specializer=[BitXor],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitXorIntNum(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorNumNum:Specializer=[BitXor],PrimitiveCheck=[]*/
+/*member: bitXorNumNum:Specializer=[BitXor],PrimitiveCheck=[]*/
 @pragma('dart2js:noInline')
 bitXorNumNum(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorNullInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitXorNullInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitXorNullInt(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorIntNull:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitXorIntNull:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitXorIntNull(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorStringInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
+/*member: bitXorStringInt:Specializer=[BitXor],PrimitiveCheck=[kind=receiver&type=num]*/
 @pragma('dart2js:noInline')
 bitXorStringInt(a, b) {
   return a ^ b;
 }
 
-/*element: bitXorIntString:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
+/*member: bitXorIntString:Specializer=[BitXor],PrimitiveCheck=[kind=argument&type=num]*/
 @pragma('dart2js:noInline')
 bitXorIntString(a, b) {
   return a ^ b;
diff --git a/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart b/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
index 70578fc..fc11e74 100644
--- a/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
+++ b/tests/compiler/dart2js/optimization/data/effectively_constant_fields.dart
@@ -13,7 +13,7 @@
   var field3 = 0;
 }
 
-/*element: method1:
+/*member: method1:
  ConstantFieldGet=[name=Class1.field1&value=IntConstant(0)],
  FieldGet=[]
 */
@@ -22,7 +22,7 @@
   return c.field1;
 }
 
-/*element: method2:FieldGet=[name=Class1.field2]*/
+/*member: method2:FieldGet=[name=Class1.field2]*/
 @pragma('dart2js:noInline')
 method2(Class1 c) {
   return c.field2;
@@ -43,7 +43,7 @@
   int Function() field4 = _field4;
 }
 
-/*element: method4:
+/*member: method4:
  ConstantFieldCall=[name=Class3.field4&value=FunctionConstant(_field4)],
  FieldCall=[]
 */
@@ -52,7 +52,7 @@
   return c.field4();
 }
 
-/*element: method6:
+/*member: method6:
  ConstantFieldGet=[name=Class1.field1&value=IntConstant(0)],
  FieldGet=[name=<null-guard>]
 */
@@ -61,7 +61,7 @@
   return c.field1;
 }
 
-/*element: method7:
+/*member: method7:
  ConstantFieldCall=[name=Class3.field4&value=FunctionConstant(_field4)],
  FieldCall=[name=<null-guard>]
 */
diff --git a/tests/compiler/dart2js/optimization/data/field_get.dart b/tests/compiler/dart2js/optimization/data/field_get.dart
index e9101e5..301efeb 100644
--- a/tests/compiler/dart2js/optimization/data/field_get.dart
+++ b/tests/compiler/dart2js/optimization/data/field_get.dart
@@ -18,7 +18,7 @@
   int field1;
 }
 
-/*element: method1:FieldGet=[name=Class1a.field1]*/
+/*member: method1:FieldGet=[name=Class1a.field1]*/
 @pragma('dart2js:noInline')
 method1(Class1a c) {
   return c.field1;
@@ -31,7 +31,7 @@
 
 class Class2b extends Class2a {}
 
-/*element: method2:FieldGet=[name=Class2a.field2]*/
+/*member: method2:FieldGet=[name=Class2a.field2]*/
 @pragma('dart2js:noInline')
 method2(Class2a c) {
   return c.field2;
@@ -69,7 +69,7 @@
   int Function() field5;
 }
 
-/*element: method5:FieldCall=[name=Class5a.field5]*/
+/*member: method5:FieldCall=[name=Class5a.field5]*/
 @pragma('dart2js:noInline')
 method5(Class5a c) {
   return c.field5();
diff --git a/tests/compiler/dart2js/optimization/data/field_set.dart b/tests/compiler/dart2js/optimization/data/field_set.dart
index 3c19021..a7e1cbb 100644
--- a/tests/compiler/dart2js/optimization/data/field_set.dart
+++ b/tests/compiler/dart2js/optimization/data/field_set.dart
@@ -20,7 +20,7 @@
   int field1;
 }
 
-/*element: method1:FieldSet=[name=Class1a.field1]*/
+/*member: method1:FieldSet=[name=Class1a.field1]*/
 @pragma('dart2js:noInline')
 method1(Class1a c) {
   c.field1 = 42;
@@ -33,7 +33,7 @@
 
 class Class2b extends Class2a {}
 
-/*element: method2:FieldSet=[name=Class2a.field2]*/
+/*member: method2:FieldSet=[name=Class2a.field2]*/
 @pragma('dart2js:noInline')
 method2(Class2a c) {
   c.field2 = 42;
@@ -70,7 +70,7 @@
   int field5;
 }
 
-/*element: method5:FieldSet=[removed=field5]*/
+/*member: method5:FieldSet=[removed=field5]*/
 @pragma('dart2js:noInline')
 method5(Class5a c) {
   c.field5 = 42;
@@ -82,7 +82,7 @@
 
 class Class6b extends Class6a {}
 
-/*element: method6:FieldSet=[removed=field6]*/
+/*member: method6:FieldSet=[removed=field6]*/
 @pragma('dart2js:noInline')
 method6(Class6a c) {
   c.field6 = 42;
diff --git a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
index 6411114..9b64132 100644
--- a/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
+++ b/tests/compiler/dart2js/optimization/data/finalized_type_variable.dart
@@ -11,7 +11,7 @@
 }
 
 class ViewCardComponent extends AppView<CardComponent> {
-  /*element: ViewCardComponent.method1:
+  /*member: ViewCardComponent.method1:
    FieldGet=[name=AppView.ctx],
    FieldSet=[name=CardComponent.title]
   */
@@ -20,7 +20,7 @@
     ctx.title = value;
   }
 
-  /*element: ViewCardComponent.method2:
+  /*member: ViewCardComponent.method2:
    FieldGet=[name=AppView.ctx,name=CardComponent.title]
   */
   @pragma('dart2js:noInline')
@@ -34,7 +34,7 @@
 }
 
 class ViewCardComponent2 extends AppView<CardComponent2> {
-  /*element: ViewCardComponent2.method1:
+  /*member: ViewCardComponent2.method1:
    FieldGet=[name=AppView.ctx],
    FieldSet=[name=CardComponent2.title]
   */
@@ -43,7 +43,7 @@
     ctx.title = value;
   }
 
-  /*element: ViewCardComponent2.method2:
+  /*member: ViewCardComponent2.method2:
    FieldGet=[name=AppView.ctx,name=CardComponent2.title]
   */
   @pragma('dart2js:noInline')
@@ -52,8 +52,8 @@
   }
 }
 
-/*strong.element: main:*/
-/*omit.element: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
+/*strong.member: main:*/
+/*omit.member: main:FieldSet=[name=AppView.ctx,name=AppView.ctx]*/
 main() {
   var c1 = new ViewCardComponent();
   c1.ctx = new CardComponent();
diff --git a/tests/compiler/dart2js/optimization/data/index.dart b/tests/compiler/dart2js/optimization/data/index.dart
index b6dd480..a38b22c 100644
--- a/tests/compiler/dart2js/optimization/data/index.dart
+++ b/tests/compiler/dart2js/optimization/data/index.dart
@@ -4,41 +4,41 @@
 
 import 'dart:collection';
 
-/*element: dynamicIndex:Specializer=[!Index]*/
+/*member: dynamicIndex:Specializer=[!Index]*/
 @pragma('dart2js:noInline')
 dynamicIndex(var list) {
   return list[0]; // This not known to be an indexable primitive.
 }
 
-/*element: unknownListIndex:Specializer=[!Index]*/
+/*member: unknownListIndex:Specializer=[!Index]*/
 @pragma('dart2js:noInline')
 unknownListIndex(List list) {
   return list[0]; // This not known to be an indexable primitive.
 }
 
-/*element: possiblyNullMutableListIndex:Specializer=[Index]*/
+/*member: possiblyNullMutableListIndex:Specializer=[Index]*/
 @pragma('dart2js:noInline')
 possiblyNullMutableListIndex(bool b) {
   var list = b ? [0] : null;
   return list[0];
 }
 
-/*element: mutableListIndex:Specializer=[Index]*/
+/*member: mutableListIndex:Specializer=[Index]*/
 @pragma('dart2js:noInline')
 mutableListIndex() {
   var list = [0];
   return list[0];
 }
 
-/*element: mutableListDynamicIndex:Specializer=[Index]*/
+/*member: mutableListDynamicIndex:Specializer=[Index]*/
 @pragma('dart2js:noInline')
 mutableListDynamicIndex(dynamic index) {
   var list = [0];
   return list[index]; // CFE inserts an implicit cast of the index.
 }
 
-/*strong.element: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
-/*omit.element: mutableDynamicListDynamicIndex:Specializer=[Index]*/
+/*strong.member: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
+/*omit.member: mutableDynamicListDynamicIndex:Specializer=[Index]*/
 @pragma('dart2js:noInline')
 @pragma('dart2js:disableFinal')
 mutableDynamicListDynamicIndex(dynamic index) {
diff --git a/tests/compiler/dart2js/optimization/data/index_assign.dart b/tests/compiler/dart2js/optimization/data/index_assign.dart
index 35c03ff..d2ac26d 100644
--- a/tests/compiler/dart2js/optimization/data/index_assign.dart
+++ b/tests/compiler/dart2js/optimization/data/index_assign.dart
@@ -2,52 +2,52 @@
 // 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.
 
-/*element: dynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*member: dynamicIndexAssign:Specializer=[!IndexAssign]*/
 @pragma('dart2js:noInline')
 dynamicIndexAssign(var list) {
   list[0] = 1;
 }
 
-/*strong.element: unknownListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: unknownListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: unknownListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: unknownListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 unknownListIndexAssign(List list) {
   list[0] = 1;
 }
 
-/*strong.element: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 possiblyNullMutableListIndexAssign(bool b) {
   var list = b ? [0] : null;
   list[0] = 1;
 }
 
-/*strong.element: mutableListIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListIndexAssign() {
   var list = [0];
   list[0] = 1;
 }
 
-/*strong.element: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListDynamicIndexAssign(dynamic index) {
   var list = [0];
   list[index] = 1;
 }
 
-/*strong.element: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
-/*omit.element: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
+/*strong.member: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.member: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
 @pragma('dart2js:noInline')
 mutableListDynamicValueIndexAssign(dynamic value) {
   var list = [0];
   list[0] = value;
 }
 
-/*element: immutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*member: immutableListIndexAssign:Specializer=[!IndexAssign]*/
 @pragma('dart2js:noInline')
 immutableListIndexAssign() {
   var list = const [0];
diff --git a/tests/compiler/dart2js/optimization/data/modulo_remainder.dart b/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
index 9139d26..d2d909cc 100644
--- a/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
+++ b/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: mod1:Specializer=[Modulo]*/
+/*member: mod1:Specializer=[Modulo]*/
 @pragma('dart2js:noInline')
 mod1(param) {
   var a = param ? 0xFFFFFFFF : 1;
@@ -11,7 +11,7 @@
   // absent: '$mod'
 }
 
-/*element: mod2:Specializer=[!Modulo]*/
+/*member: mod2:Specializer=[!Modulo]*/
 @pragma('dart2js:noInline')
 mod2(param) {
   var a = param ? 0xFFFFFFFF : -0.0;
@@ -21,7 +21,7 @@
   // absent: ' % 2'
 }
 
-/*element: mod3:Specializer=[Modulo]*/
+/*member: mod3:Specializer=[Modulo]*/
 @pragma('dart2js:noInline')
 mod3(param) {
   var a = param ? 0xFFFFFFFF : -0.0;
@@ -31,7 +31,7 @@
   // absent: '$mod'
 }
 
-/*element: rem1:Specializer=[Remainder]*/
+/*member: rem1:Specializer=[Remainder]*/
 @pragma('dart2js:noInline')
 rem1(param) {
   var a = param ? 0xFFFFFFFF : 1;
@@ -41,7 +41,7 @@
   // absent: 'remainder'
 }
 
-/*element: rem2:Specializer=[Remainder]*/
+/*member: rem2:Specializer=[Remainder]*/
 @pragma('dart2js:noInline')
 rem2(param) {
   var a = param ? 123.4 : -1;
@@ -51,7 +51,7 @@
   // absent: 'remainder'
 }
 
-/*element: rem3:Specializer=[!Remainder]*/
+/*member: rem3:Specializer=[!Remainder]*/
 @pragma('dart2js:noInline')
 rem3(param) {
   var a = param ? 123 : null;
diff --git a/tests/compiler/dart2js/rti/data/call_typed_generic.dart b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
index 972f65f..6e7e075 100644
--- a/tests/compiler/dart2js/rti/data/call_typed_generic.dart
+++ b/tests/compiler/dart2js/rti/data/call_typed_generic.dart
@@ -7,8 +7,8 @@
 /*strong.class: A:direct,explicit=[A.T],needsArgs*/
 /*omit.class: A:*/
 class A<T> {
-  /*strong.element: A.call:*/
-  /*omit.element: A.call:*/
+  /*strong.member: A.call:*/
+  /*omit.member: A.call:*/
   call(T t) {}
 }
 
diff --git a/tests/compiler/dart2js/rti/data/closure.dart b/tests/compiler/dart2js/rti/data/closure.dart
index a77b268..aeb2742 100644
--- a/tests/compiler/dart2js/rti/data/closure.dart
+++ b/tests/compiler/dart2js/rti/data/closure.dart
@@ -9,7 +9,7 @@
     return /*needsSignature*/ (T t) {};
   }
 
-  /*element: A.f:*/
+  /*member: A.f:*/
   f() {
     // TODO(johnniwinther): Optimize local function type signature need.
     return
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is.dart b/tests/compiler/dart2js/rti/data/dynamic_is.dart
index d644fe8..3918c53 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is2.dart b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
index d9574d0..b9c6996 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is2.dart
@@ -5,12 +5,12 @@
 /*omit.class: A:*/
 /*strong.class: A:explicit=[A]*/
 class A {
-  /*element: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: A.instanceMethod:deps=[B.instanceMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
 }
 
 class B {
-  /*element: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
+  /*member: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
   instanceMethod<T>(A a, t) => a.instanceMethod<T>(t);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart b/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
index 4100762..100e0b6 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is_closure.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: A.instanceMethod:direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart b/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
index 0d2153a..95b4516 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_is_closure2.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:deps=[local],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: A.instanceMethod:deps=[local],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not.dart b/tests/compiler/dart2js/rti/data/dynamic_not.dart
index 9a5b7d3..15e708a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:*/
+  /*member: A.instanceMethod:*/
   instanceMethod<T>(t) => t;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not2.dart b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
index 10a4018..aa043a6 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not2.dart
@@ -4,12 +4,12 @@
 
 /*strong.class: A:explicit=[A]*/
 class A {
-  /*element: A.instanceMethod:deps=[B.instanceMethod]*/
+  /*member: A.instanceMethod:deps=[B.instanceMethod]*/
   instanceMethod<T>(t) => t;
 }
 
 class B {
-  /*element: B.instanceMethod:*/
+  /*member: B.instanceMethod:*/
   instanceMethod<T>(A a, t) => a.instanceMethod<T>(t);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart b/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
index 03451cd..9049c26 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not_closure.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:*/
+  /*member: A.instanceMethod:*/
   instanceMethod<T>(t) => t;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart b/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
index f98d095..d06c360 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_not_closure2.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:deps=[local]*/
+  /*member: A.instanceMethod:deps=[local]*/
   instanceMethod<T>(t) => t;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart
index 55a024b..191ab7a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: staticMethod:direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod:direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
 staticMethod<T>(t) => t is T;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
index 28102d4..b018072 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off2.dart
@@ -2,11 +2,11 @@
 // 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.
 
-/*element: staticMethod:deps=[B.instanceMethod],direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod:deps=[B.instanceMethod],direct,explicit=[staticMethod.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
 staticMethod<T>(t) => t is T;
 
 class B {
-  /*element: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
+  /*member: B.instanceMethod:implicit=[instanceMethod.T],indirect,needsArgs,selectors=[Selector(call, instanceMethod, arity=2, types=1)]*/
   instanceMethod<T>(a, t) => a<T>(t);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
index f620594..807f356 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off3.dart
@@ -5,11 +5,11 @@
 /*omit.class: A:*/
 /*strong.class: A:explicit=[A]*/
 class A {
-  /*element: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: A.instanceMethod:deps=[staticMethod],direct,explicit=[instanceMethod.T],needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(t) => t is T;
 }
 
-/*element: staticMethod:implicit=[staticMethod.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
+/*member: staticMethod:implicit=[staticMethod.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
 staticMethod<T>(A a, t) => a.instanceMethod<T>(t);
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart b/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
index b37ff25..2f04620 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_tear_off4.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*element: staticMethod1:deps=[staticMethod2],direct,explicit=[staticMethod1.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
+/*member: staticMethod1:deps=[staticMethod2],direct,explicit=[staticMethod1.T],needsArgs,selectors=[Selector(call, call, arity=1, types=1)]*/
 staticMethod1<T>(t) => t is T;
 
-/*element: staticMethod2:implicit=[staticMethod2.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
+/*member: staticMethod2:implicit=[staticMethod2.T],indirect,needsArgs,selectors=[Selector(call, call, arity=2, types=1)]*/
 staticMethod2<T>(a, t) => a<T>(t);
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
index 35506c8..b13dccd 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class A {
-  /*element: A.instanceMethod:exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
+  /*member: A.instanceMethod:exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
   instanceMethod<T>() => T;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
index 975f814..2f0ab7a 100644
--- a/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
+++ b/tests/compiler/dart2js/rti/data/dynamic_type_literal2.dart
@@ -4,12 +4,12 @@
 
 /*strong.class: A:explicit=[A]*/
 class A {
-  /*element: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
+  /*member: A.instanceMethod:deps=[B.instanceMethod],exp,needsArgs,selectors=[Selector(call, instanceMethod, arity=0, types=1)]*/
   instanceMethod<T>() => T;
 }
 
 class B {
-  /*element: B.instanceMethod:needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
+  /*member: B.instanceMethod:needsArgs,selectors=[Selector(call, instanceMethod, arity=1, types=1)]*/
   instanceMethod<T>(A a) => a.instanceMethod<T>();
 }
 
diff --git a/tests/compiler/dart2js/rti/data/generic_bounds.dart b/tests/compiler/dart2js/rti/data/generic_bounds.dart
index d045fa7..2d694aa 100644
--- a/tests/compiler/dart2js/rti/data/generic_bounds.dart
+++ b/tests/compiler/dart2js/rti/data/generic_bounds.dart
@@ -14,19 +14,19 @@
 
 class Class2b<T> extends Class2a<T> {}
 
-/*strong.element: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*strong.member: method1:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
 method1<T extends Class1a>() => null;
 
-/*strong.element: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
+/*strong.member: method2:needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
 method2<T extends Class2a<num>>() => null;
 
 method3<T>() => null;
 
 class Class3 {
-  /*strong.element: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*strong.member: Class3.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T extends Class1a>() => null;
 
-  /*strong.element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+  /*strong.member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
   method5<T extends Class2a<num>>() => null;
 
   method6<T>() => null;
@@ -35,7 +35,7 @@
 /*strong.class: Class4:explicit=[Class4]*/
 class Class4 {}
 
-/*strong.element: method10:needsArgs*/
+/*strong.member: method10:needsArgs*/
 method10<T extends Class4>() => null;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_creation.dart b/tests/compiler/dart2js/rti/data/generic_creation.dart
index cdae93c..b46fc2f 100644
--- a/tests/compiler/dart2js/rti/data/generic_creation.dart
+++ b/tests/compiler/dart2js/rti/data/generic_creation.dart
@@ -6,44 +6,44 @@
 
 /*class: A:needsArgs*/
 
-/*strong.element: A.:*/
-/*omit.element: A.:*/
+/*strong.member: A.:*/
+/*omit.member: A.:*/
 class A<X, Y, Z> {
-  /*strong.element: A.shift:*/
-  /*omit.element: A.shift:*/
+  /*strong.member: A.shift:*/
+  /*omit.member: A.shift:*/
   shift() => new A<Z, X, Y>();
 
-  /*strong.element: A.swap:*/
-  /*omit.element: A.swap:*/
+  /*strong.member: A.swap:*/
+  /*omit.member: A.swap:*/
   swap() => new A<Z, Y, X>();
 
-  /*strong.element: A.first:*/
-  /*omit.element: A.first:*/
+  /*strong.member: A.first:*/
+  /*omit.member: A.first:*/
   first() => new A<X, X, X>();
 
-  /*strong.element: A.last:*/
-  /*omit.element: A.last:*/
+  /*strong.member: A.last:*/
+  /*omit.member: A.last:*/
   last() => new A<Z, Z, Z>();
 
-  /*strong.element: A.wrap:*/
-  /*omit.element: A.wrap:*/
+  /*strong.member: A.wrap:*/
+  /*omit.member: A.wrap:*/
   wrap() => new A<A<X, X, X>, A<Y, Y, Y>, A<Z, Z, Z>>();
 }
 
-/*strong.element: B.:*/
-/*omit.element: B.:*/
+/*strong.member: B.:*/
+/*omit.member: B.:*/
 class B extends A<U, V, W> {}
 
 /*class: C:needsArgs*/
 
-/*strong.element: C.:*/
-/*omit.element: C.:*/
+/*strong.member: C.:*/
+/*omit.member: C.:*/
 class C<T> extends A<U, T, W> {}
 
 /*class: D:needsArgs*/
 
-/*strong.element: D.:*/
-/*omit.element: D.:*/
+/*strong.member: D.:*/
+/*omit.member: D.:*/
 class D<X, Y, Z> extends A<Y, Z, X> {}
 
 class U {}
@@ -52,12 +52,12 @@
 
 class W {}
 
-/*strong.element: sameType:*/
-/*omit.element: sameType:*/
+/*strong.member: sameType:*/
+/*omit.member: sameType:*/
 sameType(a, b) => Expect.equals(a.runtimeType, b.runtimeType);
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   A a = new A<U, V, W>();
   sameType(new A<W, U, V>(), a.shift());
diff --git a/tests/compiler/dart2js/rti/data/generic_method1.dart b/tests/compiler/dart2js/rti/data/generic_method1.dart
index da2373a..bad6514 100644
--- a/tests/compiler/dart2js/rti/data/generic_method1.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method1.dart
@@ -15,7 +15,7 @@
 /*class: BB:implicit=[BB]*/
 class BB {}
 
-/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
+/*member: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
 @pragma('dart2js:noInline')
 method2<T>() => new A<T>();
 
@@ -27,7 +27,7 @@
   }
 }
 
-/*element: method1:implicit=[method1.T],indirect,needsArgs*/
+/*member: method1:implicit=[method1.T],indirect,needsArgs*/
 @pragma('dart2js:noInline')
 method1<T>() {
   return new B<T>().foo();
diff --git a/tests/compiler/dart2js/rti/data/generic_method2.dart b/tests/compiler/dart2js/rti/data/generic_method2.dart
index 6ddb5c0..bfa88fd 100644
--- a/tests/compiler/dart2js/rti/data/generic_method2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method2.dart
@@ -23,7 +23,7 @@
   }
 }
 
-/*element: method1:implicit=[method1.T],indirect,needsArgs*/
+/*member: method1:implicit=[method1.T],indirect,needsArgs*/
 @pragma('dart2js:noInline')
 method1<T>() {
   return new B<T>().foo();
diff --git a/tests/compiler/dart2js/rti/data/generic_method3.dart b/tests/compiler/dart2js/rti/data/generic_method3.dart
index a00bee3..8fceecc 100644
--- a/tests/compiler/dart2js/rti/data/generic_method3.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method3.dart
@@ -15,7 +15,7 @@
 /*class: BB:implicit=[BB]*/
 class BB {}
 
-/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
+/*member: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
 @pragma('dart2js:noInline')
 method2<T>() => new A<T>();
 
diff --git a/tests/compiler/dart2js/rti/data/generic_method4.dart b/tests/compiler/dart2js/rti/data/generic_method4.dart
index 342fcdd..7c7fa24 100644
--- a/tests/compiler/dart2js/rti/data/generic_method4.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method4.dart
@@ -24,13 +24,13 @@
 }
 
 class C {
-  /*element: C.method1:implicit=[method1.T],indirect,needsArgs,selectors=[Selector(call, method1, arity=0, types=1)]*/
+  /*member: C.method1:implicit=[method1.T],indirect,needsArgs,selectors=[Selector(call, method1, arity=0, types=1)]*/
   @pragma('dart2js:noInline')
   method1<T>() {
     return new B<T>().foo(this);
   }
 
-  /*element: C.method2:deps=[B],implicit=[method2.T],indirect,needsArgs,selectors=[Selector(call, method2, arity=0, types=1)]*/
+  /*member: C.method2:deps=[B],implicit=[method2.T],indirect,needsArgs,selectors=[Selector(call, method2, arity=0, types=1)]*/
   @pragma('dart2js:noInline')
   method2<T>() => new A<T>();
 }
diff --git a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
index 04ef2e4..8404071 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_instantiate.dart
@@ -8,8 +8,8 @@
 /*class: B:deps=[method],explicit=[B<A>],needsArgs*/
 class B<T> {}
 
-/*strong.element: method:needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:needsArgs*/
+/*omit.member: method:needsArgs*/
 method<T>() => new B<T>();
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is.dart b/tests/compiler/dart2js/rti/data/generic_method_is.dart
index 972f756..2012cdf 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*strong.element: method:direct,explicit=[method.T],needsArgs*/
-/*omit.element: method:direct,explicit=[method.T],needsArgs*/
+/*strong.member: method:direct,explicit=[method.T],needsArgs*/
+/*omit.member: method:direct,explicit=[method.T],needsArgs*/
 method<T>(T t) => t is T;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is2.dart b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
index 4caa1c3..a415e06 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is2.dart
@@ -44,20 +44,20 @@
 /*class: F3:implicit=[F3]*/
 class F3 {}
 
-/*element: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a1], types=1)]*/
+/*member: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a1], types=1)]*/
 // Calls to this imply a check of the passed type arguments.
 bool topLevelMethod1<T>(T t, {a1}) => t is T;
 
-/*strong.element: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
+/*strong.member: topLevelMethod2:direct,explicit=[topLevelMethod2.T],needsArgs,selectors=[Selector(call, call, arity=2, named=[a2], types=1)]*/
 // Calls to this does _not_ imply a check of the passed type arguments.
 T topLevelMethod2<T>(T t, {a2}) => t;
 
 class Class {
-  /*element: Class.instanceMethod1:direct,explicit=[instanceMethod1.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b1], types=1),Selector(call, instanceMethod1, arity=2, named=[b1], types=1)]*/
+  /*member: Class.instanceMethod1:direct,explicit=[instanceMethod1.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b1], types=1),Selector(call, instanceMethod1, arity=2, named=[b1], types=1)]*/
   // Calls to this imply a check of the passed type arguments.
   bool instanceMethod1<S>(S s, {b1}) => s is S;
 
-  /*strong.element: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
+  /*strong.member: Class.instanceMethod2:direct,explicit=[instanceMethod2.S],needsArgs,selectors=[Selector(call, call, arity=2, named=[b2], types=1),Selector(call, instanceMethod2, arity=2, named=[b2], types=1)]*/
   // Calls to this does _not_ imply a check of the passed type arguments.
   S instanceMethod2<S>(S s, {b2}) => s;
 }
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
index 142ac30..c1b9be7 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05.dart
@@ -19,8 +19,8 @@
 class B {}
 
 class C {
-  /*omit.element: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
-  /*strong.element: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*strong.member: C.bar:direct,explicit=[Iterable<bar.T>],implicit=[bar.T],needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
   List<T> bar<T>(Iterable<T> t) => <T>[t.first];
 }
 
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
index 2959bc1..ea8041b 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05a.dart
@@ -19,8 +19,8 @@
 class B {}
 
 class C {
-  /*omit.element: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
-  /*strong.element: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*omit.member: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*strong.member: C.bar:explicit=[A<bar.T>],implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
   A<T> bar<T>(A<T> t) => new A<T>(t.field);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/indirect_through_static.dart b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
index e548a31..95fb0c3 100644
--- a/tests/compiler/dart2js/rti/data/indirect_through_static.dart
+++ b/tests/compiler/dart2js/rti/data/indirect_through_static.dart
@@ -26,8 +26,8 @@
   map['x'] = new C<B>();
 }
 
-/*strong.element: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
-/*omit.element: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*strong.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
+/*omit.member: lookup:direct,explicit=[C<lookup.T>],needsArgs*/
 C<T> lookup<T>(String key) {
   final value = map[key];
   if (value != null && value is C<T>) {
diff --git a/tests/compiler/dart2js/rti/data/instantiation1.dart b/tests/compiler/dart2js/rti/data/instantiation1.dart
index 1b8e7cd..930c1ff 100644
--- a/tests/compiler/dart2js/rti/data/instantiation1.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation1.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation2.dart b/tests/compiler/dart2js/rti/data/instantiation2.dart
index 48c7b6c..777fcc0 100644
--- a/tests/compiler/dart2js/rti/data/instantiation2.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation2.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation3.dart b/tests/compiler/dart2js/rti/data/instantiation3.dart
index 7d3df34..f426821 100644
--- a/tests/compiler/dart2js/rti/data/instantiation3.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation3.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation4.dart b/tests/compiler/dart2js/rti/data/instantiation4.dart
index 1fcdac2..34948b9 100644
--- a/tests/compiler/dart2js/rti/data/instantiation4.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation4.dart
@@ -2,8 +2,8 @@
 // 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.
 
-/*strong.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
-/*omit.element: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*strong.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
+/*omit.member: f:deps=[B],direct,explicit=[f.T],needsArgs,needsInst=[<B.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
diff --git a/tests/compiler/dart2js/rti/data/instantiation5.dart b/tests/compiler/dart2js/rti/data/instantiation5.dart
index c69f333..5cde8c6 100644
--- a/tests/compiler/dart2js/rti/data/instantiation5.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation5.dart
@@ -2,13 +2,13 @@
 // 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.
 
-/*strong.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.element: f:deps=[method]*/
+/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*omit.member: f:deps=[method]*/
 int f<T>(T a) => null;
 
 typedef int F<R>(R a);
 
-/*strong.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation6.dart b/tests/compiler/dart2js/rti/data/instantiation6.dart
index 672e987..3ce71b5 100644
--- a/tests/compiler/dart2js/rti/data/instantiation6.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation6.dart
@@ -2,14 +2,14 @@
 // 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.
 
-/*strong.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
-/*omit.element: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*strong.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
+/*omit.member: f:deps=[method],direct,explicit=[f.T],needsArgs,needsInst=[<method.S>]*/
 bool f<T>(T a) => a is T;
 
 typedef bool F<R>(R a);
 
-/*strong.element: method:indirect,needsArgs*/
-/*omit.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
+/*omit.member: method:indirect,needsArgs*/
 method<S>() {
   F<S> c;
 
diff --git a/tests/compiler/dart2js/rti/data/instantiation7.dart b/tests/compiler/dart2js/rti/data/instantiation7.dart
index d8af322..87aabd6 100644
--- a/tests/compiler/dart2js/rti/data/instantiation7.dart
+++ b/tests/compiler/dart2js/rti/data/instantiation7.dart
@@ -2,23 +2,23 @@
 // 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.
 
-/*strong.element: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
-/*omit.element: f1:deps=[method]*/
+/*strong.member: f1:deps=[method],direct,explicit=[f1.T],needsArgs,needsInst=[<method.X>]*/
+/*omit.member: f1:deps=[method]*/
 int f1<T>(T a, T b, T c) => null;
 
-/*strong.element: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
-/*omit.element: f2:deps=[method]*/
+/*strong.member: f2:deps=[method],direct,explicit=[f2.S,f2.T],needsArgs,needsInst=[<method.X,method.Y>]*/
+/*omit.member: f2:deps=[method]*/
 int f2<T, S>(T a, S b, S c) => null;
 
-/*strong.element: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
-/*omit.element: f3:deps=[method]*/
+/*strong.member: f3:deps=[method],direct,explicit=[f3.S,f3.T,f3.U],needsArgs,needsInst=[<method.X,method.Y,method.Z>]*/
+/*omit.member: f3:deps=[method]*/
 int f3<T, S, U>(T a, S b, U c) => null;
 
 typedef int F1<R>(R a, R b, R c);
 typedef int F2<R, P>(R a, P b, P c);
 typedef int F3<R, P, Q>(R a, P b, Q c);
 
-/*strong.element: method:indirect,needsArgs*/
+/*strong.member: method:indirect,needsArgs*/
 method<X, Y, Z>() {
   F1<X> c1;
   F2<X, Y> c2;
diff --git a/tests/compiler/dart2js/rti/data/list_literal.dart b/tests/compiler/dart2js/rti/data/list_literal.dart
index a6d181f..1b2d499 100644
--- a/tests/compiler/dart2js/rti/data/list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal.dart
@@ -16,7 +16,7 @@
 }
 
 class Class {
-  /*element: Class.m:implicit=[m.T],indirect,needsArgs,selectors=[Selector(call, m, arity=0, types=1)]*/
+  /*member: Class.m:implicit=[m.T],indirect,needsArgs,selectors=[Selector(call, m, arity=0, types=1)]*/
   m<T>() {
     return <T>[];
   }
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
index aa06e82..d3894cd 100644
--- a/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal.dart
@@ -7,8 +7,8 @@
 /*strong.class: global#JSArray:deps=[ArrayIterator,List],explicit=[JSArray,JSArray.E,JSArray<ArrayIterator.E>],implicit=[JSArray.E],indirect,needsArgs*/
 /*omit.class: global#JSArray:deps=[List],explicit=[JSArray],needsArgs*/
 
-/*strong.element: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
+/*omit.member: method:needsArgs*/
 @pragma('dart2js:noInline')
 method<T>() {
   return () => <T>[];
diff --git a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
index 4084c3c..6edee72 100644
--- a/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_map_literal.dart
@@ -7,8 +7,8 @@
 /*strong.class: global#LinkedHashMap:deps=[Map],direct,explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],needsArgs*/
 /*omit.class: global#LinkedHashMap:deps=[Map],needsArgs*/
 
-/*strong.element: method:implicit=[method.T],indirect,needsArgs*/
-/*omit.element: method:needsArgs*/
+/*strong.member: method:implicit=[method.T],indirect,needsArgs*/
+/*omit.member: method:needsArgs*/
 @pragma('dart2js:noInline')
 method<T>() {
   return () => <T, int>{};
diff --git a/tests/compiler/dart2js/rti/data/local_function_signature2.dart b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
index ce0306e..dd0c838 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signature2.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signature2.dart
@@ -25,8 +25,8 @@
 }
 
 class Class2 {
-  /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
-  /*omit.element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T>() {
     /*needsSignature*/
     num local(T n) => null;
@@ -35,7 +35,7 @@
 }
 
 class Class3 {
-  /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+  /*member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
   method5<T>() {
     /*needsSignature*/
     T local(num n) => null;
@@ -44,8 +44,8 @@
 }
 
 class Class4 {
-  /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
-  /*omit.element: Class4.method6:*/
+  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+  /*omit.member: Class4.method6:*/
   method6<T>() {
     /**/
     num local(num n, T t) => null;
@@ -53,23 +53,23 @@
   }
 }
 
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.element: method7:needsArgs*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*omit.member: method7:needsArgs*/
 method7<T>() {
   /*needsSignature*/
   num local(T n) => null;
   return local;
 }
 
-/*element: method8:needsArgs*/
+/*member: method8:needsArgs*/
 method8<T>() {
   /*needsSignature*/
   T local(num n) => null;
   return local;
 }
 
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*omit.member: method9:*/
 method9<T>() {
   /**/
   num local(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
index 92252a3..80eed74 100644
--- a/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures_generic.dart
@@ -25,8 +25,8 @@
 }
 
 class Class2 {
-  /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
-  /*omit.element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+  /*omit.member: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
   method4<T>() {
     /*needsSignature*/
     num local(T n) => null;
@@ -35,7 +35,7 @@
 }
 
 class Class3 {
-  /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+  /*member: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
   method5<T>() {
     /*needsSignature*/
     T local(num n) => null;
@@ -44,8 +44,8 @@
 }
 
 class Class4 {
-  /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
-  /*omit.element: Class4.method6:*/
+  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
+  /*omit.member: Class4.method6:*/
   method6<T>() {
     /**/
     num local(num n, T t) => null;
@@ -53,23 +53,23 @@
   }
 }
 
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs*/
-/*omit.element: method7:needsArgs*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs*/
+/*omit.member: method7:needsArgs*/
 method7<T>() {
   /*needsSignature*/
   num local(T n) => null;
   return local;
 }
 
-/*element: method8:needsArgs*/
+/*member: method8:needsArgs*/
 method8<T>() {
   /*needsSignature*/
   T local(num n) => null;
   return local;
 }
 
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs*/
+/*omit.member: method9:*/
 method9<T>() {
   /**/
   num local(num n, T t) => null;
diff --git a/tests/compiler/dart2js/rti/data/method_signatures.dart b/tests/compiler/dart2js/rti/data/method_signatures.dart
index 5a4b083..e393181 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures.dart
@@ -5,44 +5,44 @@
 import 'package:expect/expect.dart';
 
 class Class1 {
-  /*element: Class1.method1:*/
+  /*member: Class1.method1:*/
   num method1(num n) => null;
 
-  /*element: Class1.method2:*/
+  /*member: Class1.method2:*/
   num method2(int n) => null;
 
-  /*element: Class1.method3:*/
+  /*member: Class1.method3:*/
   Object method3(num n) => null;
 }
 
 /*strong.class: Class2:direct,explicit=[Class2.T],needsArgs*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.method4:*/
-  /*omit.element: Class2.method4:*/
+  /*strong.member: Class2.method4:*/
+  /*omit.member: Class2.method4:*/
   num method4(T n) => null;
 }
 
 /*class: Class3:needsArgs*/
 class Class3<T> {
-  /*element: Class3.method5:needsSignature*/
+  /*member: Class3.method5:needsSignature*/
   T method5(num n) => null;
 }
 
 /*omit.class: Class4:*/
 /*strong.class: Class4:direct,explicit=[Class4.T],needsArgs*/
 class Class4<T> {
-  /*element: Class4.method6:*/
+  /*member: Class4.method6:*/
   num method6(num n, T t) => null;
 }
 
-/*element: method7:*/
+/*member: method7:*/
 num method7(num n) => null;
 
-/*element: method8:*/
+/*member: method8:*/
 num method8(int n) => null;
 
-/*element: method9:*/
+/*member: method9:*/
 Object method9(num n) => null;
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
index 1c1cb02..9f33a9f 100644
--- a/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
+++ b/tests/compiler/dart2js/rti/data/method_signatures_generic.dart
@@ -5,42 +5,42 @@
 import 'package:expect/expect.dart';
 
 class Class1 {
-  /*element: Class1.method1:*/
+  /*member: Class1.method1:*/
   num method1<T>(num n) => null;
 
-  /*element: Class1.method2:*/
+  /*member: Class1.method2:*/
   num method2<T>(int n) => null;
 
-  /*element: Class1.method3:*/
+  /*member: Class1.method3:*/
   int method3<T>(num n) => null;
 }
 
 class Class2 {
-  /*strong.element: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>]*/
-  /*omit.element: Class2.method4:*/
+  /*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>]*/
+  /*omit.member: Class2.method4:*/
   num method4<T>(T n) => null;
 }
 
 class Class3 {
-  /*element: Class3.method5:*/
+  /*member: Class3.method5:*/
   T method5<T>(num n) => null;
 }
 
 class Class4 {
-  /*strong.element: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>]*/
-  /*omit.element: Class4.method6:*/
+  /*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>]*/
+  /*omit.member: Class4.method6:*/
   num method6<T>(num n, T t) => null;
 }
 
-/*strong.element: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>]*/
-/*omit.element: method7:*/
+/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>]*/
+/*omit.member: method7:*/
 num method7<T>(T n) => null;
 
-/*element: method8:*/
+/*member: method8:*/
 T method8<T>(num n) => null;
 
-/*strong.element: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>]*/
-/*omit.element: method9:*/
+/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>]*/
+/*omit.member: method9:*/
 num method9<T>(num n, T t) => null;
 
 @pragma('dart2js:noInline')
diff --git a/tests/compiler/dart2js/rti/data/no_such_method1.dart b/tests/compiler/dart2js/rti/data/no_such_method1.dart
index f2e93f1..da65384 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method1.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C {
-  /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+  /*member: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
   noSuchMethod(i) => i.typeArguments;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/no_such_method2.dart b/tests/compiler/dart2js/rti/data/no_such_method2.dart
index 55434cd..8b27c38 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method2.dart
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C {
-  /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+  /*member: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
   noSuchMethod(i) => i.typeArguments;
 }
 
 class D {
-  /*element: D.foo:exp,needsArgs,selectors=[Selector(call, foo, arity=0, types=2)]*/
+  /*member: D.foo:exp,needsArgs,selectors=[Selector(call, foo, arity=0, types=2)]*/
   foo<U, V>() => [U, V];
 }
 
diff --git a/tests/compiler/dart2js/rti/data/no_such_method3.dart b/tests/compiler/dart2js/rti/data/no_such_method3.dart
index d10adf2..a6ba3c7 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method3.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method3.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C {
-  /*element: C.noSuchMethod:*/
+  /*member: C.noSuchMethod:*/
   noSuchMethod(i) => null;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/private_dynamic.dart b/tests/compiler/dart2js/rti/data/private_dynamic.dart
index 275d6c2..fb5ca94 100644
--- a/tests/compiler/dart2js/rti/data/private_dynamic.dart
+++ b/tests/compiler/dart2js/rti/data/private_dynamic.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C {
-  /*element: C._private:direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
+  /*member: C._private:direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
   _private<T>(t) => t is T;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/private_dynamic2.dart b/tests/compiler/dart2js/rti/data/private_dynamic2.dart
index 0a82cf2..5612fbf 100644
--- a/tests/compiler/dart2js/rti/data/private_dynamic2.dart
+++ b/tests/compiler/dart2js/rti/data/private_dynamic2.dart
@@ -3,12 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 class C {
-  /*element: C._private:deps=[D._private2],direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
+  /*member: C._private:deps=[D._private2],direct,explicit=[_private.T],needsArgs,selectors=[Selector(call, _private, arity=1, types=1)]*/
   _private<T>(t) => t is T;
 }
 
 class D {
-  /*element: D._private2:implicit=[_private2.T],indirect,needsArgs,selectors=[Selector(call, _private2, arity=2, types=1)]*/
+  /*member: D._private2:implicit=[_private2.T],indirect,needsArgs,selectors=[Selector(call, _private2, arity=2, types=1)]*/
   _private2<T>(c, t) => c._private<T>(t);
 }
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
index 69a3f14..08cc7bf 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals1.dart
@@ -7,13 +7,13 @@
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   /*needsSignature*/
   local1a() {}
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
index 2757f5a..c7cc1f4 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals2.dart
@@ -7,13 +7,13 @@
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   /*strong.needsArgs,needsSignature*/
   /*omit.needsArgs,needsSignature*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
index d650fb6..e586484 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals3.dart
@@ -9,12 +9,12 @@
 /*omit.class: Class1:needsArgs*/
 /*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 
-  /*strong.element: Class1.method:*/
-  /*omit.element: Class1.method:*/
+  /*strong.member: Class1.method:*/
+  /*omit.member: Class1.method:*/
   method() {
     /*needsSignature*/
     T local1a() => null;
@@ -34,13 +34,13 @@
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   new Class1<int>().method();
   new Class2<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
index 33973ff..d219396 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals4.dart
@@ -7,37 +7,37 @@
 /*strong.class: Class1:*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 
   // TODO(johnniwinther): Currently only methods that use class type variables
   // in their signature are marked as 'needs signature'. Change this to mark
   // all methods that need to support access to their function type at runtime.
 
-  /*strong.element: Class1.method1a:*/
-  /*omit.element: Class1.method1a:*/
+  /*strong.member: Class1.method1a:*/
+  /*omit.member: Class1.method1a:*/
   method1a() => null;
 
-  /*strong.element: Class1.method1b:*/
-  /*omit.element: Class1.method1b:*/
+  /*strong.member: Class1.method1b:*/
+  /*omit.member: Class1.method1b:*/
   method1b() => null;
 
-  /*strong.element: Class1.method2:*/
-  /*omit.element: Class1.method2:*/
+  /*strong.member: Class1.method2:*/
+  /*omit.member: Class1.method2:*/
   method2(t, s) => t;
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
index 82ed29c..62858b0 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals5.dart
@@ -7,33 +7,33 @@
 /*omit.class: Class1:needsArgs*/
 /*strong.class: Class1:direct,explicit=[Class1.T],needsArgs*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 
-  /*strong.element: Class1.method1a:needsSignature*/
-  /*omit.element: Class1.method1a:needsSignature*/
+  /*strong.member: Class1.method1a:needsSignature*/
+  /*omit.member: Class1.method1a:needsSignature*/
   T method1a() => null;
 
-  /*strong.element: Class1.method1b:needsSignature*/
-  /*omit.element: Class1.method1b:needsSignature*/
+  /*strong.member: Class1.method1b:needsSignature*/
+  /*omit.member: Class1.method1b:needsSignature*/
   T method1b() => null;
 
-  /*strong.element: Class1.method2:needsSignature*/
-  /*omit.element: Class1.method2:needsSignature*/
+  /*strong.member: Class1.method2:needsSignature*/
+  /*omit.member: Class1.method2:needsSignature*/
   T method2(T t, String s) => t;
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
index 219ee28..f469a25 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals6.dart
@@ -4,28 +4,28 @@
 
 import 'package:expect/expect.dart';
 
-/*strong.element: method1a:*/
-/*omit.element: method1a:*/
+/*strong.member: method1a:*/
+/*omit.member: method1a:*/
 method1a() => null;
 
-/*strong.element: method1b:*/
-/*omit.element: method1b:*/
+/*strong.member: method1b:*/
+/*omit.member: method1b:*/
 method1b() => null;
 
-/*strong.element: method2:*/
-/*omit.element: method2:*/
+/*strong.member: method2:*/
+/*omit.member: method2:*/
 method2(t, s) => t;
 
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
   Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
index ac7d406..db76621 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals7.dart
@@ -4,26 +4,26 @@
 
 import 'package:expect/expect.dart';
 
-/*element: method1a:*/
+/*member: method1a:*/
 T method1a<T>() => null;
 
-/*element: method1b:*/
+/*member: method1b:*/
 T method1b<T>() => null;
 
-/*strong.element: method2:direct,explicit=[method2.T],needsArgs*/
-/*omit.element: method2:*/
+/*strong.member: method2:direct,explicit=[method2.T],needsArgs*/
+/*omit.member: method2:*/
 T method2<T>(T t, String s) => t;
 
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
   Expect.isFalse(method1a.runtimeType == method2.runtimeType);
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
index d597301..a7b639a 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_equals8.dart
@@ -7,31 +7,31 @@
 /*strong.class: Class1:*/
 /*omit.class: Class1:*/
 class Class1<S> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 
-  /*element: Class1.method1a:*/
+  /*member: Class1.method1a:*/
   T method1a<T>() => null;
 
-  /*element: Class1.method1b:*/
+  /*member: Class1.method1b:*/
   T method1b<T>() => null;
 
-  /*strong.element: Class1.method2:direct,explicit=[method2.T],needsArgs*/
-  /*omit.element: Class1.method2:*/
+  /*strong.member: Class1.method2:direct,explicit=[method2.T],needsArgs*/
+  /*omit.member: Class1.method2:*/
   T method2<T>(T t, String s) => t;
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   var c = new Class1<int>();
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
index 53f3285..a1acdd3 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string1.dart
@@ -5,13 +5,13 @@
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   /*strong.needsSignature*/
   /*omit.*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
index 209cf08..041b311 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string2.dart
@@ -5,13 +5,13 @@
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   /*strong.needsArgs,needsSignature*/
   /*omit.*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
index 0496521..9d80812 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string3.dart
@@ -5,25 +5,25 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 
-  /*strong.element: Class1.method:needsSignature*/
-  /*omit.element: Class1.method:*/
+  /*strong.member: Class1.method:needsSignature*/
+  /*omit.member: Class1.method:*/
   T method() => null;
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
index 907e515..f4511ea 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string4.dart
@@ -4,20 +4,20 @@
 
 /*class: Class1:*/
 class Class1 {
-  /*element: Class1.:*/
+  /*member: Class1.:*/
   Class1();
 
-  /*element: Class1.method:*/
+  /*member: Class1.method:*/
   T method<T>() => null;
 }
 
 /*class: Class2:*/
 class Class2<T> {
-  /*element: Class2.:*/
+  /*member: Class2.:*/
   Class2();
 }
 
-/*element: main:*/
+/*member: main:*/
 main() {
   Class1 cls1 = new Class1();
   print(cls1.method.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
index 810ca7a..20026ba 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string5.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class:*/
 /*omit.class: Class:*/
 class Class<T> {
-  /*strong.element: Class.:*/
-  /*omit.element: Class.:*/
+  /*strong.member: Class.:*/
+  /*omit.member: Class.:*/
   Class();
 }
 
-/*strong.element: method1:*/
-/*omit.element: method1:*/
+/*strong.member: method1:*/
+/*omit.member: method1:*/
 method1() {}
 
-/*strong.element: method2:*/
-/*omit.element: method2:*/
+/*strong.member: method2:*/
+/*omit.member: method2:*/
 method2(int i, String s) => i;
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   print('${method1.runtimeType}');
   method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
index b684856..fa6db4d 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_closure_to_string6.dart
@@ -4,17 +4,17 @@
 
 /*class: Class:*/
 class Class<T> {
-  /*element: Class.:*/
+  /*member: Class.:*/
   Class();
 }
 
-/*element: method1:*/
+/*member: method1:*/
 method1<T>() {}
 
-/*element: method2:*/
+/*member: method2:*/
 method2<T>(t, s) => t;
 
-/*element: main:*/
+/*member: main:*/
 main() {
   print('${method1.runtimeType}');
   method2(0, '');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
index 0f6cce7..bf0d3e2 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals1.dart
@@ -6,12 +6,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.element: Class1a.:*/
-  /*omit.element: Class1a.:*/
+  /*strong.member: Class1a.:*/
+  /*omit.member: Class1a.:*/
   Class1a();
 
-  /*strong.element: Class1a.==:*/
-  /*omit.element: Class1a.==:*/
+  /*strong.member: Class1a.==:*/
+  /*omit.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return runtimeType == other.runtimeType;
@@ -20,8 +20,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.element: Class1b.:*/
-  /*omit.element: Class1b.:*/
+  /*strong.member: Class1b.:*/
+  /*omit.member: Class1b.:*/
   Class1b();
 }
 
@@ -29,21 +29,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.element: Class1c.:*/
-  /*omit.element: Class1c.:*/
+  /*strong.member: Class1c.:*/
+  /*omit.member: Class1c.:*/
   Class1c();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
index eb04620..77b9099 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals2.dart
@@ -6,12 +6,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.element: Class1a.:*/
-  /*omit.element: Class1a.:*/
+  /*strong.member: Class1a.:*/
+  /*omit.member: Class1a.:*/
   Class1a();
 
-  /*strong.element: Class1a.==:*/
-  /*omit.element: Class1a.==:*/
+  /*strong.member: Class1a.==:*/
+  /*omit.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return other.runtimeType == runtimeType;
@@ -20,8 +20,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.element: Class1b.:*/
-  /*omit.element: Class1b.:*/
+  /*strong.member: Class1b.:*/
+  /*omit.member: Class1b.:*/
   Class1b();
 }
 
@@ -29,21 +29,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.element: Class1c.:*/
-  /*omit.element: Class1c.:*/
+  /*strong.member: Class1c.:*/
+  /*omit.member: Class1c.:*/
   Class1c();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
index e83b5cf..c290ac6 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals3.dart
@@ -6,12 +6,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.element: Class1a.:*/
-  /*omit.element: Class1a.:*/
+  /*strong.member: Class1a.:*/
+  /*omit.member: Class1a.:*/
   Class1a();
 
-  /*strong.element: Class1a.==:*/
-  /*omit.element: Class1a.==:*/
+  /*strong.member: Class1a.==:*/
+  /*omit.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return runtimeType == other?.runtimeType;
@@ -20,8 +20,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.element: Class1b.:*/
-  /*omit.element: Class1b.:*/
+  /*strong.member: Class1b.:*/
+  /*omit.member: Class1b.:*/
   Class1b();
 }
 
@@ -29,21 +29,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.element: Class1c.:*/
-  /*omit.element: Class1c.:*/
+  /*strong.member: Class1c.:*/
+  /*omit.member: Class1c.:*/
   Class1c();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
index f3f3b67..5e77f79 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals4.dart
@@ -6,12 +6,12 @@
 
 /*class: Class1a:needsArgs*/
 class Class1a<T> {
-  /*strong.element: Class1a.:*/
-  /*omit.element: Class1a.:*/
+  /*strong.member: Class1a.:*/
+  /*omit.member: Class1a.:*/
   Class1a();
 
-  /*strong.element: Class1a.==:*/
-  /*omit.element: Class1a.==:*/
+  /*strong.member: Class1a.==:*/
+  /*omit.member: Class1a.==:*/
   bool operator ==(other) {
     if (identical(this, other)) return true;
     return other?.runtimeType == runtimeType;
@@ -20,8 +20,8 @@
 
 /*class: Class1b:needsArgs*/
 class Class1b<T> extends Class1a<T> {
-  /*strong.element: Class1b.:*/
-  /*omit.element: Class1b.:*/
+  /*strong.member: Class1b.:*/
+  /*omit.member: Class1b.:*/
   Class1b();
 }
 
@@ -29,21 +29,21 @@
 // this class.
 /*class: Class1c:needsArgs*/
 class Class1c<T> implements Class1a<T> {
-  /*strong.element: Class1c.:*/
-  /*omit.element: Class1c.:*/
+  /*strong.member: Class1c.:*/
+  /*omit.member: Class1c.:*/
   Class1c();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1a<int> cls1a = new Class1a<int>();
   Class1a<int> cls1b1 = new Class1b<int>();
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
index 56285d2..c1db9ed 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals5.dart
@@ -27,14 +27,14 @@
   Class2();
 }
 
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
 test(Class1a c, Type type) {
   return c.runtimeType == type;
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Expect.isTrue(test(new Class1a(), Class1a));
   Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
index 2aff7c1..f0cca27 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals6.dart
@@ -28,14 +28,14 @@
   Class2();
 }
 
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
 test(Class1a c, Type type) {
   return c.runtimeType == type;
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Expect.isTrue(test(new Class1a(), Class1a));
   Expect.isFalse(test(new Class1b<int>(), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
index a1748f4..8639733 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_equals7.dart
@@ -35,14 +35,14 @@
   Class3(this.field);
 }
 
-/*strong.element: test:*/
-/*omit.element: test:*/
+/*strong.member: test:*/
+/*omit.member: test:*/
 test(Class3 c, Type type) {
   return c.field.runtimeType == type;
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Expect.isTrue(test(new Class3<int>(new Class1a()), Class1a));
   Expect.isFalse(test(new Class3<int>(new Class1b<int>()), Class1a));
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
index 657513e..282d501 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string1.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
 
 main() {
   /*strong.direct,explicit=[id.T],needsArgs,needsInst=[<int>],needsSignature*/
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
index 2db3273..22ddfb3 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string2.dart
@@ -2,9 +2,9 @@
 // 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.
 
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
 
-/*strong.element: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+/*strong.member: id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
 T id<T>(T t, String s) => t;
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
index cb51e1b..222eb2b 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_instantiate_to_string3.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*element: global#instantiate1:needsArgs*/
+/*member: global#instantiate1:needsArgs*/
 
 class Class {
-  /*strong.element: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
+  /*strong.member: Class.id:direct,explicit=[id.T],needsArgs,needsInst=[<int>]*/
   T id<T>(T t, String s) => t;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
index ae67754..70f0f95 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string1.dart
@@ -5,29 +5,29 @@
 /*strong.class: Class1:*/
 /*omit.class: Class1:*/
 class Class1 {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
 /*strong.class: Class3:needsArgs*/
 /*omit.class: Class3:*/
 class Class3<T> implements Class1 {
-  /*strong.element: Class3.:*/
-  /*omit.element: Class3.:*/
+  /*strong.member: Class3.:*/
+  /*omit.member: Class3.:*/
   Class3();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1 cls1 = new Class1();
   print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
index 3c36e34..d8efa16 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string2.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
index 91058ce..baf98d4 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string3.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
index 2b9902a..77babb9 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string4.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print(cls1?.runtimeType?.toString());
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
index 22f8349..235b8be 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string5.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1<int> cls1 = new Class1<int>();
   print('${cls1?.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
index eeb633c..b312960 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string6.dart
@@ -5,21 +5,21 @@
 /*strong.class: Class1:needsArgs*/
 /*omit.class: Class1:*/
 class Class1<T> {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:needsArgs*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   dynamic cls1 = new Class1<int>();
   print('${cls1.runtimeType}');
diff --git a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
index ae67754..70f0f95 100644
--- a/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
+++ b/tests/compiler/dart2js/rti/data/runtime_type_to_string7.dart
@@ -5,29 +5,29 @@
 /*strong.class: Class1:*/
 /*omit.class: Class1:*/
 class Class1 {
-  /*strong.element: Class1.:*/
-  /*omit.element: Class1.:*/
+  /*strong.member: Class1.:*/
+  /*omit.member: Class1.:*/
   Class1();
 }
 
 /*strong.class: Class2:*/
 /*omit.class: Class2:*/
 class Class2<T> {
-  /*strong.element: Class2.:*/
-  /*omit.element: Class2.:*/
+  /*strong.member: Class2.:*/
+  /*omit.member: Class2.:*/
   Class2();
 }
 
 /*strong.class: Class3:needsArgs*/
 /*omit.class: Class3:*/
 class Class3<T> implements Class1 {
-  /*strong.element: Class3.:*/
-  /*omit.element: Class3.:*/
+  /*strong.member: Class3.:*/
+  /*omit.member: Class3.:*/
   Class3();
 }
 
-/*strong.element: main:*/
-/*omit.element: main:*/
+/*strong.member: main:*/
+/*omit.member: main:*/
 main() {
   Class1 cls1 = new Class1();
   print(cls1.runtimeType.toString());
diff --git a/tests/compiler/dart2js/rti/data/tear_off.dart b/tests/compiler/dart2js/rti/data/tear_off.dart
index 421d480..f2c56b1 100644
--- a/tests/compiler/dart2js/rti/data/tear_off.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off.dart
@@ -4,10 +4,10 @@
 
 /*class: A:*/
 class A<T> {
-  /*element: A.m:*/
+  /*member: A.m:*/
   void m(String t) {}
 
-  /*element: A.f:*/
+  /*member: A.f:*/
   void f(int t) {}
 }
 
diff --git a/tests/compiler/dart2js/rti/data/tear_off_generic.dart b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
index 24cc2ee..b3689bb 100644
--- a/tests/compiler/dart2js/rti/data/tear_off_generic.dart
+++ b/tests/compiler/dart2js/rti/data/tear_off_generic.dart
@@ -5,11 +5,11 @@
 /*strong.class: A:direct,explicit=[A.T],needsArgs*/
 /*omit.class: A:*/
 class A<T> {
-  /*strong.element: A.m:*/
-  /*omit.element: A.m:*/
+  /*strong.member: A.m:*/
+  /*omit.member: A.m:*/
   void m(T t) {}
 
-  /*element: A.f:*/
+  /*member: A.f:*/
   void f(int t) {}
 }
 
diff --git a/tests/compiler/dart2js/rti/data/type_literal_generic.dart b/tests/compiler/dart2js/rti/data/type_literal_generic.dart
index 098d700..dde4860 100644
--- a/tests/compiler/dart2js/rti/data/type_literal_generic.dart
+++ b/tests/compiler/dart2js/rti/data/type_literal_generic.dart
@@ -6,19 +6,19 @@
 class A<T> {
   instanceMethod() => T;
 
-  /*element: A.staticMethod:exp,needsArgs*/
+  /*member: A.staticMethod:exp,needsArgs*/
   static staticMethod<S>() => S;
 
-  /*element: A.staticMethodNested:exp,needsArgs*/
+  /*member: A.staticMethodNested:exp,needsArgs*/
   static staticMethodNested<S>() {
     var inner = () => S;
     return inner();
   }
 
-  /*element: A.genericMethod:exp,needsArgs,selectors=[Selector(call, genericMethod, arity=0, types=1)]*/
+  /*member: A.genericMethod:exp,needsArgs,selectors=[Selector(call, genericMethod, arity=0, types=1)]*/
   genericMethod<S>() => S;
 
-  /*element: A.genericMethodNested:exp,needsArgs,selectors=[Selector(call, genericMethodNested, arity=0, types=1)]*/
+  /*member: A.genericMethodNested:exp,needsArgs,selectors=[Selector(call, genericMethodNested, arity=0, types=1)]*/
   genericMethodNested<S>() {
     var inner = () => S;
     return inner();
@@ -42,10 +42,10 @@
   }
 }
 
-/*element: topLevelMethod:exp,needsArgs*/
+/*member: topLevelMethod:exp,needsArgs*/
 topLevelMethod<S>() => S;
 
-/*element: topLevelMethodNested:exp,needsArgs*/
+/*member: topLevelMethodNested:exp,needsArgs*/
 topLevelMethodNested<S>() {
   var inner = () => S;
   return inner();
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index fd96ed8..a6fc1c2 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -9,7 +9,6 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/runtime_types.dart';
 import 'package:compiler/src/js_emitter/model.dart';
 import 'package:compiler/src/js_model/element_map.dart';
@@ -127,7 +126,7 @@
 }
 
 class RtiClassEmissionIrComputer extends DataRegistry<String>
-    with ComputeValueMixin {
+    with ComputeValueMixin, IrDataRegistryMixin<String> {
   @override
   final Compiler compiler;
   final JsToElementMap _elementMap;
@@ -142,8 +141,9 @@
   void computeClassValue(ClassEntity cls) {
     Id id = new ClassId(cls.name);
     ir.TreeNode node = _elementMap.getClassDefinition(cls).node;
-    registerValue(
-        computeSourceSpanFromTreeNode(node), id, getClassValue(cls), cls);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+        id, getClassValue(cls), cls);
   }
 }
 
diff --git a/tests/compiler/dart2js/rti/rti_need_test_helper.dart b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
index d5c4e49..bbdd2c2 100644
--- a/tests/compiler/dart2js/rti/rti_need_test_helper.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test_helper.dart
@@ -11,7 +11,6 @@
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/js_backend/runtime_types.dart';
 import 'package:compiler/src/js_model/js_world.dart';
 import 'package:compiler/src/js_model/element_map.dart';
@@ -318,7 +317,7 @@
 }
 
 class RtiClassNeedIrComputer extends DataRegistry<String>
-    with ComputeValueMixin, IrMixin {
+    with ComputeValueMixin, IrMixin, IrDataRegistryMixin<String> {
   @override
   final Compiler compiler;
   final JsToElementMap _elementMap;
@@ -333,8 +332,9 @@
   void computeClassValue(ClassEntity cls) {
     Id id = new ClassId(cls.name);
     ir.TreeNode node = _elementMap.getClassDefinition(cls).node;
-    registerValue(
-        computeSourceSpanFromTreeNode(node), id, getClassValue(cls), cls);
+    ir.TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
+    registerValue(nodeWithOffset?.location?.file, nodeWithOffset?.fileOffset,
+        id, getClassValue(cls), cls);
   }
 }
 
diff --git a/tests/compiler/dart2js/sourcemaps/mapping_test.dart b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
index 6c933ee..a534142 100644
--- a/tests/compiler/dart2js/sourcemaps/mapping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/mapping_test.dart
@@ -9,7 +9,7 @@
 import 'package:compiler/compiler_new.dart';
 import 'package:expect/expect.dart';
 import 'package:source_maps/source_maps.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 
 import '../helpers/memory_compiler.dart';
 
@@ -72,7 +72,7 @@
     } else if (arg == '--write-js') {
       writeJs = true;
     } else {
-      int index = int.parse(arg, onError: (_) => null);
+      int index = int.tryParse(arg);
       if (index != null) {
         indices ??= <int>[];
         if (index < 0 || index >= TESTS.length) {
diff --git a/tests/compiler/dart2js/sourcemaps/stepping_test.dart b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
index c8610e0..e37bf06 100644
--- a/tests/compiler/dart2js/sourcemaps/stepping_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stepping_test.dart
@@ -11,7 +11,7 @@
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/dart2js.dart' as entry;
 import 'package:expect/expect.dart';
-import 'package:sourcemap_testing/src/annotated_code_helper.dart';
+import 'package:front_end/src/testing/annotated_code_helper.dart';
 import 'package:sourcemap_testing/src/stepping_helper.dart';
 
 void main(List<String> args) {
diff --git a/tests/compiler/dart2js_extra/22776_test.dart b/tests/compiler/dart2js_extra/22776_test.dart
index 80dbffd1..135f505 100644
--- a/tests/compiler/dart2js_extra/22776_test.dart
+++ b/tests/compiler/dart2js_extra/22776_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// Regression test for http://dartbug.com/22776/
+// Regression test for http://dartbug.com/22776
 
 import "package:expect/expect.dart";
 
diff --git a/tests/compiler/dart2js_extra/22868_test.dart b/tests/compiler/dart2js_extra/22868_test.dart
index 0d83b955..71907def 100644
--- a/tests/compiler/dart2js_extra/22868_test.dart
+++ b/tests/compiler/dart2js_extra/22868_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// Regression test for http://dartbug.com/22868/ and http://dartbug.com/22895/.
+// Regression test for http://dartbug.com/22868 and http://dartbug.com/22895
 // Ensure that the closure tracer properly handles await.
 
 main() async {
diff --git a/tests/compiler/dart2js_extra/23264_test.dart b/tests/compiler/dart2js_extra/23264_test.dart
deleted file mode 100644
index a834426..0000000
--- a/tests/compiler/dart2js_extra/23264_test.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:expect/expect.dart';
-
-class A {
-  A(ignore);
-}
-
-main() => Expect.throws(() => A(const [])); // oops, `new` is missing!
diff --git a/tests/compiler/dart2js_extra/23404_test.dart b/tests/compiler/dart2js_extra/23404_test.dart
index d3b9f46..699e63d 100644
--- a/tests/compiler/dart2js_extra/23404_test.dart
+++ b/tests/compiler/dart2js_extra/23404_test.dart
@@ -2,12 +2,13 @@
 // 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.
 
-// Regression test for http://dartbug.com/23404/
-import 'package:expect/expect.dart';
-
+// Regression test for http://dartbug.com/23404
+//
 // Dart2js crashed when the global metadata had escaped characters. That
 // happens, for example, when tearing off a function that uses a default
 // argument containing escape characters.
+import 'package:expect/expect.dart';
+
 foo([a = '\u00a0']) => a;
 bar() => '';
 
diff --git a/tests/compiler/dart2js_extra/23486_test.dart b/tests/compiler/dart2js_extra/23486_test.dart
index b628cf7..1d41e26 100644
--- a/tests/compiler/dart2js_extra/23486_test.dart
+++ b/tests/compiler/dart2js_extra/23486_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// Regression test for http://dartbug.com/23486/
+// Regression test for http://dartbug.com/23486
 //
 // Dart2js used to crash when using `super` and prefixes inside parenthesized
 // expressions.
diff --git a/tests/compiler/dart2js_extra/23804_test.dart b/tests/compiler/dart2js_extra/23804_test.dart
index fbcf965..32bb00b 100644
--- a/tests/compiler/dart2js_extra/23804_test.dart
+++ b/tests/compiler/dart2js_extra/23804_test.dart
@@ -2,7 +2,8 @@
 // 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.
 
-// Regression test for http://dartbug.com/23804/
+// Regression test for http://dartbug.com/23804
+//
 // Inference incorrectly assumed that `any` and `every` didn't escape the values
 // in the collections.
 
diff --git a/tests/compiler/dart2js_extra/23828_test.dart b/tests/compiler/dart2js_extra/23828_test.dart
index be5edd5..e2fbf7d 100644
--- a/tests/compiler/dart2js_extra/23828_test.dart
+++ b/tests/compiler/dart2js_extra/23828_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// Regression test for http://dartbug.com/23828/
+// Regression test for http://dartbug.com/23828
 // Used to fail when methods contain a name starting with `get`
 import 'package:expect/expect.dart';
 
diff --git a/tests/compiler/dart2js_extra/invalid_annotation_test.dart b/tests/compiler/dart2js_extra/invalid_annotation_test.dart
index ac7689a..fe68503 100644
--- a/tests/compiler/dart2js_extra/invalid_annotation_test.dart
+++ b/tests/compiler/dart2js_extra/invalid_annotation_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// Regression test for http://dartbug.com/23893/
+// Regression test for http://dartbug.com/23893
 //
 // Because annotations are parsed lazily, dart2js used to crash when an
 // annotation had a syntax error.
diff --git a/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart b/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
index ad09aef..d16c31c 100644
--- a/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
+++ b/tests/compiler/dart2js_extra/no_such_method_strong11_test.dart
@@ -5,7 +5,7 @@
 // dart2jsOptions=--strong
 
 // Regression test checking that nsm-forwarders do not get installed for private
-// members of other libraries. See  https://dartbug.com/33665
+// members of other libraries. See http://dartbug.com/33665
 
 import 'package:expect/expect.dart';
 import 'no_such_method_strong11_lib.dart';
diff --git a/tests/compiler/dart2js_extra/round_constant_folding_test.dart b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
index 9c0a1fe..2c786dd 100644
--- a/tests/compiler/dart2js_extra/round_constant_folding_test.dart
+++ b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
@@ -53,8 +53,9 @@
 const int PI3 = 0x1234;
 const int PI4 = 0x12345678;
 const int PI5 = 0x123456789AB;
-const int PI6 = 0x123456789ABCDEF;
-const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
+const int PI6 = 0x123456789ABCD00 + 0xEF;
+const int PI7 = 0x123456789ABCD * 0x1234567 * 0x1234567 * 0x1234567;
+//const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
 
 const int NI1 = 0 - PI1;
 const int NI2 = -PI2;
diff --git a/tests/compiler/dart2js_extra/rti/canonical_recipe_test.dart b/tests/compiler/dart2js_extra/rti/canonical_recipe_test.dart
new file mode 100644
index 0000000..856ca7a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/canonical_recipe_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+final universe = rti.testingCreateUniverse();
+
+main() {
+  test('@', '@');
+  test('~', '~');
+  test('0&', '0&');
+  test('1&', '1&');
+  test('int', 'int');
+  test('int/', 'int/');
+  test('List<int>', 'List<int>');
+  test('Foo<bool,Bar<int,double>>', 'Foo<bool,Bar<int,double>>');
+  test('@;<int,bool>', '@<int><bool>');
+}
+
+String canonicalize(String recipe) {
+  var t = rti.testingUniverseEval(universe, recipe);
+  return rti.testingCanonicalRecipe(t);
+}
+
+void test(String expected, String recipe) =>
+    Expect.equals(expected, canonicalize(recipe));
diff --git a/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart b/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart
new file mode 100644
index 0000000..7d4be33
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/recipe_syntax_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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 'dart:_recipe_syntax';
+
+main() {
+  Recipe.testEquivalence();
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_1_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_1_test.dart
new file mode 100644
index 0000000..1eb67ab
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_1_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class GenericThingy<A, B> {
+  toString() => 'GenericThingy<$A, $B>';
+}
+
+main() {
+  var rti1 = rti.instanceType(1);
+  Expect.equals('JSInt', rti.testingRtiToString(rti1));
+
+  var rti2 = rti.instanceType('Hello');
+  Expect.equals('JSString', rti.testingRtiToString(rti2));
+
+  var rti3 = rti.instanceType(Thingy());
+  Expect.equals('Thingy', rti.testingRtiToString(rti3));
+
+  var rti4 = rti.instanceType(GenericThingy<String, int>());
+  Expect.equals('GenericThingy<String, int>', rti.testingRtiToString(rti4));
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart
new file mode 100644
index 0000000..69b352a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_2_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+Type grab<T>() => T;
+
+@pragma('dart2js:noInline')
+Type grabList<T>() => grab<List<T>>();
+
+main() {
+  Expect.equals('int', grab<int>().toString());
+
+  Expect.identical(int, grab<int>());
+  Expect.identical(dynamic, grab<dynamic>());
+  Expect.identical(Object, grab<Object>());
+  Expect.identical(Null, grab<Null>());
+
+  Expect.equals('List<int>', grabList<int>().toString());
+  Expect.equals('List<Null>', grabList<Null>().toString());
+
+  Expect.equals('List<dynamic>', (List).toString());
+
+  Expect.equals('dynamic', (dynamic).toString());
+  Expect.equals('Object', (Object).toString());
+  Expect.equals('Null', (Null).toString());
+
+  Expect.equals(List, grabList<dynamic>());
+}
diff --git a/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart b/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart
new file mode 100644
index 0000000..7d8d51e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/runtime_type_3_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+import "dart:_foreign_helper" show JS;
+
+main() {
+  Expect.equals('JSArray<int>', <int>[].runtimeType.toString());
+
+  // TODO(35084): An 'any' type would make JS-interop easier to use.
+  Expect.equals('JSArray<dynamic>', JS('', '[]').runtimeType.toString());
+}
diff --git a/tests/compiler/dart2js_extra/rti/simple_is_test.dart b/tests/compiler/dart2js_extra/rti/simple_is_test.dart
new file mode 100644
index 0000000..7c7aafa
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/simple_is_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2019, 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.
+//
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class Generic<AA> {
+  checkMethod(o) => o is AA;
+}
+
+@pragma('dart2js:noInline')
+void check<T>(o) {
+  Expect.isTrue(o is T);
+  Expect.isFalse(o is! T);
+}
+
+main() {
+  check<Thingy>(Thingy());
+
+  check<Generic<int>>(Generic<int>());
+
+  check<Generic<dynamic>>(Generic<dynamic>());
+  check<Generic<Object>>(Generic<Object>());
+  check<Generic<Object>>(Generic<dynamic>());
+  check<Generic<dynamic>>(Generic<Object>());
+
+  Expect.isTrue(Generic<Thingy>().checkMethod(Thingy()));
+  Expect.isTrue(Generic<Object>().checkMethod(Object()));
+  Expect.isTrue(Generic<Object>().checkMethod(Thingy()));
+  Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+  Expect.isTrue(Generic<dynamic>().checkMethod(Object()));
+
+  Expect.isFalse(Generic<Thingy>().checkMethod(123));
+  Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+}
diff --git a/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart b/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart
new file mode 100644
index 0000000..064327f
--- /dev/null
+++ b/tests/compiler/dart2js_extra/rti/simple_type_bound_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2019, 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.
+//
+// dart2jsOptions=--experiment-new-rti
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+dynamic makeFunction(x) {
+  // Return a local function since that does not require any tear-off code.
+  dynamic foo<U extends V, V extends num>() {
+    // Returning x ensures this is a local function and will not be optimized to
+    // a static tear-off.
+    return x;
+  }
+
+  return foo;
+}
+
+@pragma('dart2js:noInline')
+void test(dynamic action, bool expectThrows) {
+  // Don't use Expect.throws because it is hard to call without implicit type
+  // checks.
+  try {
+    // There is no type check here, just a dynamic 'call' selector.
+    action();
+  } catch (e, st) {
+    if (expectThrows) return;
+    Expect.fail('Should throw');
+    return;
+  }
+  if (expectThrows) {
+    Expect.fail('Did not throw');
+  }
+}
+
+main() {
+  dynamic f = makeFunction(123);
+
+  test(() => f<String, int>(), true);
+  test(() => f<num, num>(), false);
+}
diff --git a/tests/compiler/dart2js_extra/rti/subtype_test.dart b/tests/compiler/dart2js_extra/rti/subtype_test.dart
index 91fb5b5..c90f0f7 100644
--- a/tests/compiler/dart2js_extra/rti/subtype_test.dart
+++ b/tests/compiler/dart2js_extra/rti/subtype_test.dart
@@ -2,32 +2,106 @@
 // 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 'dart:_foreign_helper' show JS, JS_GET_NAME;
+import 'dart:_js_embedded_names' show JsGetName;
 import 'dart:_rti' as rti;
 import "package:expect/expect.dart";
 
+final String objectName = JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
+final String futureName = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+final String nullName = JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+const typeRulesJson = r'''
+{
+  "int": {"num": []},
+  "List": {"Iterable": ["1"]},
+  "CodeUnits": {
+    "List": ["int"],
+    "Iterable": ["int"]
+  }
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+final universe = rti.testingCreateUniverse();
+
 main() {
-  testCodeUnits();
+  rti.testingAddRules(universe, typeRules);
+  runTests();
+  runTests(); // Ensure caching didn't change anything.
 }
 
-void testCodeUnits() {
-  var universe = rti.testingCreateUniverse();
+void runTests() {
+  testInterfaces();
+  testTopTypes();
+  testNull();
+  testFutureOr();
+}
 
-  var intRule = rti.testingCreateRule();
-  rti.testingAddSupertype(intRule, 'num', []);
+void testInterfaces() {
+  strictSubtype('List<CodeUnits>', 'Iterable<List<int>>');
+  strictSubtype('CodeUnits', 'Iterable<num>');
+  strictSubtype('Iterable<int>', 'Iterable<num>');
+  unrelated('int', 'CodeUnits');
+  equivalent('double', 'double');
+  equivalent('List<int>', 'List<int>');
+}
 
-  var listRule = rti.testingCreateRule();
-  rti.testingAddSupertype(listRule, 'Iterable', ['1']);
+void testTopTypes() {
+  strictSubtype('List<int>', objectName);
+  equivalent(objectName, objectName);
+  equivalent('@', '@');
+  equivalent('~', '~');
+  equivalent('1&', '1&');
+  equivalent(objectName, '@');
+  equivalent(objectName, '~');
+  equivalent(objectName, '1&');
+  equivalent('@', '~');
+  equivalent('@', '1&');
+  equivalent('~', '1&');
+  equivalent('List<$objectName>', 'List<@>');
+  equivalent('List<$objectName>', 'List<~>');
+  equivalent('List<$objectName>', 'List<1&>');
+  equivalent('List<@>', 'List<~>');
+  equivalent('List<@>', 'List<1&>');
+  equivalent('List<~>', 'List<1&>');
+}
 
-  var codeUnitsRule = rti.testingCreateRule();
-  rti.testingAddSupertype(codeUnitsRule, 'List', ['int']);
+void testNull() {
+  strictSubtype(nullName, 'int');
+  strictSubtype(nullName, 'Iterable<CodeUnits>');
+  strictSubtype(nullName, objectName);
+  equivalent(nullName, nullName);
+}
 
-  rti.testingAddRule(universe, 'int', intRule);
-  rti.testingAddRule(universe, 'List', listRule);
-  rti.testingAddRule(universe, 'CodeUnits', codeUnitsRule);
+void testFutureOr() {
+  strictSubtype('$futureName<int>', '$futureName<num>');
+  strictSubtype('int', 'int/');
+  strictSubtype('$futureName<int>', 'int/');
+  strictSubtype('int/', 'num/');
+  strictSubtype('int', 'num/');
+  strictSubtype('$futureName<int>', 'num/');
+  equivalent('@/', '~/');
+}
 
-  var rti1 = rti.testingUniverseEval(universe, 'List<CodeUnits>');
-  var rti2 = rti.testingUniverseEval(universe, 'Iterable<List<int>>');
+String reason(String s, String t) => "$s <: $t";
 
-  Expect.isTrue(rti.testingIsSubtype(universe, rti1, rti2));
-  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+void strictSubtype(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void unrelated(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isFalse(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void equivalent(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isTrue(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
 }
diff --git a/tests/compiler/dart2js_extra/type_argument_optimization_test.dart b/tests/compiler/dart2js_extra/type_argument_optimization_test.dart
new file mode 100644
index 0000000..21b41c5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/type_argument_optimization_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2019, 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.
+
+// Regression test for issue 37267.
+
+typedef UpdateShouldNotify<T> = bool Function(T previous, T current);
+
+typedef ValueWidgetBuilder<T> = Widget Function(
+    BuildContext context, T value, Widget child);
+
+class BuildContext {}
+
+class Widget {}
+
+abstract class ProxyWidget extends Widget {
+  final Widget child;
+
+  ProxyWidget({this.child});
+}
+
+abstract class InheritedWidget extends ProxyWidget {
+  InheritedWidget({Widget child}) : super(child: child);
+}
+
+class InheritedProvider<T> extends InheritedWidget {
+  final T _value;
+  final UpdateShouldNotify<T> _updateShouldNotify;
+
+  InheritedProvider(
+      {T value, UpdateShouldNotify<T> updateShouldNotify, Widget child})
+      : _value = value,
+        _updateShouldNotify = updateShouldNotify,
+        super(child: child);
+}
+
+class StateDelegate {}
+
+abstract class ValueStateDelegate<T> extends StateDelegate {
+  T get value;
+}
+
+class ValueStateDelegateImpl<T> implements ValueStateDelegate<T> {
+  final T value;
+
+  ValueStateDelegateImpl(this.value);
+}
+
+class DelegateWidget {
+  final StateDelegate delegate;
+
+  DelegateWidget(this.delegate);
+}
+
+abstract class Listenable {}
+
+abstract class ValueListenable<T> extends Listenable {
+  T get value;
+}
+
+class ValueListenableImpl<T> implements ValueListenable<T> {
+  final T value;
+
+  ValueListenableImpl(this.value);
+}
+
+class ValueDelegateWidget<T> extends DelegateWidget {
+  ValueDelegateWidget(ValueStateDelegate<T> delegate) : super(delegate);
+
+  @pragma('dart2js:tryInline')
+  ValueStateDelegate<T> get delegate => super.delegate as ValueStateDelegate<T>;
+}
+
+class ValueListenableProvider<T>
+    extends ValueDelegateWidget<ValueListenable<T>> {
+  final Widget child;
+
+  final UpdateShouldNotify<T> updateShouldNotify;
+
+  ValueListenableProvider(ValueStateDelegate<ValueListenable<T>> delegate,
+      this.updateShouldNotify, this.child)
+      : super(delegate);
+
+  Widget build() {
+    return ValueListenableBuilder<T>(
+      valueListenable: delegate.value,
+      builder: (_, value, child) {
+        return InheritedProvider<T>(
+          value: value,
+          updateShouldNotify: updateShouldNotify,
+          child: child,
+        );
+      },
+      child: child,
+    );
+  }
+}
+
+class ValueListenableBuilder<T> extends Widget {
+  final ValueListenable<T> valueListenable;
+  final ValueWidgetBuilder<T> builder;
+  final Widget child;
+
+  ValueListenableBuilder({this.valueListenable, this.builder, this.child});
+}
+
+void main() {
+  print(create(42).valueListenable.value);
+  print(create('foo').valueListenable.value);
+}
+
+ValueListenableBuilder<T> create<T>(T value) {
+  ValueListenableImpl<T> valueListenable = new ValueListenableImpl<T>(value);
+  ValueStateDelegateImpl<ValueListenable<T>> valueStateDelegate =
+      new ValueStateDelegateImpl<ValueListenable<T>>(valueListenable);
+  ValueListenableProvider<T> valueListenableProvider =
+      new ValueListenableProvider<T>(valueStateDelegate, null, null);
+  Widget widget = valueListenableProvider.build();
+  print(value);
+  return widget;
+}
diff --git a/tests/compiler/dart2js_extra/typed_locals_test.dart b/tests/compiler/dart2js_extra/typed_locals_test.dart
deleted file mode 100644
index 86ba926..0000000
--- a/tests/compiler/dart2js_extra/typed_locals_test.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, 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.
-
-void main() {
-  String s = 3;
-  int i = 'hestfisk';
-  void v;
-}
diff --git a/tests/compiler/dart2js_extra/unused_local_const_test.dart b/tests/compiler/dart2js_extra/unused_local_const_test.dart
new file mode 100644
index 0000000..acd2076
--- /dev/null
+++ b/tests/compiler/dart2js_extra/unused_local_const_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, 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.
+
+// dart2jsOptions=--enable-experiment=constant-update-2018
+
+class A {
+  const A();
+
+  A operator -() => this;
+}
+
+main() {
+  const a = const A();
+  const c = //# 01: compile-time error
+      const bool.fromEnvironment('foo') ? null : -a; //# 01: continued
+}
diff --git a/tests/compiler/dartdevc_native/subtype_test.dart b/tests/compiler/dartdevc_native/subtype_test.dart
new file mode 100644
index 0000000..4a14499
--- /dev/null
+++ b/tests/compiler/dartdevc_native/subtype_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, 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";
+import 'dart:_foreign_helper' show JS;
+import 'dart:_runtime' as dart;
+
+class A {}
+
+class B extends A {}
+
+class C extends B {}
+
+class D<T extends B> {}
+
+// Returns sWrapped<tWrapped> as a wrapped type.
+Object generic1(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  var sGeneric = dart.getGenericClass(s);
+  return dart.wrapType(JS('', '#(#)', sGeneric, t));
+}
+
+void checkSubtype(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  Expect.isTrue(dart.isSubtypeOf(s, t));
+}
+
+void checkProperSubtype(Type sWrapped, Type tWrapped) {
+  var s = dart.unwrapType(sWrapped);
+  var t = dart.unwrapType(tWrapped);
+  Expect.isTrue(dart.isSubtypeOf(s, t));
+  Expect.isFalse(dart.isSubtypeOf(t, s));
+}
+
+void main() {
+  checkProperSubtype(B, A);
+  checkProperSubtype(C, B);
+  checkProperSubtype(C, A);
+
+  checkSubtype(D, generic1(D, B));
+  checkSubtype(generic1(D, B), D);
+  checkProperSubtype(generic1(D, C), generic1(D, B));
+}
diff --git a/tests/corelib_2/bigint_test.dart b/tests/corelib_2/bigint_test.dart
index 89b361b..bffa4c9 100644
--- a/tests/corelib_2/bigint_test.dart
+++ b/tests/corelib_2/bigint_test.dart
@@ -771,11 +771,13 @@
   Expect.equals(BigInt.zero, BigInt.zero >> 1234567890);
   Expect.equals(BigInt.two.pow(999), BigInt.one << 999);
   Expect.equals(BigInt.one, BigInt.two.pow(999) >> 999);
-  Expect.equals(BigInt.zero, new BigInt.from(12) >> 0x7FFFFFFFFFFFFFFF);
-  Expect.equals(-BigInt.one, -new BigInt.from(12) >> 0x7FFFFFFFFFFFFFFF);
+  // 0x7FFFFFFFFFFFFFFF on VM, slightly rounded up on web platform.
+  const int maxInt64 = 0x7FFFFFFFFFFFF000 + 0xFFF;
+  Expect.equals(BigInt.zero, new BigInt.from(12) >> maxInt64);
+  Expect.equals(-BigInt.one, -new BigInt.from(12) >> maxInt64);
   bool exceptionCaught = false;
   try {
-    var a = BigInt.one << 0x7FFFFFFFFFFFFFFF;
+    var a = BigInt.one << maxInt64;
   } on OutOfMemoryError catch (e) {
     exceptionCaught = true;
   } catch (e) {
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index b196c6f..c58a56d 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -16,33 +16,20 @@
 
 [ $compiler == dart2js ]
 bigint_from_test: RuntimeError # Issue 32589
-bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 core_runtime_types_test: RuntimeError # Issue 34147
 date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
-date_time_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_ceil_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_floor_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 error_stack_trace1_test: RuntimeError # Issue 12399
-growable_list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-growable_list_test: RuntimeError # Concurrent modifications test always runs
-int_ceil_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_ceil_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_parse_radix_int64_test/02: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_parse_radix_test/01: RuntimeError
-int_round_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_round_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_to_int_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_to_radix_string_test/01: RuntimeError
@@ -54,7 +41,6 @@
 list_unmodifiable_test: Pass, RuntimeError # Issue 28712
 num_parse_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 num_parse_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-num_sign_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 
 [ $compiler != dartdevc ]
 error_stack_trace_test/static: MissingCompileTimeError
@@ -70,11 +56,21 @@
 bool_from_environment2_test/03: MissingCompileTimeError
 string_from_environment3_test/03: MissingCompileTimeError
 
-[ $compiler == precompiler ]
-bigint_test: Pass, Timeout # --no_intrinsify
-int_parse_radix_test: Pass, Timeout # --no_intrinsify
-integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
-regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
+[ $compiler == none ]
+int_parse_radix_bad_handler_test: MissingCompileTimeError
+symbol_operator_test/03: Fail # Issue 11669
+symbol_reserved_word_test/02: CompileTimeError # Issue 20191
+symbol_reserved_word_test/04: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/06: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_reserved_word_test/07: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/09: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_reserved_word_test/10: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
+symbol_reserved_word_test/12: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_test/01: Fail, Pass # Issue 11669
+symbol_test/02: MissingCompileTimeError # Issue 11669
+symbol_test/03: MissingCompileTimeError # Issue 11669
+symbol_test/none: Fail # Issue 11669
+unicode_test: Fail # Issue 6706
 
 [ $mode == debug ]
 regexp/pcre_test: Pass, Slow # Issue 22008
@@ -184,7 +180,6 @@
 [ $compiler == dart2js && $minified ]
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
-growable_list_test: RuntimeError # Concurrent modifications test always runs
 hash_set_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(_CustomHashSet.#x), local(_CustomHashSet.#)) for j:closure_call(_CustomHashSet__CustomHashSet_closure.call).
 integer_to_radix_string_test/01: RuntimeError
 integer_to_radix_string_test/02: RuntimeError
@@ -235,9 +230,11 @@
 iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
 string_base_vm_static_test: MissingCompileTimeError
 
-[ $compiler == precompiler && $runtime == dart_precompiled && !$checked ]
-iterable_generate_test/01: RuntimeError
-splay_tree_from_iterable_test: RuntimeError
+# We no longer expect Dart2 tests to run with the standalone VM without the new
+# common front end, but for now we get better coverage by still running them in
+# checked mode, which is mostly Dart2-compatible.
+[ $compiler == none && !$checked && ($runtime == dart_precompiled || $runtime == vm) ]
+*: SkipByDesign
 
 [ $mode == release && $hot_reload && ($compiler == dartk || $compiler == dartkb) ]
 bigint_parse_radix_test: Crash
@@ -271,12 +268,6 @@
 symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
 unicode_test: RuntimeError # Issue 18061: German double S.
 
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
-*: SkipByDesign
-
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
@@ -290,52 +281,10 @@
 [ $arch == simdbc || $arch == simdbc64 ]
 regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
 
-[ $compiler == app_jit || $compiler == none || $compiler == precompiler ]
-int_parse_radix_bad_handler_test: MissingCompileTimeError
-symbol_operator_test/03: Fail # Issue 11669
-symbol_reserved_word_test/02: CompileTimeError # Issue 20191
-symbol_reserved_word_test/04: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/06: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/07: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/09: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_reserved_word_test/10: MissingCompileTimeError # Issue 11669, 19972, With the exception of 'void', const Symbol() should not accept reserved words.
-symbol_reserved_word_test/12: RuntimeError # Issue 11669, With the exception of 'void', new Symbol() should not accept reserved words.
-symbol_test/01: Fail, Pass # Issue 11669
-symbol_test/02: MissingCompileTimeError # Issue 11669
-symbol_test/03: MissingCompileTimeError # Issue 11669
-symbol_test/none: Fail # Issue 11669
-unicode_test: Fail # Issue 6706
-
-[ $compiler == app_jit || $compiler == precompiler ]
-from_environment_const_type_test/02: MissingCompileTimeError
-from_environment_const_type_test/03: MissingCompileTimeError
-from_environment_const_type_test/04: MissingCompileTimeError
-from_environment_const_type_test/06: MissingCompileTimeError
-from_environment_const_type_test/07: MissingCompileTimeError
-from_environment_const_type_test/08: MissingCompileTimeError
-from_environment_const_type_test/09: MissingCompileTimeError
-from_environment_const_type_test/11: MissingCompileTimeError
-from_environment_const_type_test/12: MissingCompileTimeError
-from_environment_const_type_test/13: MissingCompileTimeError
-from_environment_const_type_test/14: MissingCompileTimeError
-from_environment_const_type_test/16: MissingCompileTimeError
-from_environment_const_type_undefined_test/02: MissingCompileTimeError
-from_environment_const_type_undefined_test/03: MissingCompileTimeError
-from_environment_const_type_undefined_test/04: MissingCompileTimeError
-from_environment_const_type_undefined_test/06: MissingCompileTimeError
-from_environment_const_type_undefined_test/07: MissingCompileTimeError
-from_environment_const_type_undefined_test/08: MissingCompileTimeError
-from_environment_const_type_undefined_test/09: MissingCompileTimeError
-from_environment_const_type_undefined_test/11: MissingCompileTimeError
-from_environment_const_type_undefined_test/12: MissingCompileTimeError
-from_environment_const_type_undefined_test/13: MissingCompileTimeError
-from_environment_const_type_undefined_test/14: MissingCompileTimeError
-from_environment_const_type_undefined_test/16: MissingCompileTimeError
-iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
-
 [ $compiler == dartdevc || $compiler == dartdevk ]
 bigint_from_test: RuntimeError # Issue 32589
-bigint_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
+bigint_test/03: SkipSlow # modPow is very slow
+bigint_test/15: SkipSlow # modPow is very slow
 bit_twiddling_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 compare_to2_test: RuntimeError # Issue 30170
 compare_to2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -346,12 +295,7 @@
 double_round_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_truncate_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 error_stack_trace_test/nullThrown: RuntimeError # .stackTrace not present for exception caught from 'throw null;'
-growable_list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 hash_set_test/01: RuntimeError # Issue 29921
-int_ceil_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_ceil_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_floor_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_from_environment_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_modulo_arith_test/none: RuntimeError # Issue 29921
 int_parse_radix_int64_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -360,11 +304,6 @@
 int_parse_radix_int64_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 int_parse_radix_test/01: RuntimeError # Issue 29921
 int_parse_with_limited_ints_test: Skip # Requires fixed-size int64 support.
-int_round_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_round_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_to_int_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int_truncate_to_double_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/modPow: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 integer_arith_vm_test/modPow: RuntimeError # Issue 30170
 integer_arith_vm_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -379,7 +318,6 @@
 nan_infinity_test/01: RuntimeError # Issue 29921
 num_parse_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 num_parse_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-num_sign_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 regexp/alternative-length-miscalculation_test: RuntimeError # Issue 29921
 regexp/ascii-regexp-subject_test: RuntimeError # Issue 29921
 regexp/bol-with-multiline_test: RuntimeError # Issue 29921
diff --git a/tests/corelib_2/date_time_extremes_test.dart b/tests/corelib_2/date_time_extremes_test.dart
new file mode 100644
index 0000000..05563d1
--- /dev/null
+++ b/tests/corelib_2/date_time_extremes_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2012, 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";
+
+// Dart test program for DateTime, extreme values.
+
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+// Identical to _maxMillisecondsSinceEpoch in date_time.dart
+const int _MAX_MILLISECONDS = 8640000000000000;
+
+void testExtremes() {
+  var dt =
+      new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+  Expect.equals(275760, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(13, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+  Expect.equals(-271821, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(20, dt.day);
+  Expect.equals(0, dt.hour);
+  Expect.equals(0, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+  // Make sure that we can build the extreme dates in local too.
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(-_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
+      _MAX_MILLISECONDS + 1,
+      isUtc: true));
+  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
+      -_MAX_MILLISECONDS - 1,
+      isUtc: true));
+  Expect.throws(
+      () => new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS + 1));
+  Expect.throws(
+      () => new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS - 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+  Expect.throws(
+      () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() =>
+      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+  Expect.throws(
+      () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() =>
+      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      _MAX_MILLISECONDS * 1000 + 1,
+      isUtc: true));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      -_MAX_MILLISECONDS * 1000 - 1,
+      isUtc: true));
+  Expect.throws(() =>
+      new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000 + 1));
+  Expect.throws(() =>
+      new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000 - 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+  Expect.throws(() =>
+      new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() =>
+      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+  Expect.throws(() =>
+      new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() => new DateTime.utc(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
+}
+
+void main() {
+  testExtremes();
+}
diff --git a/tests/corelib_2/date_time_far_away_dates_test.dart b/tests/corelib_2/date_time_far_away_dates_test.dart
new file mode 100644
index 0000000..ba7104f
--- /dev/null
+++ b/tests/corelib_2/date_time_far_away_dates_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2019, 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";
+
+// Dart test program for DateTime, far away dates.
+
+// TODO(37442): Find far-away dates with milliseconds-since-epoch values that
+// are 'web' integers.
+
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+void testFarAwayDates() {
+  DateTime dt =
+      new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(27, dt.day);
+  Expect.equals(1, dt.hour);
+  Expect.equals(46, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(5, dt.day);
+  Expect.equals(22, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+  // Same with local zone.
+  dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(true, dt.day == 27 || dt.day == 26);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 46 % 15);
+  Expect.equals(40, dt.second);
+  Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(true, 5 == dt.day || 6 == dt.day);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 13);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  if (!supportsMicroseconds) return;
+  dt =
+      new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(27, dt.day);
+  Expect.equals(1, dt.hour);
+  Expect.equals(46, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001,
+      isUtc: true);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(5, dt.day);
+  Expect.equals(22, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+  // Same with local zone.
+  dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(true, dt.day == 27 || dt.day == 26);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 46 % 15);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(true, 5 == dt.day || 6 == dt.day);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 13);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+}
+
+void main() {
+  testFarAwayDates();
+}
diff --git a/tests/corelib_2/date_time_test.dart b/tests/corelib_2/date_time_test.dart
index 07a920d..e782ca5 100644
--- a/tests/corelib_2/date_time_test.dart
+++ b/tests/corelib_2/date_time_test.dart
@@ -49,96 +49,6 @@
   Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
 }
 
-void testFarAwayDates() {
-  DateTime dt =
-      new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
-  Expect.equals(33658, dt.year);
-  Expect.equals(9, dt.month);
-  Expect.equals(27, dt.day);
-  Expect.equals(1, dt.hour);
-  Expect.equals(46, dt.minute);
-  Expect.equals(40, dt.second);
-  Expect.equals(1, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
-  Expect.equals(-29719, dt.year);
-  Expect.equals(4, dt.month);
-  Expect.equals(5, dt.day);
-  Expect.equals(22, dt.hour);
-  Expect.equals(13, dt.minute);
-  Expect.equals(19, dt.second);
-  Expect.equals(999, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-  // Same with local zone.
-  dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
-  Expect.equals(33658, dt.year);
-  Expect.equals(9, dt.month);
-  Expect.equals(true, dt.day == 27 || dt.day == 26);
-  // Not much we can test for local hour.
-  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-  // Timezones can have offsets down to 15 minute.
-  Expect.equals(true, dt.minute % 15 == 46 % 15);
-  Expect.equals(40, dt.second);
-  Expect.equals(1, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-  dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
-  Expect.equals(-29719, dt.year);
-  Expect.equals(4, dt.month);
-  Expect.equals(true, 5 == dt.day || 6 == dt.day);
-  // Not much we can test for local hour.
-  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-  // Timezones can have offsets down to 15 minute.
-  Expect.equals(true, dt.minute % 15 == 13);
-  Expect.equals(19, dt.second);
-  Expect.equals(999, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-
-  if (!supportsMicroseconds) return;
-  dt =
-      new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
-  Expect.equals(33658, dt.year);
-  Expect.equals(9, dt.month);
-  Expect.equals(27, dt.day);
-  Expect.equals(1, dt.hour);
-  Expect.equals(46, dt.minute);
-  Expect.equals(40, dt.second);
-  Expect.equals(0, dt.millisecond);
-  Expect.equals(1, dt.microsecond);
-  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001,
-      isUtc: true);
-  Expect.equals(-29719, dt.year);
-  Expect.equals(4, dt.month);
-  Expect.equals(5, dt.day);
-  Expect.equals(22, dt.hour);
-  Expect.equals(13, dt.minute);
-  Expect.equals(19, dt.second);
-  Expect.equals(999, dt.millisecond);
-  Expect.equals(999, dt.microsecond);
-  // Same with local zone.
-  dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
-  Expect.equals(33658, dt.year);
-  Expect.equals(9, dt.month);
-  Expect.equals(true, dt.day == 27 || dt.day == 26);
-  // Not much we can test for local hour.
-  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-  // Timezones can have offsets down to 15 minute.
-  Expect.equals(true, dt.minute % 15 == 46 % 15);
-  Expect.equals(40, dt.second);
-  Expect.equals(0, dt.millisecond);
-  Expect.equals(1, dt.microsecond);
-  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
-  Expect.equals(-29719, dt.year);
-  Expect.equals(4, dt.month);
-  Expect.equals(true, 5 == dt.day || 6 == dt.day);
-  // Not much we can test for local hour.
-  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
-  // Timezones can have offsets down to 15 minute.
-  Expect.equals(true, dt.minute % 15 == 13);
-  Expect.equals(19, dt.second);
-  Expect.equals(999, dt.millisecond);
-  Expect.equals(999, dt.microsecond);
-}
-
 void testEquivalentYears() {
   // All hardcoded values come from V8. This means that the values are not
   // necessarily correct (see limitations of DateTime object in
@@ -363,88 +273,6 @@
   Expect.equals(0, dt.microsecond);
 }
 
-void testExtremes() {
-  var dt =
-      new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
-  Expect.equals(275760, dt.year);
-  Expect.equals(9, dt.month);
-  Expect.equals(13, dt.day);
-  Expect.equals(0, dt.hour);
-  Expect.equals(0, dt.minute);
-  Expect.equals(0, dt.second);
-  Expect.equals(0, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
-  Expect.equals(-271821, dt.year);
-  Expect.equals(4, dt.month);
-  Expect.equals(20, dt.day);
-  Expect.equals(0, dt.hour);
-  Expect.equals(0, dt.minute);
-  Expect.equals(0, dt.second);
-  Expect.equals(0, dt.millisecond);
-  Expect.equals(0, dt.microsecond);
-  // Make sure that we can build the extreme dates in local too.
-  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
-  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-  Expect.equals(_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
-  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-  Expect.equals(-_MAX_MILLISECONDS, dt.millisecondsSinceEpoch);
-  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
-      _MAX_MILLISECONDS + 1,
-      isUtc: true));
-  Expect.throws(() => new DateTime.fromMillisecondsSinceEpoch(
-      -_MAX_MILLISECONDS - 1,
-      isUtc: true));
-  Expect.throws(
-      () => new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS + 1));
-  Expect.throws(
-      () => new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS - 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
-  Expect.throws(
-      () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
-  Expect.throws(() =>
-      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
-  Expect.throws(
-      () => new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
-  Expect.throws(() =>
-      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, -1));
-
-  if (!supportsMicroseconds) return;
-
-  dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
-  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-  Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
-  dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
-  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
-  Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
-  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
-      _MAX_MILLISECONDS * 1000 + 1,
-      isUtc: true));
-  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
-      -_MAX_MILLISECONDS * 1000 - 1,
-      isUtc: true));
-  Expect.throws(() =>
-      new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000 + 1));
-  Expect.throws(() =>
-      new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000 - 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
-  Expect.throws(() =>
-      new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
-  Expect.throws(() =>
-      new DateTime.utc(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, 1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
-  Expect.throws(() =>
-      new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
-  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
-  Expect.throws(() => new DateTime.utc(
-      dt.year, dt.month, dt.day, dt.hour, dt.minute, 0, 0, -1));
-}
-
 void testUTCGetters() {
   var dt = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
   Expect.equals(2011, dt.year);
@@ -1372,8 +1200,6 @@
   testUnderflowAndOverflow();
   testDateStrings();
   testEquivalentYears();
-  testExtremes();
-  testFarAwayDates();
   testWeekday();
   testToStrings();
   testIsoString();
diff --git a/tests/corelib_2/growable_list_test.dart b/tests/corelib_2/growable_list_test.dart
index 8c3443ae..2172710 100644
--- a/tests/corelib_2/growable_list_test.dart
+++ b/tests/corelib_2/growable_list_test.dart
@@ -90,8 +90,8 @@
   testGrowable(new List<int>()..length = 5);
   testGrowable(new List<int>.filled(5, null, growable: true));
   Expect.throwsArgumentError(() => new List<int>(-1), "-1");
-  // There must be limits. Fix this test if we ever allow 10^30 elements.
-  Expect.throwsArgumentError(() => new List<int>(0x7fffffffffffffff), "bignum");
+  // There must be limits. Fix this test if we ever allow 2^63 elements.
+  Expect.throwsArgumentError(() => new List<int>(0x7ffffffffffff000), "bignum");
   Expect.throwsArgumentError(() => new List<int>(null), "null");
   testThrowsOrTypeError(
       () => new List([] as Object), // Cast to avoid warning.
diff --git a/tests/corelib_2/int_ceil_test.dart b/tests/corelib_2/int_ceil_test.dart
index 9b50dbd..731e15a 100644
--- a/tests/corelib_2/int_ceil_test.dart
+++ b/tests/corelib_2/int_ceil_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0, 0.ceil());
   Expect.equals(1, 1.ceil());
   Expect.equals(0x1234, 0x1234.ceil());
   Expect.equals(0x12345678, 0x12345678.ceil());
   Expect.equals(0x123456789AB, 0x123456789AB.ceil());
-  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.ceil());
-  Expect.equals(-1, -1.ceil());
-  Expect.equals(-0x1234, -0x1234.ceil());
-  Expect.equals(-0x12345678, -0x12345678.ceil());
-  Expect.equals(-0x123456789AB, -0x123456789AB.ceil());
-  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.ceil());
+  Expect.equals(big, big.ceil());
+  Expect.equals(-1, (-1).ceil());
+  Expect.equals(-0x1234, (-0x1234).ceil());
+  Expect.equals(-0x12345678, (-0x12345678).ceil());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).ceil());
+  Expect.equals(-big, (-big).ceil());
 
   Expect.isTrue(0.ceil() is int);
   Expect.isTrue(1.ceil() is int);
   Expect.isTrue(0x1234.ceil() is int);
   Expect.isTrue(0x12345678.ceil() is int);
   Expect.isTrue(0x123456789AB.ceil() is int);
-  Expect.isTrue(0x123456789ABCDEF.ceil() is int);
-  Expect.isTrue(-1.ceil() is int);
-  Expect.isTrue(-0x1234.ceil() is int);
-  Expect.isTrue(-0x12345678.ceil() is int);
-  Expect.isTrue(-0x123456789AB.ceil() is int);
-  Expect.isTrue(-0x123456789ABCDEF.ceil() is int);
+  Expect.isTrue(big.ceil() is int);
+  Expect.isTrue((-1).ceil() is int);
+  Expect.isTrue((-0x1234).ceil() is int);
+  Expect.isTrue((-0x12345678).ceil() is int);
+  Expect.isTrue((-0x123456789AB).ceil() is int);
+  Expect.isTrue((-big).ceil() is int);
 }
diff --git a/tests/corelib_2/int_ceil_to_double_test.dart b/tests/corelib_2/int_ceil_to_double_test.dart
index e31d298..0a35acb 100644
--- a/tests/corelib_2/int_ceil_to_double_test.dart
+++ b/tests/corelib_2/int_ceil_to_double_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0.0, 0.ceilToDouble());
   Expect.equals(1.0, 1.ceilToDouble());
   Expect.equals(0x1234, 0x1234.ceilToDouble());
   Expect.equals(0x12345678, 0x12345678.ceilToDouble());
   Expect.equals(0x123456789AB, 0x123456789AB.ceilToDouble());
-  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.ceilToDouble());
-  Expect.equals(-1.0, -1.ceilToDouble());
-  Expect.equals(-0x1234, -0x1234.ceilToDouble());
-  Expect.equals(-0x12345678, -0x12345678.ceilToDouble());
-  Expect.equals(-0x123456789AB, -0x123456789AB.ceilToDouble());
-  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.ceilToDouble());
+  Expect.equals(81985529216486900.0, big.ceilToDouble());
+  Expect.equals(-1.0, (-1).ceilToDouble());
+  Expect.equals(-0x1234, (-0x1234).ceilToDouble());
+  Expect.equals(-0x12345678, (-0x12345678).ceilToDouble());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).ceilToDouble());
+  Expect.equals(-81985529216486900.0, (-big).ceilToDouble());
 
   Expect.isTrue(0.ceilToDouble() is double);
   Expect.isTrue(1.ceilToDouble() is double);
   Expect.isTrue(0x1234.ceilToDouble() is double);
   Expect.isTrue(0x12345678.ceilToDouble() is double);
   Expect.isTrue(0x123456789AB.ceilToDouble() is double);
-  Expect.isTrue(0x123456789ABCDEF.ceilToDouble() is double);
-  Expect.isTrue(-1.ceilToDouble() is double);
-  Expect.isTrue(-0x1234.ceilToDouble() is double);
-  Expect.isTrue(-0x12345678.ceilToDouble() is double);
-  Expect.isTrue(-0x123456789AB.ceilToDouble() is double);
-  Expect.isTrue(-0x123456789ABCDEF.ceilToDouble() is double);
+  Expect.isTrue(big.ceilToDouble() is double);
+  Expect.isTrue((-1).ceilToDouble() is double);
+  Expect.isTrue((-0x1234).ceilToDouble() is double);
+  Expect.isTrue((-0x12345678).ceilToDouble() is double);
+  Expect.isTrue((-0x123456789AB).ceilToDouble() is double);
+  Expect.isTrue((-big).ceilToDouble() is double);
 }
diff --git a/tests/corelib_2/int_floor_test.dart b/tests/corelib_2/int_floor_test.dart
index 6588824..e85d5df 100644
--- a/tests/corelib_2/int_floor_test.dart
+++ b/tests/corelib_2/int_floor_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0, 0.floor());
   Expect.equals(1, 1.floor());
   Expect.equals(0x1234, 0x1234.floor());
   Expect.equals(0x12345678, 0x12345678.floor());
   Expect.equals(0x123456789AB, 0x123456789AB.floor());
-  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.floor());
-  Expect.equals(-1, -1.floor());
-  Expect.equals(-0x1234, -0x1234.floor());
-  Expect.equals(-0x12345678, -0x12345678.floor());
-  Expect.equals(-0x123456789AB, -0x123456789AB.floor());
-  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.floor());
+  Expect.equals(big, big.floor());
+  Expect.equals(-1, (-1).floor());
+  Expect.equals(-0x1234, (-0x1234).floor());
+  Expect.equals(-0x12345678, (-0x12345678).floor());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).floor());
+  Expect.equals(-big, (-big).floor());
 
   Expect.isTrue(0.floor() is int);
   Expect.isTrue(1.floor() is int);
   Expect.isTrue(0x1234.floor() is int);
   Expect.isTrue(0x12345678.floor() is int);
   Expect.isTrue(0x123456789AB.floor() is int);
-  Expect.isTrue(0x123456789ABCDEF.floor() is int);
-  Expect.isTrue(-1.floor() is int);
-  Expect.isTrue(-0x1234.floor() is int);
-  Expect.isTrue(-0x12345678.floor() is int);
-  Expect.isTrue(-0x123456789AB.floor() is int);
-  Expect.isTrue(-0x123456789ABCDEF.floor() is int);
+  Expect.isTrue(big.floor() is int);
+  Expect.isTrue((-1).floor() is int);
+  Expect.isTrue((-0x1234).floor() is int);
+  Expect.isTrue((-0x12345678).floor() is int);
+  Expect.isTrue((-0x123456789AB).floor() is int);
+  Expect.isTrue((-big).floor() is int);
 }
diff --git a/tests/corelib_2/int_floor_to_double_test.dart b/tests/corelib_2/int_floor_to_double_test.dart
index 7510849..659b295 100644
--- a/tests/corelib_2/int_floor_to_double_test.dart
+++ b/tests/corelib_2/int_floor_to_double_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0.0, 0.floorToDouble());
   Expect.equals(1.0, 1.floorToDouble());
   Expect.equals(0x1234, 0x1234.floorToDouble());
   Expect.equals(0x12345678, 0x12345678.floorToDouble());
   Expect.equals(0x123456789AB, 0x123456789AB.floorToDouble());
-  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.floorToDouble());
-  Expect.equals(-1.0, -1.floorToDouble());
-  Expect.equals(-0x1234, -0x1234.floorToDouble());
-  Expect.equals(-0x12345678, -0x12345678.floorToDouble());
-  Expect.equals(-0x123456789AB, -0x123456789AB.floorToDouble());
-  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.floorToDouble());
+  Expect.equals(81985529216486900.0, big.floorToDouble());
+  Expect.equals(-1.0, (-1).floorToDouble());
+  Expect.equals(-0x1234, (-0x1234).floorToDouble());
+  Expect.equals(-0x12345678, (-0x12345678).floorToDouble());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).floorToDouble());
+  Expect.equals(-81985529216486900.0, (-big).floorToDouble());
 
   Expect.isTrue(0.floorToDouble() is double);
   Expect.isTrue(1.floorToDouble() is double);
   Expect.isTrue(0x1234.floorToDouble() is double);
   Expect.isTrue(0x12345678.floorToDouble() is double);
   Expect.isTrue(0x123456789AB.floorToDouble() is double);
-  Expect.isTrue(0x123456789ABCDEF.floorToDouble() is double);
-  Expect.isTrue(-1.floorToDouble() is double);
-  Expect.isTrue(-0x1234.floorToDouble() is double);
-  Expect.isTrue(-0x12345678.floorToDouble() is double);
-  Expect.isTrue(-0x123456789AB.floorToDouble() is double);
-  Expect.isTrue(-0x123456789ABCDEF.floorToDouble() is double);
+  Expect.isTrue(big.floorToDouble() is double);
+  Expect.isTrue((-1).floorToDouble() is double);
+  Expect.isTrue((-0x1234).floorToDouble() is double);
+  Expect.isTrue((-0x12345678).floorToDouble() is double);
+  Expect.isTrue((-0x123456789AB).floorToDouble() is double);
+  Expect.isTrue((-big).floorToDouble() is double);
 }
diff --git a/tests/corelib_2/int_round_test.dart b/tests/corelib_2/int_round_test.dart
index 21b1f7c..3e9a8ae 100644
--- a/tests/corelib_2/int_round_test.dart
+++ b/tests/corelib_2/int_round_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // truncating arithmetic on web.
+
   Expect.equals(0, 0.round());
   Expect.equals(1, 1.round());
   Expect.equals(0x1234, 0x1234.round());
   Expect.equals(0x12345678, 0x12345678.round());
   Expect.equals(0x123456789AB, 0x123456789AB.round());
-  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.round());
-  Expect.equals(-1, -1.round());
-  Expect.equals(-0x1234, -0x1234.round());
-  Expect.equals(-0x12345678, -0x12345678.round());
-  Expect.equals(-0x123456789AB, -0x123456789AB.round());
-  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.round());
+  Expect.equals(big, big.round());
+  Expect.equals(-1, (-1).round());
+  Expect.equals(-0x1234, (-0x1234).round());
+  Expect.equals(-0x12345678, (-0x12345678).round());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).round());
+  Expect.equals(-big, (-big).round());
 
   Expect.isTrue(0.round() is int);
   Expect.isTrue(1.round() is int);
   Expect.isTrue(0x1234.round() is int);
   Expect.isTrue(0x12345678.round() is int);
   Expect.isTrue(0x123456789AB.round() is int);
-  Expect.isTrue(0x123456789ABCDEF.round() is int);
-  Expect.isTrue(-1.round() is int);
-  Expect.isTrue(-0x1234.round() is int);
-  Expect.isTrue(-0x12345678.round() is int);
-  Expect.isTrue(-0x123456789AB.round() is int);
-  Expect.isTrue(-0x123456789ABCDEF.round() is int);
+  Expect.isTrue(big.round() is int);
+  Expect.isTrue((-1).round() is int);
+  Expect.isTrue((-0x1234).round() is int);
+  Expect.isTrue((-0x12345678).round() is int);
+  Expect.isTrue((-0x123456789AB).round() is int);
+  Expect.isTrue((-big).round() is int);
 }
diff --git a/tests/corelib_2/int_round_to_double_test.dart b/tests/corelib_2/int_round_to_double_test.dart
index fdc6c94..b49cd94 100644
--- a/tests/corelib_2/int_round_to_double_test.dart
+++ b/tests/corelib_2/int_round_to_double_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0.0, 0.roundToDouble());
   Expect.equals(1.0, 1.roundToDouble());
   Expect.equals(0x1234, 0x1234.roundToDouble());
   Expect.equals(0x12345678, 0x12345678.roundToDouble());
   Expect.equals(0x123456789AB, 0x123456789AB.roundToDouble());
-  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.roundToDouble());
-  Expect.equals(-1.0, -1.roundToDouble());
-  Expect.equals(-0x1234, -0x1234.roundToDouble());
-  Expect.equals(-0x12345678, -0x12345678.roundToDouble());
-  Expect.equals(-0x123456789AB, -0x123456789AB.roundToDouble());
-  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.roundToDouble());
+  Expect.equals(81985529216486900.0, big.roundToDouble());
+  Expect.equals(-1.0, (-1).roundToDouble());
+  Expect.equals(-0x1234, (-0x1234).roundToDouble());
+  Expect.equals(-0x12345678, (-0x12345678).roundToDouble());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).roundToDouble());
+  Expect.equals(-81985529216486900.0, (-big).roundToDouble());
 
   Expect.isTrue(0.roundToDouble() is double);
   Expect.isTrue(1.roundToDouble() is double);
   Expect.isTrue(0x1234.roundToDouble() is double);
   Expect.isTrue(0x12345678.roundToDouble() is double);
   Expect.isTrue(0x123456789AB.roundToDouble() is double);
-  Expect.isTrue(0x123456789ABCDEF.roundToDouble() is double);
-  Expect.isTrue(-1.roundToDouble() is double);
-  Expect.isTrue(-0x1234.roundToDouble() is double);
-  Expect.isTrue(-0x12345678.roundToDouble() is double);
-  Expect.isTrue(-0x123456789AB.roundToDouble() is double);
-  Expect.isTrue(-0x123456789ABCDEF.roundToDouble() is double);
+  Expect.isTrue(big.roundToDouble() is double);
+  Expect.isTrue((-1).roundToDouble() is double);
+  Expect.isTrue((-0x1234).roundToDouble() is double);
+  Expect.isTrue((-0x12345678).roundToDouble() is double);
+  Expect.isTrue((-0x123456789AB).roundToDouble() is double);
+  Expect.isTrue((-big).roundToDouble() is double);
 }
diff --git a/tests/corelib_2/int_to_int_test.dart b/tests/corelib_2/int_to_int_test.dart
index ea3de36..065d357 100644
--- a/tests/corelib_2/int_to_int_test.dart
+++ b/tests/corelib_2/int_to_int_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0, 0.toInt());
   Expect.equals(1, 1.toInt());
   Expect.equals(0x1234, 0x1234.toInt());
   Expect.equals(0x12345678, 0x12345678.toInt());
   Expect.equals(0x123456789AB, 0x123456789AB.toInt());
-  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.toInt());
-  Expect.equals(-1, -1.toInt());
-  Expect.equals(-0x1234, -0x1234.toInt());
-  Expect.equals(-0x12345678, -0x12345678.toInt());
-  Expect.equals(-0x123456789AB, -0x123456789AB.toInt());
-  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.toInt());
+  Expect.equals(big, big.toInt());
+  Expect.equals(-1, (-1).toInt());
+  Expect.equals(-0x1234, (-0x1234).toInt());
+  Expect.equals(-0x12345678, (-0x12345678).toInt());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).toInt());
+  Expect.equals(-big, (-big).toInt());
 
   Expect.isTrue(0.toInt() is int);
   Expect.isTrue(1.toInt() is int);
   Expect.isTrue(0x1234.toInt() is int);
   Expect.isTrue(0x12345678.toInt() is int);
   Expect.isTrue(0x123456789AB.toInt() is int);
-  Expect.isTrue(0x123456789ABCDEF.toInt() is int);
-  Expect.isTrue(-1.toInt() is int);
-  Expect.isTrue(-0x1234.toInt() is int);
-  Expect.isTrue(-0x12345678.toInt() is int);
-  Expect.isTrue(-0x123456789AB.toInt() is int);
-  Expect.isTrue(-0x123456789ABCDEF.toInt() is int);
+  Expect.isTrue(big.toInt() is int);
+  Expect.isTrue((-1).toInt() is int);
+  Expect.isTrue((-0x1234).toInt() is int);
+  Expect.isTrue((-0x12345678).toInt() is int);
+  Expect.isTrue((-0x123456789AB).toInt() is int);
+  Expect.isTrue((-big).toInt() is int);
 }
diff --git a/tests/corelib_2/int_truncate_test.dart b/tests/corelib_2/int_truncate_test.dart
index 605241d..f26a856 100644
--- a/tests/corelib_2/int_truncate_test.dart
+++ b/tests/corelib_2/int_truncate_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0, 0.truncate());
   Expect.equals(1, 1.truncate());
   Expect.equals(0x1234, 0x1234.truncate());
   Expect.equals(0x12345678, 0x12345678.truncate());
   Expect.equals(0x123456789AB, 0x123456789AB.truncate());
-  Expect.equals(0x123456789ABCDEF, 0x123456789ABCDEF.truncate());
-  Expect.equals(-1, -1.truncate());
-  Expect.equals(-0x1234, -0x1234.truncate());
-  Expect.equals(-0x12345678, -0x12345678.truncate());
-  Expect.equals(-0x123456789AB, -0x123456789AB.truncate());
-  Expect.equals(-0x123456789ABCDEF, -0x123456789ABCDEF.truncate());
+  Expect.equals(big, big.truncate());
+  Expect.equals(-1, (-1).truncate());
+  Expect.equals(-0x1234, (-0x1234).truncate());
+  Expect.equals(-0x12345678, (-0x12345678).truncate());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).truncate());
+  Expect.equals(-big, (-big).truncate());
 
   Expect.isTrue(0.truncate() is int);
   Expect.isTrue(1.truncate() is int);
   Expect.isTrue(0x1234.truncate() is int);
   Expect.isTrue(0x12345678.truncate() is int);
   Expect.isTrue(0x123456789AB.truncate() is int);
-  Expect.isTrue(0x123456789ABCDEF.truncate() is int);
-  Expect.isTrue(-1.truncate() is int);
-  Expect.isTrue(-0x1234.truncate() is int);
-  Expect.isTrue(-0x12345678.truncate() is int);
-  Expect.isTrue(-0x123456789AB.truncate() is int);
-  Expect.isTrue(-0x123456789ABCDEF.truncate() is int);
+  Expect.isTrue(big.truncate() is int);
+  Expect.isTrue((-1).truncate() is int);
+  Expect.isTrue((-0x1234).truncate() is int);
+  Expect.isTrue((-0x12345678).truncate() is int);
+  Expect.isTrue((-0x123456789AB).truncate() is int);
+  Expect.isTrue((-big).truncate() is int);
 }
diff --git a/tests/corelib_2/int_truncate_to_double_test.dart b/tests/corelib_2/int_truncate_to_double_test.dart
index c2b7cc7..20b27d3 100644
--- a/tests/corelib_2/int_truncate_to_double_test.dart
+++ b/tests/corelib_2/int_truncate_to_double_test.dart
@@ -5,27 +5,29 @@
 import 'package:expect/expect.dart';
 
 main() {
+  const int big = 0x123456789AB0000 + 0xCDEF; // Slightly rounded on web.
+
   Expect.equals(0.0, 0.truncateToDouble());
   Expect.equals(1.0, 1.truncateToDouble());
   Expect.equals(0x1234, 0x1234.truncateToDouble());
   Expect.equals(0x12345678, 0x12345678.truncateToDouble());
   Expect.equals(0x123456789AB, 0x123456789AB.truncateToDouble());
-  Expect.equals(81985529216486900.0, 0x123456789ABCDEF.truncateToDouble());
-  Expect.equals(-1.0, -1.truncateToDouble());
-  Expect.equals(-0x1234, -0x1234.truncateToDouble());
-  Expect.equals(-0x12345678, -0x12345678.truncateToDouble());
-  Expect.equals(-0x123456789AB, -0x123456789AB.truncateToDouble());
-  Expect.equals(-81985529216486900.0, -0x123456789ABCDEF.truncateToDouble());
+  Expect.equals(81985529216486900.0, big.truncateToDouble());
+  Expect.equals(-1.0, (-1).truncateToDouble());
+  Expect.equals(-0x1234, (-0x1234).truncateToDouble());
+  Expect.equals(-0x12345678, (-0x12345678).truncateToDouble());
+  Expect.equals(-0x123456789AB, (-0x123456789AB).truncateToDouble());
+  Expect.equals(-81985529216486900.0, (-big).truncateToDouble());
 
   Expect.isTrue(0.truncateToDouble() is double);
   Expect.isTrue(1.truncateToDouble() is double);
   Expect.isTrue(0x1234.truncateToDouble() is double);
   Expect.isTrue(0x12345678.truncateToDouble() is double);
   Expect.isTrue(0x123456789AB.truncateToDouble() is double);
-  Expect.isTrue(0x123456789ABCDEF.truncateToDouble() is double);
-  Expect.isTrue(-1.truncateToDouble() is double);
-  Expect.isTrue(-0x1234.truncateToDouble() is double);
-  Expect.isTrue(-0x12345678.truncateToDouble() is double);
-  Expect.isTrue(-0x123456789AB.truncateToDouble() is double);
-  Expect.isTrue(-0x123456789ABCDEF.truncateToDouble() is double);
+  Expect.isTrue(big.truncateToDouble() is double);
+  Expect.isTrue((-1).truncateToDouble() is double);
+  Expect.isTrue((-0x1234).truncateToDouble() is double);
+  Expect.isTrue((-0x12345678).truncateToDouble() is double);
+  Expect.isTrue((-0x123456789AB).truncateToDouble() is double);
+  Expect.isTrue((-big).truncateToDouble() is double);
 }
diff --git a/tests/corelib_2/num_sign_test.dart b/tests/corelib_2/num_sign_test.dart
index d7913bb..db5f497 100644
--- a/tests/corelib_2/num_sign_test.dart
+++ b/tests/corelib_2/num_sign_test.dart
@@ -25,51 +25,54 @@
   0,
   1,
   2,
-  0x7f, //                     ~7 bits
+  0x7f, //                        ~7 bits
   0x80,
-  0xff, //                     ~8 bits
+  0xff, //                        ~8 bits
   0x100,
-  0xffff, //                   ~16 bits
+  0xffff, //                      ~16 bits
   0x10000,
-  0x3fffffff, //               ~30 bits (max positive 32-bit tagged smi)
+  0x3fffffff, //                  ~30 bits (max positive 32-bit tagged smi)
   0x40000000,
   0x40000001,
-  0x7fffffff, //               ~31 bits
+  0x7fffffff, //                  ~31 bits
   0x80000000,
   0x80000001,
-  0xfffffffff, //              ~32 bits
+  0xfffffffff, //                 ~32 bits
   0x100000000,
   0x100000001,
-  0x10000000000000, //         ~53 bits
+  0x10000000000000, //            ~53 bits
   0x10000000000001,
   0x1fffffffffffff,
   0x20000000000000,
-  0x20000000000001, //         first integer not representable as double.
-  0x20000000000002,
-  0x7fffffffffffffff, //       ~63 bits
+  // Use arithmetic to construct values below since they are not valid 'web
+  // integers'. On platforms that use doubles to represent integers, there will
+  // be some rounding in the arithmetic, testing a nearby value instead.
+  0x20000000000000 + 1, //        first integer not representable as double.
+  0x20000000000000 + 2,
+  0x7ffffffffffff000 + 0xfff, //  ~63 bits
   0x8000000000000000,
-  0x8000000000000001,
-  0xffffffffffffffff, //       ~64 bits
+  0x8000000000000000 + 1,
+  0xfffffffffffff000 + 0xfff, //  ~64 bits
   // Doubles.
   0.0,
-  5e-324, //                   min positive
-  2.225073858507201e-308, //   max denormal
-  2.2250738585072014e-308, //  min normal
-  0.49999999999999994, //      ~0.5
+  5e-324, //                      min positive
+  2.225073858507201e-308, //      max denormal
+  2.2250738585072014e-308, //     min normal
+  0.49999999999999994, //         ~0.5
   0.5,
   0.5000000000000001,
-  0.9999999999999999, //       ~1.0
+  0.9999999999999999, //          ~1.0
   1.0,
   1.0000000000000002,
-  4294967295.0, //             ~32 bits
+  4294967295.0, //                ~32 bits
   4294967296.0,
-  4503599627370495.5, //       max fractional
+  4503599627370495.5, //          max fractional
   4503599627370497.0,
   9007199254740991.0,
-  9007199254740992.0, //       max exact (+1 is not a double)
-  1.7976931348623157e+308, //  max finite double
-  1.0 / 0.0, //                Infinity
-  0.0 / 0.0, //                NaN
+  9007199254740992.0, //          max exact (+1 is not a double)
+  1.7976931348623157e+308, //     max finite double
+  1.0 / 0.0, //                   Infinity
+  0.0 / 0.0, //                   NaN
 ];
 
 main() {
diff --git a/tests/ffi/aliasing_test.dart b/tests/ffi/aliasing_test.dart
new file mode 100644
index 0000000..34a32fe
--- /dev/null
+++ b/tests/ffi/aliasing_test.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2019, 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.
+//
+// Dart test programing for testing that optimizations do wrongly assume loads
+// from and stores to C memory are not aliased.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=--deterministic --optimization-counter-threshold=50 --enable-inlining-annotations
+
+library FfiTest;
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'dylib_utils.dart';
+
+void main() {
+  for (int i = 0; i < 100; ++i) {
+    testNonAlias();
+    testAliasCast();
+    testAliasCast2();
+    testAliasOffsetBy();
+    testAliasOffsetBy2();
+    testAliasElementAt();
+    testAliasElementAt2();
+    testAliasFromAddress();
+    testAliasFromAddress2();
+    testAliasFromAddressViaMemory();
+    testAliasFromAddressViaMemory2();
+    testAliasFromAddressViaNativeFunction();
+    testAliasFromAddressViaNativeFunction2();
+    testPartialOverlap();
+  }
+}
+
+void testNonAlias() {
+  final source = Pointer<Int64>.allocate();
+  source.store(42);
+  final int a = source.load();
+  source.store(1984);
+  // alias.load() should be re-executed, as we wrote to alias.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasCast() {
+  final source = Pointer<Int64>.allocate();
+  final alias = source.cast<Int8>().cast<Int64>();
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasCast2() {
+  final source = Pointer<Int64>.allocate();
+  final alias = source.cast<Int16>().cast<Int64>();
+  final alias2 = source.cast<Int8>().cast<Int64>();
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  source.free();
+}
+
+void testAliasOffsetBy() {
+  final source = Pointer<Int64>.allocate(count: 2);
+  final alias = source.offsetBy(8).offsetBy(-8);
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasOffsetBy2() {
+  final source = Pointer<Int64>.allocate(count: 3);
+  final alias = source.offsetBy(16).offsetBy(-16);
+  final alias2 = source.offsetBy(8).offsetBy(-8);
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  source.free();
+}
+
+void testAliasElementAt() {
+  final source = Pointer<Int64>.allocate(count: 2);
+  final alias = source.elementAt(1).elementAt(-1);
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasElementAt2() {
+  final source = Pointer<Int64>.allocate(count: 3);
+  final alias = source.elementAt(2).elementAt(-2);
+  final alias2 = source.elementAt(1).elementAt(-1);
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  source.free();
+}
+
+void testAliasFromAddress() {
+  final source = Pointer<Int64>.allocate();
+  final alias = Pointer<Int64>.fromAddress(source.address);
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasFromAddress2() {
+  final source = Pointer<Int64>.allocate();
+  final alias = Pointer<Int64>.fromAddress(source.address);
+  final alias2 = Pointer<Int64>.fromAddress(source.address);
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  source.free();
+}
+
+void testAliasFromAddressViaMemory() {
+  final helper = Pointer<IntPtr>.allocate();
+  final source = Pointer<Int64>.allocate();
+  helper.store(source.address);
+  final alias = Pointer<Int64>.fromAddress(helper.load());
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  helper.free();
+  source.free();
+}
+
+void testAliasFromAddressViaMemory2() {
+  final helper = Pointer<IntPtr>.allocate();
+  final source = Pointer<Int64>.allocate();
+  helper.store(source.address);
+  final alias = Pointer<Int64>.fromAddress(helper.load());
+  final alias2 = Pointer<Int64>.fromAddress(helper.load());
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  helper.free();
+  source.free();
+}
+
+typedef NativeQuadOpSigned = Int64 Function(Int8, Int16, Int32, Int64);
+typedef QuadOp = int Function(int, int, int, int);
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+QuadOp intComputation = ffiTestFunctions
+    .lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
+
+void testAliasFromAddressViaNativeFunction() {
+  final source = Pointer<Int64>.allocate();
+  final alias =
+      Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+  source.store(42);
+  final int a = source.load();
+  alias.store(1984);
+  // source.load() should be re-executed, we wrote alias which aliases source.
+  Expect.notEquals(a, source.load<int>());
+  source.free();
+}
+
+void testAliasFromAddressViaNativeFunction2() {
+  final source = Pointer<Int64>.allocate();
+  final alias =
+      Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+  final alias2 =
+      Pointer<Int64>.fromAddress(intComputation(0, 0, 0, source.address));
+  alias.store(42);
+  final int a = alias.load();
+  alias2.store(1984);
+  // alias.load() should be re-executed, we wrote alias2 which aliases alias.
+  Expect.notEquals(a, alias.load<int>());
+  source.free();
+}
+
+// TODO(dacoharkes): Replace with @pragma annotations once available.
+const NeverInline = 'NeverInline';
+
+@NeverInline
+Pointer<Int8> makeDerived(Pointer<Int64> source) =>
+    source.offsetBy(7).cast<Int8>();
+
+testPartialOverlap() {
+  final source = Pointer<Int64>.allocate(count: 2);
+  final derived = makeDerived(source);
+  source.store(0x1122334455667788);
+  final int value = source.load();
+  derived.store(0xaa);
+  Expect.notEquals(value, source.load<int>());
+  source.free();
+}
diff --git a/tests/ffi/coordinate.dart b/tests/ffi/coordinate.dart
index fbca952..8c8b4d4 100644
--- a/tests/ffi/coordinate.dart
+++ b/tests/ffi/coordinate.dart
@@ -4,37 +4,23 @@
 
 library FfiTest;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 /// Sample struct for dart:ffi library.
-@ffi.struct
-class Coordinate extends ffi.Pointer<ffi.Void> {
-  @ffi.Double()
+class Coordinate extends Struct<Coordinate> {
+  @Double()
   double x;
 
-  @ffi.Double()
+  @Double()
   double y;
 
-  @ffi.Pointer()
-  Coordinate next;
+  @Pointer()
+  Pointer<Coordinate> next;
 
-  /// generated by @ffi.struct annotation
-  external static int sizeOf();
-
-  Coordinate offsetBy(int offsetInBytes) =>
-      super.offsetBy(offsetInBytes).cast();
-
-  Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
-
-  static Coordinate allocate({int count: 1}) =>
-      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
-
-  /// Allocate a new [Coordinate] in C memory and populate its fields.
-  factory Coordinate(double x, double y, Coordinate next) {
-    Coordinate result = Coordinate.allocate()
+  factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
+    return Pointer<Coordinate>.allocate().load<Coordinate>()
       ..x = x
       ..y = y
       ..next = next;
-    return result;
   }
 }
diff --git a/tests/ffi/coordinate_bare.dart b/tests/ffi/coordinate_bare.dart
index 764cb9f..7858882 100644
--- a/tests/ffi/coordinate_bare.dart
+++ b/tests/ffi/coordinate_bare.dart
@@ -4,17 +4,16 @@
 
 library FfiTestCoordinateBare;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 /// Stripped down sample struct for dart:ffi library.
-@ffi.struct
-class Coordinate extends ffi.Pointer<ffi.Void> {
-  @ffi.Double()
+class Coordinate extends Struct<Coordinate> {
+  @Double()
   double x;
 
-  @ffi.Double()
+  @Double()
   double y;
 
-  @ffi.Pointer()
-  Coordinate next;
+  @Pointer()
+  Pointer<Coordinate> next;
 }
diff --git a/tests/ffi/coordinate_manual.dart b/tests/ffi/coordinate_manual.dart
deleted file mode 100644
index d4d1aca..0000000
--- a/tests/ffi/coordinate_manual.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2019, 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.
-
-library FfiTestCoordinateManual;
-
-import 'dart:ffi' as ffi;
-
-/// Sample struct for dart:ffi library without use of ffi annotations.
-class Coordinate extends ffi.Pointer<ffi.Void> {
-  ffi.Pointer<ffi.Double> get _xPtr => cast();
-  set x(double v) => _xPtr.store(v);
-  double get x => _xPtr.load();
-
-  ffi.Pointer<ffi.Double> get _yPtr =>
-      offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
-  set y(double v) => _yPtr.store(v);
-  double get y => _yPtr.load();
-
-  ffi.Pointer<Coordinate> get _nextPtr =>
-      offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
-  set next(Coordinate v) => _nextPtr.store(v);
-  Coordinate get next => _nextPtr.load();
-
-  static int sizeOf() =>
-      ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
-
-  Coordinate offsetBy(int offsetInBytes) =>
-      super.offsetBy(offsetInBytes).cast();
-
-  Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
-
-  static Coordinate allocate({int count: 1}) =>
-      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
-
-  /// Allocate a new [Coordinate] in C memory and populate its fields.
-  factory Coordinate(double x, double y, Coordinate next) {
-    Coordinate result = Coordinate.allocate()
-      ..x = x
-      ..y = y
-      ..next = next;
-    return result;
-  }
-}
diff --git a/tests/ffi/cstring.dart b/tests/ffi/cstring.dart
index b976007..b0bfdae 100644
--- a/tests/ffi/cstring.dart
+++ b/tests/ffi/cstring.dart
@@ -6,27 +6,31 @@
 
 import 'dart:convert';
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
-/// Sample non-struct subtype of Pointer for dart:ffi library.
-class CString extends ffi.Pointer<ffi.Uint8> {
-  CString elementAt(int index) => super.elementAt(index).cast();
+/// Sample non-struct Pointer wrapper for dart:ffi library.
+class Utf8 extends ffi.Struct<Utf8> {
+  @ffi.Int8()
+  int char;
 
-  String fromUtf8() {
+  static String fromUtf8(Pointer<Utf8> str) {
     List<int> units = [];
     int len = 0;
     while (true) {
-      int char = elementAt(len++).load<int>();
+      int char = str.elementAt(len++).load<Utf8>().char;
       if (char == 0) break;
       units.add(char);
     }
     return Utf8Decoder().convert(units);
   }
 
-  factory CString.toUtf8(String s) {
-    CString result = ffi.allocate<ffi.Uint8>(count: s.length + 1).cast();
+  static Pointer<Utf8> toUtf8(String s) {
+    Pointer<Utf8> result = Pointer<Utf8>.allocate(count: s.length + 1).cast();
     List<int> units = Utf8Encoder().convert(s);
-    for (int i = 0; i < s.length; i++) result.elementAt(i).store(units[i]);
-    result.elementAt(s.length).store(0);
+    for (int i = 0; i < s.length; i++) {
+      result.elementAt(i).load<Utf8>().char = units[i];
+    }
+    result.elementAt(s.length).load<Utf8>().char = 0;
     return result;
   }
 }
diff --git a/tests/ffi/data_not_asan_test.dart b/tests/ffi/data_not_asan_test.dart
index 2be8598..308c458 100644
--- a/tests/ffi/data_not_asan_test.dart
+++ b/tests/ffi/data_not_asan_test.dart
@@ -3,27 +3,35 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // Dart test program for testing dart:ffi primitive data pointers.
-// This test tries to allocate too much memory on purpose to test the Exception
-// thrown on malloc failing.
-// This malloc also triggers an asan alarm, so this test is in a separate file
+//
+// These mallocs trigger an asan alarm, so these tests are in a separate file
 // which is excluded in asan mode.
 
 library FfiTest;
 
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
 import "package:expect/expect.dart";
 
 void main() {
   testPointerAllocateTooLarge();
+  testPointerAllocateNegative();
 }
 
-/// This test is skipped in asan mode.
 void testPointerAllocateTooLarge() {
+  // Try to allocate something that doesn't fit in 64 bit address space.
   int maxInt = 9223372036854775807; // 2^63 - 1
-  Expect.throws(
-      () => ffi.allocate<ffi.Int64>(count: maxInt)); // does not fit in range
+  Expect.throws(() => Pointer<ffi.Int64>.allocate(count: maxInt));
+
+  // Try to allocate almost the full 64 bit address space.
   int maxInt1_8 = 1152921504606846975; // 2^60 -1
-  Expect.throws(
-      () => ffi.allocate<ffi.Int64>(count: maxInt1_8)); // not enough memory
+  Expect.throws(() => Pointer<ffi.Int64>.allocate(count: maxInt1_8));
+}
+
+void testPointerAllocateNegative() {
+  // Passing in -1 will be converted into an unsigned integer. So, it will try
+  // to allocate SIZE_MAX - 1 + 1 bytes. This will fail as it is the max amount
+  // of addressable memory on the system.
+  Expect.throws(() => Pointer<ffi.Int8>.allocate(count: -1));
 }
diff --git a/tests/ffi/data_test.dart b/tests/ffi/data_test.dart
index 4cdc79b..a86f9af 100644
--- a/tests/ffi/data_test.dart
+++ b/tests/ffi/data_test.dart
@@ -7,6 +7,7 @@
 library FfiTest;
 
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
 import "package:expect/expect.dart";
 
@@ -15,7 +16,7 @@
   testPointerFromPointer();
   testPointerPointerArithmetic();
   testPointerPointerArithmeticSizes();
-  testPointerAllocateNonPositive();
+  testPointerAllocateZero();
   testPointerCast();
   testCastGeneric();
   testCastGeneric2();
@@ -54,85 +55,96 @@
 }
 
 void testPointerBasic() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  Pointer<ffi.Int64> p = Pointer.allocate();
   p.store(42);
   Expect.equals(42, p.load<int>());
   p.free();
 }
 
 void testPointerFromPointer() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  Pointer<ffi.Int64> p = Pointer.allocate();
   p.store(1337);
   int ptr = p.address;
-  ffi.Pointer<ffi.Int64> p2 = ffi.fromAddress(ptr);
+  Pointer<ffi.Int64> p2 = Pointer.fromAddress(ptr);
   Expect.equals(1337, p2.load<int>());
   p.free();
 }
 
 void testPointerPointerArithmetic() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
-  ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+  Pointer<ffi.Int64> p = Pointer.allocate(count: 2);
+  Pointer<ffi.Int64> p2 = p.elementAt(1);
   p2.store(100);
-  ffi.Pointer<ffi.Int64> p3 = p.offsetBy(8);
+  Pointer<ffi.Int64> p3 = p.offsetBy(8);
   Expect.equals(100, p3.load<int>());
   p.free();
 }
 
 void testPointerPointerArithmeticSizes() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
-  ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+  Pointer<ffi.Int64> p = Pointer.allocate(count: 2);
+  Pointer<ffi.Int64> p2 = p.elementAt(1);
   int addr = p.address;
   Expect.equals(addr + 8, p2.address);
   p.free();
 
-  ffi.Pointer<ffi.Int32> p3 = ffi.allocate(count: 2);
-  ffi.Pointer<ffi.Int32> p4 = p3.elementAt(1);
+  Pointer<ffi.Int32> p3 = Pointer.allocate(count: 2);
+  Pointer<ffi.Int32> p4 = p3.elementAt(1);
   addr = p3.address;
   Expect.equals(addr + 4, p4.address);
   p3.free();
 }
 
-void testPointerAllocateNonPositive() {
-  Expect.throws(() => ffi.allocate<ffi.Int8>(count: 0));
-  Expect.throws(() => ffi.allocate<ffi.Int8>(count: -1));
+void testPointerAllocateZero() {
+  // > If size is 0, either a null pointer or a unique pointer that can be
+  // > successfully passed to free() shall be returned.
+  // http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
+  //
+  // Null pointer throws a Dart exception.
+  bool returnedNullPointer = false;
+  ffi.Pointer<ffi.Int8> p;
+  try {
+    p = Pointer<ffi.Int8>.allocate(count: 0);
+  } on Exception {
+    returnedNullPointer = true;
+  }
+  if (!returnedNullPointer) {
+    p.free();
+  }
 }
 
 void testPointerCast() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate();
-  ffi.Pointer<ffi.Int32> p2 = p.cast(); // gets the correct type args back
+  Pointer<ffi.Int64> p = Pointer.allocate();
+  Pointer<ffi.Int32> p2 = p.cast(); // gets the correct type args back
   p.free();
 }
 
 void testCastGeneric() {
-  ffi.Pointer<T> generic<T extends ffi.NativeType>(ffi.Pointer<ffi.Int16> p) {
+  Pointer<T> generic<T extends ffi.NativeType>(Pointer<ffi.Int16> p) {
     return p.cast();
   }
 
-  ffi.Pointer<ffi.Int16> p = ffi.allocate();
-  ffi.Pointer<ffi.Int64> p2 = generic(p);
+  Pointer<ffi.Int16> p = Pointer.allocate();
+  Pointer<ffi.Int64> p2 = generic(p);
   p.free();
 }
 
 void testCastGeneric2() {
-  ffi.Pointer<ffi.Int64> generic<T extends ffi.NativeType>(ffi.Pointer<T> p) {
+  Pointer<ffi.Int64> generic<T extends ffi.NativeType>(Pointer<T> p) {
     return p.cast();
   }
 
-  ffi.Pointer<ffi.Int16> p = ffi.allocate();
-  ffi.Pointer<ffi.Int64> p2 = generic(p);
+  Pointer<ffi.Int16> p = Pointer.allocate();
+  Pointer<ffi.Int64> p2 = generic(p);
   p.free();
 }
 
 void testCastNativeType() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate();
-  Expect.throws(() {
-    p.cast<ffi.Pointer>();
-  });
+  ffi.Pointer<ffi.Int64> p = Pointer.allocate();
+  p.cast<ffi.Pointer>();
   p.free();
 }
 
 void testCondensedNumbersInt8() {
-  ffi.Pointer<ffi.Int8> p = ffi.allocate(count: 8);
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate(count: 8);
   for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
     p.elementAt(i).store(i * 3);
   }
@@ -143,7 +155,7 @@
 }
 
 void testCondensedNumbersFloat() {
-  ffi.Pointer<ffi.Float> p = ffi.allocate(count: 8);
+  ffi.Pointer<ffi.Float> p = Pointer.allocate(count: 8);
   for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
     p.elementAt(i).store(1.511366173271439e-13);
   }
@@ -154,7 +166,7 @@
 }
 
 void testRangeInt8() {
-  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate();
   p.store(127);
   Expect.equals(127, p.load<int>());
   p.store(-128);
@@ -173,7 +185,7 @@
 }
 
 void testRangeUint8() {
-  ffi.Pointer<ffi.Uint8> p = ffi.allocate();
+  ffi.Pointer<ffi.Uint8> p = Pointer.allocate();
   p.store(255);
   Expect.equals(255, p.load<int>());
   p.store(0);
@@ -192,7 +204,7 @@
 }
 
 void testRangeInt16() {
-  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  ffi.Pointer<ffi.Int16> p = Pointer.allocate();
   p.store(0x7FFF);
   Expect.equals(0x7FFF, p.load<int>());
   p.store(-0x8000);
@@ -206,7 +218,7 @@
 }
 
 void testRangeUint16() {
-  ffi.Pointer<ffi.Uint16> p = ffi.allocate();
+  ffi.Pointer<ffi.Uint16> p = Pointer.allocate();
   p.store(0xFFFF);
   Expect.equals(0xFFFF, p.load<int>());
   p.store(0);
@@ -219,7 +231,7 @@
 }
 
 void testRangeInt32() {
-  ffi.Pointer<ffi.Int32> p = ffi.allocate();
+  ffi.Pointer<ffi.Int32> p = Pointer.allocate();
   p.store(0x7FFFFFFF);
   Expect.equals(0x7FFFFFFF, p.load<int>());
   p.store(-0x80000000);
@@ -233,7 +245,7 @@
 }
 
 void testRangeUint32() {
-  ffi.Pointer<ffi.Uint32> p = ffi.allocate();
+  ffi.Pointer<ffi.Uint32> p = Pointer.allocate();
   p.store(0xFFFFFFFF);
   Expect.equals(0xFFFFFFFF, p.load<int>());
   p.store(0);
@@ -246,7 +258,7 @@
 }
 
 void testRangeInt64() {
-  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  ffi.Pointer<ffi.Int64> p = Pointer.allocate();
   p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
   Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
   p.store(-0x8000000000000000); // -2 ^ 63
@@ -255,7 +267,7 @@
 }
 
 void testRangeUint64() {
-  ffi.Pointer<ffi.Uint64> p = ffi.allocate();
+  ffi.Pointer<ffi.Uint64> p = Pointer.allocate();
   p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
   Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
   p.store(-0x8000000000000000); // -2 ^ 63 interpreted as 2 ^ 63
@@ -270,7 +282,7 @@
 }
 
 void testRangeIntPtr() {
-  ffi.Pointer<ffi.IntPtr> p = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> p = Pointer.allocate();
   int pAddr = p.address;
   p.store(pAddr); // its own address should fit
   p.store(0x7FFFFFFF); // and 32 bit addresses should fit
@@ -281,7 +293,7 @@
 }
 
 void testFloat() {
-  ffi.Pointer<ffi.Float> p = ffi.allocate();
+  ffi.Pointer<ffi.Float> p = Pointer.allocate();
   p.store(1.511366173271439e-13);
   Expect.equals(1.511366173271439e-13, p.load<double>());
   p.store(1.4260258159703532e-105); // float does not have enough precision
@@ -290,23 +302,23 @@
 }
 
 void testDouble() {
-  ffi.Pointer<ffi.Double> p = ffi.allocate();
+  ffi.Pointer<ffi.Double> p = Pointer.allocate();
   p.store(1.4260258159703532e-105);
   Expect.equals(1.4260258159703532e-105, p.load<double>());
   p.free();
 }
 
 void testVoid() {
-  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
   ffi.Pointer<ffi.Void> p2 = p1.cast(); // make this dart pointer opaque
   p2.address; // we can print the address
   p2.free();
 }
 
 void testPointerPointer() {
-  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  ffi.Pointer<ffi.Int16> p = Pointer.allocate();
   p.store(17);
-  ffi.Pointer<ffi.Pointer<ffi.Int16>> p2 = ffi.allocate();
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p2 = Pointer.allocate();
   p2.store(p);
   Expect.equals(17, p2.load<ffi.Pointer<ffi.Int16>>().load<int>());
   p2.free();
@@ -314,32 +326,36 @@
 }
 
 void testPointerPointerNull() {
-  ffi.Pointer<ffi.Pointer<ffi.Int8>> pointerToPointer = ffi.allocate();
-  ffi.Pointer<ffi.Int8> value = null;
+  Pointer<Pointer<ffi.Int8>> pointerToPointer = Pointer.allocate();
+  Pointer<ffi.Int8> value = ffi.nullptr.cast();
   pointerToPointer.store(value);
   value = pointerToPointer.load();
-  Expect.isNull(value);
-  value = ffi.allocate();
+  Expect.equals(value, ffi.nullptr);
+  value = Pointer.allocate();
   pointerToPointer.store(value);
   value = pointerToPointer.load();
   Expect.isNotNull(value);
   value.free();
-  value = null;
+  value = ffi.nullptr.cast();
   pointerToPointer.store(value);
   value = pointerToPointer.load();
-  Expect.isNull(value);
+  Expect.equals(value, ffi.nullptr);
   pointerToPointer.free();
 }
 
 void testPointerStoreNull() {
   int i = null;
-  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate();
   Expect.throws(() => p.store(i));
   p.free();
   double d = null;
-  ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+  ffi.Pointer<ffi.Float> p2 = Pointer.allocate();
   Expect.throws(() => p2.store(d));
   p2.free();
+  Pointer<ffi.Void> x = null;
+  ffi.Pointer<ffi.Pointer<ffi.Void>> p3 = Pointer.allocate();
+  Expect.throws(() => p3.store(x));
+  p3.free();
 }
 
 void testSizeOf() {
@@ -364,7 +380,7 @@
       head.store(value);
       return;
     }
-    ffi.Pointer<ffi.IntPtr> next = ffi.allocate();
+    ffi.Pointer<ffi.IntPtr> next = Pointer.allocate();
     head.store(next.address);
     createChain(next, length - 1, value);
   }
@@ -373,12 +389,12 @@
     if (length == 0) {
       return head.load();
     }
-    ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+    ffi.Pointer<ffi.IntPtr> next = Pointer.fromAddress(head.load());
     return getChainValue(next, length - 1);
   }
 
   void freeChain(ffi.Pointer<ffi.IntPtr> head, int length) {
-    ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+    ffi.Pointer<ffi.IntPtr> next = Pointer.fromAddress(head.load());
     head.free();
     if (length == 0) {
       return;
@@ -386,7 +402,7 @@
     freeChain(next, length - 1);
   }
 
-  ffi.Pointer<ffi.IntPtr> head = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> head = Pointer.allocate();
   createChain(head, length, 512);
   int tailValue = getChainValue(head, length);
   Expect.equals(512, tailValue);
@@ -394,23 +410,23 @@
 }
 
 void testTypeTest() {
-  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate();
   Expect.isTrue(p is ffi.Pointer);
   p.free();
 }
 
 void testToString() {
-  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  ffi.Pointer<ffi.Int16> p = Pointer.allocate();
   Expect.stringEquals(
       "Pointer<Int16>: address=0x", p.toString().substring(0, 26));
   p.free();
-  ffi.Pointer<ffi.Int64> p2 = ffi.fromAddress(0x123abc);
+  ffi.Pointer<ffi.Int64> p2 = Pointer.fromAddress(0x123abc);
   Expect.stringEquals("Pointer<Int64>: address=0x123abc", p2.toString());
 }
 
 void testEquality() {
-  ffi.Pointer<ffi.Int8> p = ffi.fromAddress(12345678);
-  ffi.Pointer<ffi.Int8> p2 = ffi.fromAddress(12345678);
+  ffi.Pointer<ffi.Int8> p = Pointer.fromAddress(12345678);
+  ffi.Pointer<ffi.Int8> p2 = Pointer.fromAddress(12345678);
   Expect.equals(p, p2);
   Expect.equals(p.hashCode, p2.hashCode);
   ffi.Pointer<ffi.Int16> p3 = p.cast();
@@ -427,7 +443,7 @@
 void testAllocateGeneric() {
   ffi.Pointer<T> generic<T extends ffi.NativeType>() {
     ffi.Pointer<T> pointer;
-    pointer = ffi.allocate();
+    pointer = Pointer.allocate();
     return pointer;
   }
 
@@ -437,19 +453,19 @@
 
 void testAllocateVoid() {
   Expect.throws(() {
-    ffi.Pointer<ffi.Void> p = ffi.allocate();
+    ffi.Pointer<ffi.Void> p = Pointer.allocate();
   });
 }
 
 void testAllocateNativeFunction() {
   Expect.throws(() {
-    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.allocate();
+    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.allocate();
   });
 }
 
 void testAllocateNativeType() {
   Expect.throws(() {
-    ffi.allocate();
+    Pointer.allocate();
   });
 }
 
@@ -484,8 +500,8 @@
 
 void testFreeZeroOut() {
   // at least one of these pointers should have address != 0 on all platforms
-  ffi.Pointer<ffi.Int8> p1 = ffi.allocate();
-  ffi.Pointer<ffi.Int8> p2 = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p1 = Pointer.allocate();
+  ffi.Pointer<ffi.Int8> p2 = Pointer.allocate();
   Expect.notEquals(0, p1.address & p2.address);
   p1.free();
   p2.free();
diff --git a/tests/ffi/dynamic_library_test.dart b/tests/ffi/dynamic_library_test.dart
index 3282f4c..7b29a18 100644
--- a/tests/ffi/dynamic_library_test.dart
+++ b/tests/ffi/dynamic_library_test.dart
@@ -8,7 +8,7 @@
 
 library FfiTest;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 import 'dylib_utils.dart';
 
@@ -21,10 +21,11 @@
   testLookupError();
   testToString();
   testEquality();
+  testHandle();
 }
 
 void testOpen() {
-  ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   Expect.notEquals(null, l);
 }
 
@@ -33,35 +34,46 @@
       () => dlopenPlatformSpecific("doesnotexistforsurelibrary123409876"));
 }
 
-typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
+typedef NativeDoubleUnOp = Double Function(Double);
 
 typedef DoubleUnOp = double Function(double);
 
 void testLookup() {
-  ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
   Expect.approxEquals(12.0, timesFour(3));
 }
 
 void testLookupError() {
-  ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   Expect.throws(() => l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>(
       "functionnamethatdoesnotexistforsure749237593845"));
 }
 
 void testToString() {
-  ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
   Expect.stringEquals(
       "DynamicLibrary: handle=0x", l.toString().substring(0, 25));
 }
 
 void testEquality() {
-  ffi.DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
-  ffi.DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
   Expect.equals(l, l2);
   Expect.equals(l.hashCode, l2.hashCode);
   Expect.notEquals(l, null);
   Expect.notEquals(null, l);
-  ffi.DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
+  DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
   Expect.notEquals(l, l3);
 }
+
+void testHandle() {
+  DynamicLibrary l = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  DynamicLibrary l2 = dlopenPlatformSpecific("ffi_test_dynamic_library");
+  Pointer<Void> h = l.handle;
+  Pointer<Void> h2 = l2.handle;
+  Expect.equals(h, h2);
+  DynamicLibrary l3 = dlopenPlatformSpecific("ffi_test_functions");
+  Pointer<Void> h3 = l3.handle;
+  Expect.notEquals(h, h3);
+}
diff --git a/tests/ffi/enable_structs_test.dart b/tests/ffi/enable_structs_test.dart
index ed8655b..21f48d0 100644
--- a/tests/ffi/enable_structs_test.dart
+++ b/tests/ffi/enable_structs_test.dart
@@ -6,20 +6,17 @@
 
 library FfiTest;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 import "package:expect/expect.dart";
 
-@ffi.struct
-class C extends ffi.Pointer<ffi.Void> {
-  @ffi.IntPtr()
+class C extends Struct<C> {
+  @IntPtr()
   int x;
-  external static int sizeOf();
 }
 
 void main() {
-  final C c = ffi.fromAddress<C>(1);
+  final C c = nullptr.cast<C>().load();
   Expect.throws<UnimplementedError>(() => c.x);
   Expect.throws<UnimplementedError>(() => c.x = 0);
-  Expect.throws<UnimplementedError>(() => C.sizeOf());
 }
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 1fa9e5b..de333a5 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -19,12 +19,12 @@
 function_callbacks_test/03: Skip
 
 [ $runtime == dart_precompiled ]
-*: Skip # AOT is not yet supported: dartbug.com/35765
+function_callbacks_test: Skip  # Issue dartbug.com/37295
 
 [ $arch == arm && $system != android ]
 *: Skip # "hardfp" calling convention is not yet supported (iOS is also supported but not tested): dartbug.com/36309
 
-[ $arch == simdbc64 && $system != linux && $system != macos ]
+[ $arch == simdbc64 && $system != android && $system != linux && $system != macos ]
 *: Skip # FFI not yet supported outside x64 Linux: dartbug.com/36809
 
 [ $runtime != dart_precompiled && $runtime != vm ]
diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart
index b3ddc9a..1b25dc1 100644
--- a/tests/ffi/function_callbacks_test.dart
+++ b/tests/ffi/function_callbacks_test.dart
@@ -139,45 +139,73 @@
 Pointer<Int64> store(Pointer<Int64> ptr) => ptr.elementAt(1)..store(1337);
 
 typedef NullPointersType = Pointer<Int64> Function(Pointer<Int64>);
-Pointer<Int64> nullPointers(Pointer<Int64> ptr) => ptr?.elementAt(1);
+Pointer<Int64> nullPointers(Pointer<Int64> ptr) => ptr.elementAt(1);
 
 typedef ReturnNullType = Int32 Function();
 int returnNull() {
-  print('Expect "unhandled exception" error message to follow.');
   return null;
 }
 
 typedef ReturnVoid = Void Function();
 void returnVoid() {}
 
+void throwException() {
+  throw "Exception.";
+}
+
+typedef ThrowExceptionInt = IntPtr Function();
+int throwExceptionInt() {
+  throw "Exception.";
+}
+
+typedef ThrowExceptionDouble = Double Function();
+double throwExceptionDouble() {
+  throw "Exception.";
+}
+
+typedef ThrowExceptionPointer = Pointer<Void> Function();
+Pointer<Void> throwExceptionPointer() {
+  throw "Exception.";
+}
+
 void testGC() {
   triggerGc();
 }
 
 final List<Test> testcases = [
-  Test("SimpleAddition", fromFunction<SimpleAdditionType>(simpleAddition)),
-  Test("IntComputation", fromFunction<IntComputationType>(intComputation)),
-  Test("UintComputation", fromFunction<UintComputationType>(uintComputation)),
-  Test("SimpleMultiply", fromFunction<SimpleMultiplyType>(simpleMultiply)),
+  Test("SimpleAddition", Pointer.fromFunction<SimpleAdditionType>(simpleAddition, 0)),
+  Test("IntComputation", Pointer.fromFunction<IntComputationType>(intComputation, 0)),
+  Test(
+      "UintComputation", Pointer.fromFunction<UintComputationType>(uintComputation, 0)),
+  Test("SimpleMultiply", Pointer.fromFunction<SimpleMultiplyType>(simpleMultiply, 0.0)),
   Test("SimpleMultiplyFloat",
-      fromFunction<SimpleMultiplyFloatType>(simpleMultiplyFloat)),
-  Test("ManyInts", fromFunction<ManyIntsType>(manyInts)),
-  Test("ManyDoubles", fromFunction<ManyDoublesType>(manyDoubles)),
-  Test("ManyArgs", fromFunction<ManyArgsType>(manyArgs)),
-  Test("Store", fromFunction<StoreType>(store)),
-  Test("NullPointers", fromFunction<NullPointersType>(nullPointers)),
-  Test("ReturnNull", fromFunction<ReturnNullType>(returnNull)),
-  Test("GC", fromFunction<ReturnVoid>(testGC)),
+      Pointer.fromFunction<SimpleMultiplyFloatType>(simpleMultiplyFloat, 0.0)),
+  Test("ManyInts", Pointer.fromFunction<ManyIntsType>(manyInts, 0)),
+  Test("ManyDoubles", Pointer.fromFunction<ManyDoublesType>(manyDoubles, 0.0)),
+  Test("ManyArgs", Pointer.fromFunction<ManyArgsType>(manyArgs, 0.0)),
+  Test("Store", Pointer.fromFunction<StoreType>(store, null)),
+  Test("NullPointers", Pointer.fromFunction<NullPointersType>(nullPointers, null)),
+  Test("ReturnNull", Pointer.fromFunction<ReturnNullType>(returnNull, 42)),
+  Test("ReturnVoid", Pointer.fromFunction<ReturnVoid>(returnVoid, null)),
+  Test("ThrowExceptionDouble",
+      Pointer.fromFunction<ThrowExceptionDouble>(throwExceptionDouble, 42.0)),
+  Test(
+      "ThrowExceptionPointer",
+      Pointer.fromFunction<ThrowExceptionPointer>(
+          throwExceptionPointer, Pointer<Void>.fromAddress(42))),
+  Test("ThrowException", Pointer.fromFunction<ThrowExceptionInt>(throwExceptionInt, 42)),
+  Test("GC", Pointer.fromFunction<ReturnVoid>(testGC, null)),
 ];
 
 testCallbackWrongThread() =>
-    Test("CallbackWrongThread", fromFunction<ReturnVoid>(returnVoid)).run();
+    Test("CallbackWrongThread", Pointer.fromFunction<ReturnVoid>(returnVoid, null)).run();
 
 testCallbackOutsideIsolate() =>
-    Test("CallbackOutsideIsolate", fromFunction<ReturnVoid>(returnVoid)).run();
+    Test("CallbackOutsideIsolate", Pointer.fromFunction<ReturnVoid>(returnVoid, null))
+        .run();
 
 isolateHelper(int callbackPointer) {
-  final Pointer<Void> ptr = fromAddress(callbackPointer);
+  final Pointer<Void> ptr = Pointer.fromAddress(callbackPointer);
   final NativeCallbackTestFn tester =
       testLibrary.lookupFunction<NativeCallbackTest, NativeCallbackTestFn>(
           "TestCallbackWrongIsolate");
@@ -185,15 +213,27 @@
 }
 
 testCallbackWrongIsolate() async {
-  final int callbackPointer = fromFunction<ReturnVoid>(returnVoid).address;
+  final int callbackPointer = Pointer.fromFunction<ReturnVoid>(returnVoid, null).address;
   final ReceivePort exitPort = ReceivePort();
   await Isolate.spawn(isolateHelper, callbackPointer,
       errorsAreFatal: true, onExit: exitPort.sendPort);
   await exitPort.first;
 }
 
+// Correct type of exceptionalReturn argument to Pointer.fromFunction.
+double testExceptionalReturn() {
+  Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0.0);
+  Expect.throwsArgumentError(() => Pointer.fromFunction<Void Function()>(returnVoid, 0));
+  Pointer.fromFunction<Void Function()>(returnVoid, null);
+  Expect.throwsArgumentError(() => Pointer.fromFunction<Double Function()>(returnVoid, null));
+
+  Pointer.fromFunction<Double Function()>(testExceptionalReturn, "abc");  //# 61: compile-time error
+  Pointer.fromFunction<Double Function()>(testExceptionalReturn, 0);  //# 62: compile-time error
+}
+
 void main() async {
   testcases.forEach((t) => t.run()); //# 00: ok
+  testExceptionalReturn(); //# 00: ok
 
   // These tests terminate the process after successful completion, so we have
   // to run them separately.
diff --git a/tests/ffi/function_structs_test.dart b/tests/ffi/function_structs_test.dart
index 6f1f906..875f621 100644
--- a/tests/ffi/function_structs_test.dart
+++ b/tests/ffi/function_structs_test.dart
@@ -10,6 +10,7 @@
 library FfiTest;
 
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
 import 'dylib_utils.dart';
 
@@ -18,7 +19,7 @@
 import 'coordinate.dart';
 import 'very_large_struct.dart';
 
-typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+typedef NativeCoordinateOp = Pointer<Coordinate> Function(Pointer<Coordinate>);
 
 void main() {
   testFunctionWithStruct();
@@ -35,14 +36,15 @@
       ffiTestFunctions.lookup("TransposeCoordinate");
   NativeCoordinateOp f1 = p1.asFunction();
 
-  Coordinate c1 = Coordinate(10.0, 20.0, null);
-  Coordinate c2 = Coordinate(42.0, 84.0, c1);
-  c1.next = c2;
+  Pointer<Coordinate> c1 =
+      Coordinate.allocate(10.0, 20.0, ffi.nullptr.cast<Coordinate>()).addressOf;
+  Pointer<Coordinate> c2 = Coordinate.allocate(42.0, 84.0, c1).addressOf;
+  c1.load<Coordinate>().next = c2;
 
-  Coordinate result = f1(c1);
+  Coordinate result = f1(c1).load();
 
-  Expect.approxEquals(20.0, c1.x);
-  Expect.approxEquals(30.0, c1.y);
+  Expect.approxEquals(20.0, c1.load<Coordinate>().x);
+  Expect.approxEquals(30.0, c1.load<Coordinate>().y);
 
   Expect.approxEquals(42.0, result.x);
   Expect.approxEquals(84.0, result.y);
@@ -57,36 +59,36 @@
       ffiTestFunctions.lookup("CoordinateElemAt1");
   NativeCoordinateOp f1 = p1.asFunction();
 
-  Coordinate c1 = Coordinate.allocate(count: 3);
-  Coordinate c2 = c1.elementAt(1);
-  Coordinate c3 = c1.elementAt(2);
+  Coordinate c1 = Pointer<Coordinate>.allocate(count: 3).load();
+  Coordinate c2 = c1.addressOf.elementAt(1).load();
+  Coordinate c3 = c1.addressOf.elementAt(2).load();
   c1.x = 10.0;
   c1.y = 10.0;
-  c1.next = c3;
+  c1.next = c3.addressOf;
   c2.x = 20.0;
   c2.y = 20.0;
-  c2.next = c1;
+  c2.next = c1.addressOf;
   c3.x = 30.0;
   c3.y = 30.0;
-  c3.next = c2;
+  c3.next = c2.addressOf;
 
-  Coordinate result = f1(c1);
+  Coordinate result = f1(c1.addressOf).load();
   Expect.approxEquals(20.0, result.x);
   Expect.approxEquals(20.0, result.y);
 
-  c1.free();
+  c1.addressOf.free();
 }
 
-typedef VeryLargeStructSum = int Function(VeryLargeStruct);
-typedef NativeVeryLargeStructSum = ffi.Int64 Function(VeryLargeStruct);
+typedef VeryLargeStructSum = int Function(Pointer<VeryLargeStruct>);
+typedef NativeVeryLargeStructSum = ffi.Int64 Function(Pointer<VeryLargeStruct>);
 
 void testFunctionWithVeryLargeStruct() {
   ffi.Pointer<ffi.NativeFunction<NativeVeryLargeStructSum>> p1 =
       ffiTestFunctions.lookup("SumVeryLargeStruct");
   VeryLargeStructSum f = p1.asFunction();
 
-  VeryLargeStruct vls1 = VeryLargeStruct.allocate(count: 2);
-  VeryLargeStruct vls2 = vls1.elementAt(1);
+  VeryLargeStruct vls1 = Pointer<VeryLargeStruct>.allocate(count: 2).load();
+  VeryLargeStruct vls2 = vls1.addressOf.elementAt(1).load();
   List<VeryLargeStruct> structs = [vls1, vls2];
   for (VeryLargeStruct struct in structs) {
     struct.a = 1;
@@ -102,19 +104,19 @@
     struct.k = 1024;
     struct.smallLastField = 1;
   }
-  vls1.parent = vls2;
+  vls1.parent = vls2.addressOf;
   vls1.numChidlren = 2;
-  vls1.children = vls1;
-  vls2.parent = vls2;
-  vls2.parent = null;
+  vls1.children = vls1.addressOf;
+  vls2.parent = vls2.addressOf;
+  vls2.parent = ffi.nullptr.cast();
   vls2.numChidlren = 0;
-  vls2.children = null;
+  vls2.children = ffi.nullptr.cast();
 
-  int result = f(vls1);
+  int result = f(vls1.addressOf);
   Expect.equals(2051, result);
 
-  result = f(vls2);
+  result = f(vls2.addressOf);
   Expect.equals(2048, result);
 
-  vls1.free();
+  vls1.addressOf.free();
 }
diff --git a/tests/ffi/function_test.dart b/tests/ffi/function_test.dart
index 2865d30..f31a470 100644
--- a/tests/ffi/function_test.dart
+++ b/tests/ffi/function_test.dart
@@ -12,6 +12,7 @@
 library FfiTest;
 
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
 import 'dylib_utils.dart';
 
@@ -38,6 +39,7 @@
     testFloatRounding();
     testVoidReturn();
     testNoArgs();
+    testException();
   }
 }
 
@@ -50,7 +52,7 @@
 typedef GenericBinaryOp<T> = int Function(int, T);
 
 void testNativeFunctionFromCast() {
-  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
   ffi.Pointer<ffi.NativeFunction<NativeBinaryOp>> p2 = p1.cast();
   p2.asFunction<BinaryOp>();
   p2.asFunction<GenericBinaryOp<int>>();
@@ -83,73 +85,73 @@
 typedef NativeReturnMaxUint8 = ffi.Uint8 Function();
 int Function() returnMaxUint8 = ffiTestFunctions
     .lookup("ReturnMaxUint8")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint8>>>()
+    .cast<ffi.NativeFunction<NativeReturnMaxUint8>>()
     .asFunction();
 
 typedef NativeReturnMaxUint16 = ffi.Uint16 Function();
 int Function() returnMaxUint16 = ffiTestFunctions
     .lookup("ReturnMaxUint16")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint16>>>()
+    .cast<ffi.NativeFunction<NativeReturnMaxUint16>>()
     .asFunction();
 
 typedef NativeReturnMaxUint32 = ffi.Uint32 Function();
 int Function() returnMaxUint32 = ffiTestFunctions
     .lookup("ReturnMaxUint32")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMaxUint32>>>()
+    .cast<ffi.NativeFunction<NativeReturnMaxUint32>>()
     .asFunction();
 
 typedef NativeReturnMinInt8 = ffi.Int8 Function();
 int Function() returnMinInt8 = ffiTestFunctions
     .lookup("ReturnMinInt8")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt8>>>()
+    .cast<ffi.NativeFunction<NativeReturnMinInt8>>()
     .asFunction();
 
 typedef NativeReturnMinInt16 = ffi.Int16 Function();
 int Function() returnMinInt16 = ffiTestFunctions
     .lookup("ReturnMinInt16")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt16>>>()
+    .cast<ffi.NativeFunction<NativeReturnMinInt16>>()
     .asFunction();
 
 typedef NativeReturnMinInt32 = ffi.Int32 Function();
 int Function() returnMinInt32 = ffiTestFunctions
     .lookup("ReturnMinInt32")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeReturnMinInt32>>>()
+    .cast<ffi.NativeFunction<NativeReturnMinInt32>>()
     .asFunction();
 
 typedef NativeTakeMaxUint8 = ffi.IntPtr Function(ffi.Uint8);
 int Function(int) takeMaxUint8 = ffiTestFunctions
     .lookup("TakeMaxUint8")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint8>>>()
+    .cast<ffi.NativeFunction<NativeTakeMaxUint8>>()
     .asFunction();
 
 typedef NativeTakeMaxUint16 = ffi.IntPtr Function(ffi.Uint16);
 int Function(int) takeMaxUint16 = ffiTestFunctions
     .lookup("TakeMaxUint16")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint16>>>()
+    .cast<ffi.NativeFunction<NativeTakeMaxUint16>>()
     .asFunction();
 
 typedef NativeTakeMaxUint32 = ffi.IntPtr Function(ffi.Uint32);
 int Function(int) takeMaxUint32 = ffiTestFunctions
     .lookup("TakeMaxUint32")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMaxUint32>>>()
+    .cast<ffi.NativeFunction<NativeTakeMaxUint32>>()
     .asFunction();
 
 typedef NativeTakeMinInt8 = ffi.IntPtr Function(ffi.Int8);
 int Function(int) takeMinInt8 = ffiTestFunctions
     .lookup("TakeMinInt8")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt8>>>()
+    .cast<ffi.NativeFunction<NativeTakeMinInt8>>()
     .asFunction();
 
 typedef NativeTakeMinInt16 = ffi.IntPtr Function(ffi.Int16);
 int Function(int) takeMinInt16 = ffiTestFunctions
     .lookup("TakeMinInt16")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt16>>>()
+    .cast<ffi.NativeFunction<NativeTakeMinInt16>>()
     .asFunction();
 
 typedef NativeTakeMinInt32 = ffi.IntPtr Function(ffi.Int32);
 int Function(int) takeMinInt32 = ffiTestFunctions
     .lookup("TakeMinInt32")
-    .cast<ffi.Pointer<ffi.NativeFunction<NativeTakeMinInt32>>>()
+    .cast<ffi.NativeFunction<NativeTakeMinInt32>>()
     .asFunction();
 
 void testExtension() {
@@ -351,7 +353,7 @@
     .lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
 
 void testNativeFunctionPointer() {
-  ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+  ffi.Pointer<ffi.Int64> p2 = Pointer.allocate(count: 2);
   p2.store(42);
   p2.elementAt(1).store(1000);
   ffi.Pointer<ffi.Int64> result = assign1337Index1(p2);
@@ -381,12 +383,12 @@
     .lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("NullableInt64ElemAt1");
 
 void testNullPointers() {
-  ffi.Pointer<ffi.Int64> result = nullableInt64ElemAt1(null);
-  Expect.isNull(result);
+  Pointer<ffi.Int64> result = nullableInt64ElemAt1(ffi.nullptr.cast());
+  Expect.equals(result, ffi.nullptr);
 
-  ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+  Pointer<ffi.Int64> p2 = Pointer.allocate(count: 2);
   result = nullableInt64ElemAt1(p2);
-  Expect.isNotNull(result);
+  Expect.notEquals(result, ffi.nullptr);
   p2.free();
 }
 
@@ -397,7 +399,7 @@
     NativeFloatPointerToBool, FloatPointerToBool>("IsRoughly1337");
 
 void testFloatRounding() {
-  ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+  Pointer<ffi.Float> p2 = Pointer.allocate();
   p2.store(1337.0);
 
   int result = isRoughly1337(p2);
@@ -430,3 +432,15 @@
   double result = inventFloatValue();
   Expect.approxEquals(1337.0, result);
 }
+
+// Throw an exception from within the trampoline and collect a stacktrace
+// include its frame.
+void testException() {
+  try {
+    sumPlus42(null, null);
+  } catch (e, s) {
+    print("$e, $s");
+    return;
+  }
+  throw "Didn't throw!";
+}
diff --git a/tests/ffi/negative_function_test.dart b/tests/ffi/negative_function_test.dart
index f851728..d96c17c 100644
--- a/tests/ffi/negative_function_test.dart
+++ b/tests/ffi/negative_function_test.dart
@@ -13,6 +13,8 @@
 main() {
   testWrongArity();
   testWrongTypes();
+  testDynamicAsFunction();
+  testDynamicLookupFunction();
 }
 
 ffi.DynamicLibrary ffiTestFunctions =
@@ -61,3 +63,21 @@
     Expect.throwsTypeError(() => pointerOp(0));
   }
 }
+
+// Test that invoking 'Pointer.asFunction' with a dynamic receiver type throws
+// an exception.
+void testDynamicAsFunction() {
+  dynamic x = ffi.nullptr.cast<ffi.NativeFunction<ffi.Void Function()>>();
+  Expect.throwsUnsupportedError(() {
+    x.asFunction<void Function()>();
+  });
+}
+
+// Test that invoking 'DynamicLibrary.lookupFunction' with a dynamic receiver
+// type throws an exception.
+void testDynamicLookupFunction() {
+  dynamic lib = ffiTestFunctions;
+  Expect.throwsUnsupportedError(() {
+    lib.lookupFunction<ffi.Void Function(), void Function()>("_");
+  });
+}
diff --git a/tests/ffi/object_gc_test.dart b/tests/ffi/object_gc_test.dart
new file mode 100644
index 0000000..deecb10
--- /dev/null
+++ b/tests/ffi/object_gc_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, 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 GC of Pointer objects.
+//
+// SharedObjects=ffi_test_functions
+
+library FfiTest;
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+import 'cstring.dart';
+import 'dylib_utils.dart';
+
+DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
+
+final triggerGc = ffiTestFunctions
+    .lookupFunction<Void Function(), void Function()>("TriggerGC");
+
+void main() async {
+  testSizeOf();
+  testGC();
+}
+
+dynamic bar;
+
+Future<void> testGC() async {
+  bar = Pointer<Int8>.fromAddress(11);
+  // Verify that the objects manufactured by 'fromAddress' can be scanned by the
+  // GC.
+  triggerGc();
+}
+
+void testSizeOf() {
+  Expect.equals(true, 4 == sizeOf<Pointer>() || 8 == sizeOf<Pointer>());
+}
diff --git a/tests/ffi/regress_37100_test.dart b/tests/ffi/regress_37100_test.dart
index 7281042..19af367 100644
--- a/tests/ffi/regress_37100_test.dart
+++ b/tests/ffi/regress_37100_test.dart
@@ -10,12 +10,12 @@
 
 import 'dylib_utils.dart';
 
-class EVP_MD extends Pointer<Void> {}
+class EVP_MD extends Struct<EVP_MD> {}
 
 DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
 
-final EVP_sha1 = ffiTestFunctions
-    .lookupFunction<EVP_MD Function(), EVP_MD Function()>('LargePointer');
+final EVP_sha1 = ffiTestFunctions.lookupFunction<Pointer<EVP_MD> Function(),
+    Pointer<EVP_MD> Function()>('LargePointer');
 
 main() {
   int result = EVP_sha1().address;
diff --git a/tests/ffi/regress_37254_test.dart b/tests/ffi/regress_37254_test.dart
new file mode 100644
index 0000000..faf9897
--- /dev/null
+++ b/tests/ffi/regress_37254_test.dart
@@ -0,0 +1,263 @@
+// Copyright (c) 2019, 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.
+//
+// This program tests interaction with generic Pointers.
+//
+// Notation used in following tables:
+// * static_type//dynamic_type
+// * P = Pointer
+// * I = Int8
+// * NT = NativeType
+//
+// Note #1: When NNBD is landed, implicit downcasts will be static errors.
+//
+// Note #2: When we switch to extension methods we will _only_ use the static
+//          type of the container.
+//
+// ===== a.store(b) ======
+// Does a.store(b), where a and b have specific static and dynamic types: run
+// fine, fail at compile time, or fail at runtime?
+// =======================
+//                  b     P<I>//P<I>   P<NT>//P<I>           P<NT>//P<NT>
+// a
+// P<P<I>>//P<P<I>>     1 ok         2 implicit downcast   3 implicit downcast
+//                                     of argument: ok       of argument: fail
+//                                                           at runtime
+//
+// P<P<NT>>//P<P<I>>    4 ok         5 ok                  6 fail at runtime
+//
+// P<P<NT>>//P<P<NT>>   7 ok         8 ok                  9 ok
+//
+// ====== final c = a.load() ======
+// What is the (inferred) static type and runtime type of `a.load()`. Note that
+// we assume extension method here: on Pointer<PointerT>> { Pointer<T> load(); }
+// ================================
+// a                    a.load()
+//                      inferred static type*//runtime type
+// P<P<I>>//P<P<I>>     P<I>//P<I>
+//
+// P<P<NT>>//P<P<I>>    P<NT>//P<I>
+//
+// P<P<NT>>//P<P<NT>>   P<NT>//P<NT>
+//
+// * The inferred static type when we get extension methods.
+//
+// ====== b = a.load() ======
+// What happens when we try to assign the result of a.load() to variable b with
+// a specific static type: runs fine, fails at compile time, or fails at runtime.
+// ==========================
+//                  b     P<I>                        P<NT>
+// a
+// P<P<I>>//P<P<I>>     1 ok                        2 ok
+//
+// P<P<NT>>//P<P<I>>    3 implicit downcast         4 ok
+//                        of returnvalue: ok
+//
+// P<P<NT>>//P<P<NT>>   5 implicit downcast         6 ok
+//                        of returnvalue: fail
+//                        at runtime
+//
+// These are the normal Dart assignment rules.
+
+import 'dart:ffi';
+
+import "package:expect/expect.dart";
+
+// ===== a.store(b) ======
+// The tests follow table cells left to right, top to bottom.
+void store1() {
+  final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+  final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store2() {
+  final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+  final Pointer<NativeType> b =
+      Pointer<Int8>.allocate(); // Reified Pointer<Int8> at runtime.
+
+  // Successful implicit downcast of argument at runtime.
+  // Should succeed now, should statically be rejected when NNBD lands.
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store3() {
+  final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+  final Pointer<NativeType> b =
+      Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+  // Failing implicit downcast of argument at runtime.
+  // Should fail now at runtime, should statically be rejected when NNBD lands.
+  Expect.throws(() {
+    a.store(b);
+  });
+
+  a.free();
+  b.free();
+}
+
+void store4() {
+  // Reified as Pointer<Pointer<Int8>> at runtime.
+  final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+  final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store5() {
+  // Reified as Pointer<Pointer<Int8>> at runtime.
+  final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+  final Pointer<NativeType> b =
+      Pointer<Int8>.allocate(); // Reified as Pointer<Int8> at runtime.
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store6() {
+  // Reified as Pointer<Pointer<Int8>> at runtime.
+  final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+  final Pointer<NativeType> b =
+      Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+  // Fails on type check of argument.
+  Expect.throws(() {
+    a.store(b);
+  });
+
+  a.free();
+  b.free();
+}
+
+void store7() {
+  final Pointer<Pointer<NativeType>> a =
+      Pointer<Pointer<NativeType>>.allocate();
+  final Pointer<Int8> b = Pointer<Int8>.allocate();
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store8() {
+  final Pointer<Pointer<NativeType>> a =
+      Pointer<Pointer<NativeType>>.allocate();
+
+  // Reified as Pointer<Int8> at runtime.
+  final Pointer<NativeType> b = Pointer<Int8>.allocate();
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+void store9() {
+  final Pointer<Pointer<NativeType>> a =
+      Pointer<Pointer<NativeType>>.allocate();
+  final Pointer<NativeType> b =
+      Pointer<Int8>.allocate().cast<Pointer<NativeType>>();
+
+  a.store(b);
+
+  a.free();
+  b.free();
+}
+
+// ====== b = a.load() ======
+// The tests follow table cells left to right, top to bottom.
+void load1() {
+  final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+
+  Pointer<Int8> b = a.load();
+  Expect.type<Pointer<Int8>>(b);
+
+  a.free();
+}
+
+void load2() {
+  final Pointer<Pointer<Int8>> a = Pointer<Pointer<Int8>>.allocate();
+
+  Pointer<NativeType> b = a.load<Pointer<Int8>>();
+  Expect.type<Pointer<Int8>>(b);
+
+  a.free();
+}
+
+void load3() {
+  // Reified as Pointer<Pointer<Int8>> at runtime.
+  final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+  Pointer<Int8> b = a.load<Pointer<NativeType>>();
+  Expect.type<Pointer<Int8>>(b);
+
+  a.free();
+}
+
+void load4() {
+  // Reified as Pointer<Pointer<Int8>> at runtime.
+  final Pointer<Pointer<NativeType>> a = Pointer<Pointer<Int8>>.allocate();
+
+  // Return value runtime type is Pointer<Int8>.
+  Pointer<NativeType> b = a.load();
+  Expect.type<Pointer<Int8>>(b);
+
+  a.free();
+}
+
+void load5() {
+  final Pointer<Pointer<NativeType>> a =
+      Pointer<Pointer<NativeType>>.allocate();
+
+  // Failing implicit downcast of return value at runtime.
+  // Should fail now at runtime, should statically be rejected when NNBD lands.
+  Expect.throws(() {
+    Pointer<Int8> b = a.load<Pointer<NativeType>>();
+  });
+
+  a.free();
+}
+
+void load6() {
+  final Pointer<Pointer<NativeType>> a =
+      Pointer<Pointer<NativeType>>.allocate();
+
+  Pointer<NativeType> b = a.load();
+  Expect.type<Pointer<NativeType>>(b);
+
+  a.free();
+}
+
+void main() {
+  store1();
+  store2();
+  store3();
+  store4();
+  store5();
+  store6();
+  store7();
+  store8();
+  store9();
+  load1();
+  load2();
+  load3();
+  load4();
+  load5();
+  load6();
+}
diff --git a/tests/ffi/snapshot_test.dart b/tests/ffi/snapshot_test.dart
index 02b4cc4..a3b7d22 100644
--- a/tests/ffi/snapshot_test.dart
+++ b/tests/ffi/snapshot_test.dart
@@ -14,7 +14,7 @@
 
 main(args) async {
   try {
-    await Isolate.spawn(print, fromAddress<Pointer<Void>>(1));
+    await Isolate.spawn(print, Pointer<Void>.fromAddress(1));
   } catch (e) {
     Expect.type<ArgumentError>(e);
     return;
diff --git a/tests/ffi/static_checks_test.dart b/tests/ffi/static_checks_test.dart
index e0ab94c..7b8cdfb 100644
--- a/tests/ffi/static_checks_test.dart
+++ b/tests/ffi/static_checks_test.dart
@@ -9,6 +9,7 @@
 library FfiTest;
 
 import 'dart:ffi' as ffi;
+import 'dart:ffi' show Pointer;
 
 import 'dylib_utils.dart';
 
@@ -55,7 +56,7 @@
     return result;
   }
 
-  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate();
   p.store(123);
   ffi.Pointer loseType = p;
   generic(loseType);
@@ -64,7 +65,7 @@
 
 void testGetGeneric2() {
   T generic<T extends Object>() {
-    ffi.Pointer<ffi.Int8> p = ffi.allocate();
+    Pointer<ffi.Int8> p = Pointer.allocate();
     p.store(123);
     T result;
     result = p.load<T>(); //# 21: compile-time error
@@ -76,7 +77,7 @@
 }
 
 void testGetVoid() {
-  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
   ffi.Pointer<ffi.Void> p2 = p1.cast();
 
   p2.load<int>(); //# 22: compile-time error
@@ -85,7 +86,7 @@
 }
 
 void testGetNativeFunction() {
-  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
   IntUnOp f = p.load(); //# 23: compile-time error
 }
 
@@ -94,8 +95,8 @@
 }
 
 void testGetTypeMismatch() {
-  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
-  ffi.Pointer<ffi.Int16> typedNull = null;
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = Pointer.allocate();
+  ffi.Pointer<ffi.Int16> typedNull = ffi.nullptr.cast();
   p.store(typedNull);
 
   // this fails to compile due to type mismatch
@@ -109,7 +110,7 @@
     p.store(123); //# 26: compile-time error
   }
 
-  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p = Pointer.allocate();
   p.store(123);
   ffi.Pointer loseType = p;
   generic(loseType);
@@ -118,7 +119,7 @@
 
 void testSetGeneric2() {
   void generic<T extends Object>(T arg) {
-    ffi.Pointer<ffi.Int8> p = ffi.allocate();
+    ffi.Pointer<ffi.Int8> p = Pointer.allocate();
     p.store(arg); //# 27: compile-time error
     p.free();
   }
@@ -127,7 +128,7 @@
 }
 
 void testSetVoid() {
-  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.IntPtr> p1 = Pointer.allocate();
   ffi.Pointer<ffi.Void> p2 = p1.cast();
 
   p2.store(1234); //# 28: compile-time error
@@ -136,7 +137,7 @@
 }
 
 void testSetNativeFunction() {
-  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
   IntUnOp f = (a) => a + 1;
   p.store(f); //# 29: compile-time error
 }
@@ -147,10 +148,10 @@
 
 void testSetTypeMismatch() {
   // the pointer to pointer types must match up
-  ffi.Pointer<ffi.Int8> pHelper = ffi.allocate();
+  ffi.Pointer<ffi.Int8> pHelper = Pointer.allocate();
   pHelper.store(123);
 
-  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = Pointer.allocate();
 
   // this fails to compile due to type mismatch
   p.store(pHelper); //# 40: compile-time error
@@ -161,7 +162,7 @@
 
 void testAsFunctionGeneric() {
   T generic<T extends Function>() {
-    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
     Function f;
     f = p.asFunction<T>(); //# 11: compile-time error
     return f;
@@ -177,7 +178,7 @@
     return f;
   }
 
-  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
   generic(p);
 }
 
@@ -189,7 +190,7 @@
 typedef IntBinOp = int Function(int, int);
 
 void testAsFunctionTypeMismatch() {
-  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = Pointer.fromAddress(1337);
   IntBinOp f = p.asFunction(); //# 14: compile-time error
 }
 
@@ -303,67 +304,132 @@
 }
 
 // error on missing field annotation
-@ffi.struct
-class TestStruct extends ffi.Pointer<ffi.Void> {
+class TestStruct extends ffi.Struct<TestStruct> {
   @ffi.Double()
   double x;
 
   double y; //# 50: compile-time error
 }
 
-// error on missing struct annotation
-class TestStruct2 extends ffi.Pointer<ffi.Void> {
-  @ffi.Double() //# 51: compile-time error
-  double x; //# 51: compile-time error
-}
-
-// error on missing annotation on subtype
-@ffi.struct
-class TestStruct3 extends TestStruct {
-  double z; //# 52: compile-time error
-}
+// Cannot extend structs.
+class TestStruct3 extends TestStruct {} //# 52: compile-time error
 
 // error on double annotation
-@ffi.struct
-class TestStruct4 extends ffi.Pointer<ffi.Void> {
+class TestStruct4 extends ffi.Struct<TestStruct4> {
   @ffi.Double()
   @ffi.Double() //# 53: compile-time error
   double z;
 }
 
 // error on annotation not matching up
-@ffi.struct
-class TestStruct5 extends ffi.Pointer<ffi.Void> {
+class TestStruct5 extends ffi.Struct<TestStruct5> {
   @ffi.Int64() //# 54: compile-time error
   double z; //# 54: compile-time error
 }
 
 // error on annotation not matching up
-@ffi.struct
-class TestStruct6 extends ffi.Pointer<ffi.Void> {
+class TestStruct6 extends ffi.Struct<TestStruct6> {
   @ffi.Void() //# 55: compile-time error
   double z; //# 55: compile-time error
 }
 
 // error on annotation not matching up
-@ffi.struct
-class TestStruct7 extends ffi.Pointer<ffi.Void> {
+class TestStruct7 extends ffi.Struct<TestStruct7> {
   @ffi.NativeType() //# 56: compile-time error
   double z; //# 56: compile-time error
 }
 
 // error on field initializer on field
-@ffi.struct
-class TestStruct8 extends ffi.Pointer<ffi.Void> {
+class TestStruct8 extends ffi.Struct<TestStruct8> {
   @ffi.Double() //# 57: compile-time error
   double z = 10.0; //# 57: compile-time error
 }
 
 // error on field initializer in constructor
-@ffi.struct
-class TestStruct9 extends ffi.Pointer<ffi.Void> {
+class TestStruct9 extends ffi.Struct<TestStruct9> {
   @ffi.Double()
   double z;
 
   TestStruct9() : z = 0.0 {} //# 58: compile-time error
 }
+
+// A struct "C" must extend "Struct<C>", not "Struct<AnythingElse>".
+class TestStruct10 extends ffi.Struct<ffi.Int8> {} //# 59: compile-time error
+
+// Struct classes may not be generic.
+class TestStruct11<T> extends ffi.Struct<TestStruct11<dynamic>> {} //# 60: compile-time error
+
+// Structs may not appear inside structs (currently, there is no suitable
+// annotation).
+class TestStruct12 extends ffi.Struct<TestStruct12> {
+  @ffi.Pointer //# 61: compile-time error
+  TestStruct9 struct; //# 61: compile-time error
+}
+
+// Cannot extend native types.
+
+class ENativeType extends ffi.NativeType {} //# 90: compile-time error
+
+class EInt8 extends ffi.Int8 {} //# 91: compile-time error
+
+class EInt16 extends ffi.Int16 {} //# 92: compile-time error
+
+class EInt32 extends ffi.Int32 {} //# 93: compile-time error
+
+class EInt64 extends ffi.Int64 {} //# 94: compile-time error
+
+class EUint8 extends ffi.Uint8 {} //# 95: compile-time error
+
+class EUint16 extends ffi.Uint16 {} //# 96: compile-time error
+
+class EUint32 extends ffi.Uint32 {} //# 97: compile-time error
+
+class EUint64 extends ffi.Uint64 {} //# 98: compile-time error
+
+class EIntPtr extends ffi.IntPtr {} //# 99: compile-time error
+
+class EFloat extends ffi.Float {} //# 910: compile-time error
+
+class EDouble extends ffi.Double {} //# 911: compile-time error
+
+class EVoid extends ffi.Void {} //# 912: compile-time error
+
+class ENativeFunction extends ffi.NativeFunction {} //# 913: compile-time error
+
+class EPointer extends ffi.Pointer {} //# 914: compile-time error
+
+// Cannot implement native natives or Struct.
+
+// Cannot extend native types.
+
+class INativeType implements ffi.NativeType {} //# 80: compile-time error
+
+class IInt8 implements ffi.Int8 {} //# 81: compile-time error
+
+class IInt16 implements ffi.Int16 {} //# 82: compile-time error
+
+class IInt32 implements ffi.Int32 {} //# 83: compile-time error
+
+class IInt64 implements ffi.Int64 {} //# 84: compile-time error
+
+class IUint8 implements ffi.Uint8 {} //# 85: compile-time error
+
+class IUint16 implements ffi.Uint16 {} //# 86: compile-time error
+
+class IUint32 implements ffi.Uint32 {} //# 87: compile-time error
+
+class IUint64 implements ffi.Uint64 {} //# 88: compile-time error
+
+class IIntPtr implements ffi.IntPtr {} //# 88: compile-time error
+
+class IFloat implements ffi.Float {} //# 810: compile-time error
+
+class IDouble implements ffi.Double {} //# 811: compile-time error
+
+class IVoid implements ffi.Void {} //# 812: compile-time error
+
+class INativeFunction implements ffi.NativeFunction {} //# 813: compile-time error
+
+class IPointer implements ffi.Pointer {} //# 814: compile-time error
+
+class IStruct implements ffi.Struct {} //# 815: compile-time error
diff --git a/tests/ffi/structs_test.dart b/tests/ffi/structs_test.dart
index cbb2eab..a2ed758 100644
--- a/tests/ffi/structs_test.dart
+++ b/tests/ffi/structs_test.dart
@@ -6,12 +6,11 @@
 
 library FfiTest;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 import "package:expect/expect.dart";
 
 import 'coordinate_bare.dart' as bare;
-import 'coordinate_manual.dart' as manual;
 import 'coordinate.dart';
 
 void main() {
@@ -19,24 +18,24 @@
   testStructFromAddress();
   testStructWithNulls();
   testBareStruct();
-  testManualStruct();
   testTypeTest();
 }
 
 /// allocates each coordinate separately in c memory
 void testStructAllocate() {
-  Coordinate c1 = Coordinate(10.0, 10.0, null);
-  Coordinate c2 = Coordinate(20.0, 20.0, c1);
-  Coordinate c3 = Coordinate(30.0, 30.0, c2);
-  c1.next = c3;
+  Pointer<Coordinate> c1 =
+      Coordinate.allocate(10.0, 10.0, nullptr.cast()).addressOf;
+  Pointer<Coordinate> c2 = Coordinate.allocate(20.0, 20.0, c1).addressOf;
+  Pointer<Coordinate> c3 = Coordinate.allocate(30.0, 30.0, c2).addressOf;
+  c1.load<Coordinate>().next = c3;
 
-  Coordinate currentCoordinate = c1;
+  Coordinate currentCoordinate = c1.load();
   Expect.equals(10.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(30.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(20.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(10.0, currentCoordinate.x);
 
   c1.free();
@@ -46,91 +45,76 @@
 
 /// allocates coordinates consecutively in c memory
 void testStructFromAddress() {
-  Coordinate c1 = Coordinate.allocate(count: 3);
-  Coordinate c2 = c1.elementAt(1);
-  Coordinate c3 = c1.elementAt(2);
-  c1.x = 10.0;
-  c1.y = 10.0;
-  c1.next = c3;
-  c2.x = 20.0;
-  c2.y = 20.0;
-  c2.next = c1;
-  c3.x = 30.0;
-  c3.y = 30.0;
-  c3.next = c2;
+  Pointer<Coordinate> c1 = Pointer.allocate(count: 3);
+  Pointer<Coordinate> c2 = c1.elementAt(1);
+  Pointer<Coordinate> c3 = c1.elementAt(2);
+  c1.load<Coordinate>().x = 10.0;
+  c1.load<Coordinate>().y = 10.0;
+  c1.load<Coordinate>().next = c3;
+  c2.load<Coordinate>().x = 20.0;
+  c2.load<Coordinate>().y = 20.0;
+  c2.load<Coordinate>().next = c1;
+  c3.load<Coordinate>().x = 30.0;
+  c3.load<Coordinate>().y = 30.0;
+  c3.load<Coordinate>().next = c2;
 
-  Coordinate currentCoordinate = c1;
+  Coordinate currentCoordinate = c1.load();
   Expect.equals(10.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(30.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(20.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(10.0, currentCoordinate.x);
 
   c1.free();
 }
 
 void testStructWithNulls() {
-  Coordinate coordinate = Coordinate(10.0, 10.0, null);
-  Expect.isNull(coordinate.next);
-  coordinate.next = coordinate;
-  Expect.isNotNull(coordinate.next);
-  coordinate.next = null;
-  Expect.isNull(coordinate.next);
+  Pointer<Coordinate> coordinate =
+      Coordinate.allocate(10.0, 10.0, nullptr.cast<Coordinate>()).addressOf;
+  Expect.equals(coordinate.load<Coordinate>().next, nullptr);
+  coordinate.load<Coordinate>().next = coordinate;
+  Expect.notEquals(coordinate.load<Coordinate>().next, nullptr);
+  coordinate.load<Coordinate>().next = nullptr.cast();
+  Expect.equals(coordinate.load<Coordinate>().next, nullptr);
   coordinate.free();
 }
 
 void testBareStruct() {
-  int structSize = ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
-  bare.Coordinate c1 = ffi.allocate<ffi.Uint8>(count: structSize * 3).cast();
-  bare.Coordinate c2 = c1.offsetBy(structSize).cast();
-  bare.Coordinate c3 = c1.offsetBy(structSize * 2).cast();
+  int structSize = sizeOf<Double>() * 2 + sizeOf<IntPtr>();
+  bare.Coordinate c1 = Pointer<Uint8>.allocate(count: structSize * 3)
+      .cast<bare.Coordinate>()
+      .load();
+  bare.Coordinate c2 =
+      c1.addressOf.offsetBy(structSize).cast<bare.Coordinate>().load();
+  bare.Coordinate c3 =
+      c1.addressOf.offsetBy(structSize * 2).cast<bare.Coordinate>().load();
   c1.x = 10.0;
   c1.y = 10.0;
-  c1.next = c3;
+  c1.next = c3.addressOf;
   c2.x = 20.0;
   c2.y = 20.0;
-  c2.next = c1;
+  c2.next = c1.addressOf;
   c3.x = 30.0;
   c3.y = 30.0;
-  c3.next = c2;
+  c3.next = c2.addressOf;
 
   bare.Coordinate currentCoordinate = c1;
   Expect.equals(10.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(30.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(20.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
+  currentCoordinate = currentCoordinate.next.load();
   Expect.equals(10.0, currentCoordinate.x);
 
-  c1.free();
-}
-
-void testManualStruct() {
-  manual.Coordinate c1 = manual.Coordinate(10.0, 10.0, null);
-  manual.Coordinate c2 = manual.Coordinate(20.0, 20.0, c1);
-  manual.Coordinate c3 = manual.Coordinate(30.0, 30.0, c2);
-  c1.next = c3;
-
-  manual.Coordinate currentCoordinate = c1;
-  Expect.equals(10.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
-  Expect.equals(30.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
-  Expect.equals(20.0, currentCoordinate.x);
-  currentCoordinate = currentCoordinate.next;
-  Expect.equals(10.0, currentCoordinate.x);
-
-  c1.free();
-  c2.free();
-  c3.free();
+  c1.addressOf.free();
 }
 
 void testTypeTest() {
-  Coordinate c = Coordinate(10, 10, null);
-  Expect.isTrue(c is ffi.Pointer);
-  Expect.isTrue(c is ffi.Pointer<ffi.Void>);
-  c.free();
+  Coordinate c = Coordinate.allocate(10, 10, nullptr.cast<Coordinate>());
+  Expect.isTrue(c is Struct);
+  Expect.isTrue(c is Struct<Coordinate>);
+  c.addressOf.free();
 }
diff --git a/tests/ffi/subtype_test.dart b/tests/ffi/subtype_test.dart
deleted file mode 100644
index 54977b5..0000000
--- a/tests/ffi/subtype_test.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2019, 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.
-//
-// Dart test program for testing dart:ffi Pointer subtypes.
-//
-// SharedObjects=ffi_test_functions
-// VMOptions=--verbose-gc
-
-library FfiTest;
-
-import 'dart:ffi' as ffi;
-
-import "package:expect/expect.dart";
-
-import 'cstring.dart';
-import 'dylib_utils.dart';
-
-ffi.DynamicLibrary ffiTestFunctions =
-    dlopenPlatformSpecific("ffi_test_functions");
-
-final triggerGc = ffiTestFunctions
-    .lookupFunction<ffi.Void Function(), void Function()>("TriggerGC");
-
-void main() async {
-  testAllocate();
-  testSizeOf();
-  testGC();
-}
-
-dynamic bar;
-
-void testAllocate() {
-  CString cs = CString.toUtf8("hello world!");
-  Expect.equals("hello world!", cs.fromUtf8());
-  cs.free();
-}
-
-Future<void> testGC() async {
-  bar = ffi.fromAddress<CString>(11);
-  // Verify that the objects manufactured by 'fromAddress' can be scanned by the
-  // GC.
-  triggerGc();
-}
-
-void testSizeOf() {
-  Expect.equals(true, 4 == ffi.sizeOf<CString>() || 8 == ffi.sizeOf<CString>());
-}
diff --git a/tests/ffi/very_large_struct.dart b/tests/ffi/very_large_struct.dart
index 283cb57..06cbac6 100644
--- a/tests/ffi/very_large_struct.dart
+++ b/tests/ffi/very_large_struct.dart
@@ -4,64 +4,52 @@
 
 library FfiTestCoordinateBare;
 
-import 'dart:ffi' as ffi;
+import 'dart:ffi';
 
 /// Large sample struct for dart:ffi library.
-@ffi.struct
-class VeryLargeStruct extends ffi.Pointer<ffi.Void> {
-  @ffi.Int8()
+class VeryLargeStruct extends Struct<VeryLargeStruct> {
+  @Int8()
   int a;
 
-  @ffi.Int16()
+  @Int16()
   int b;
 
-  @ffi.Int32()
+  @Int32()
   int c;
 
-  @ffi.Int64()
+  @Int64()
   int d;
 
-  @ffi.Uint8()
+  @Uint8()
   int e;
 
-  @ffi.Uint16()
+  @Uint16()
   int f;
 
-  @ffi.Uint32()
+  @Uint32()
   int g;
 
-  @ffi.Uint64()
+  @Uint64()
   int h;
 
-  @ffi.IntPtr()
+  @IntPtr()
   int i;
 
-  @ffi.Float()
+  @Float()
   double j;
 
-  @ffi.Double()
+  @Double()
   double k;
 
-  @ffi.Pointer()
-  VeryLargeStruct parent;
+  @Pointer()
+  Pointer<VeryLargeStruct> parent;
 
-  @ffi.IntPtr()
+  @IntPtr()
   int numChidlren;
 
-  @ffi.Pointer()
-  VeryLargeStruct children;
+  @Pointer()
+  Pointer<VeryLargeStruct> children;
 
-  @ffi.Int8()
+  @Int8()
   int smallLastField;
-
-  // generated by @ffi.struct annotation
-  external static int sizeOf();
-
-  VeryLargeStruct offsetBy(int offsetInBytes) =>
-      super.offsetBy(offsetInBytes).cast();
-
-  VeryLargeStruct elementAt(int index) => offsetBy(sizeOf() * index);
-
-  static VeryLargeStruct allocate({int count: 1}) =>
-      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
 }
diff --git a/tests/language_2/branch_canonicalization_test.dart b/tests/language_2/branch_canonicalization_test.dart
index dfb35f6..49990cd 100644
--- a/tests/language_2/branch_canonicalization_test.dart
+++ b/tests/language_2/branch_canonicalization_test.dart
@@ -47,7 +47,7 @@
 
 main() {
   final a = 1.0;
-  final b = 1 << 62;
+  final b = 0x4000000000000000; // 1 << 62
   final x = new A(), y = new B(), z = new C();
   for (var i = 0; i < 20; i++) {
     Expect.equals(1, fooDouble(a, a));
diff --git a/tests/language_2/const_map4_test.dart b/tests/language_2/const_map4_test.dart
index 2d759b9..397672c 100644
--- a/tests/language_2/const_map4_test.dart
+++ b/tests/language_2/const_map4_test.dart
@@ -13,11 +13,15 @@
   b = const {1: 'a', 2: 'b', 3: 'c'};
   Expect.equals(true, a == b);
 
+  a = const <int, String>{1: 'a', 2: 'b', 3: 'c'};
+  b = const {1: 'a', 2: 'b', 3: 'c'};
+  Expect.equals(true, a == b);
+
   a = const <num, String>{1: 'a', 2: 'b', 3: 'c'};
   b = const {1: 'a', 2: 'b', 3: 'c'};
   Expect.equals(false, a == b);
 
   a = const <dynamic, dynamic>{1: 'a', 2: 'b', 3: 'c'};
   b = const {1: 'a', 2: 'b', 3: 'c'};
-  Expect.equals(true, a == b);
+  Expect.equals(false, a == b);
 }
diff --git a/tests/language_2/fannkuch_test.dart b/tests/language_2/fannkuch_test.dart
index 4aac0f5..a08a0cf 100644
--- a/tests/language_2/fannkuch_test.dart
+++ b/tests/language_2/fannkuch_test.dart
@@ -1,8 +1,8 @@
 // Copyright (c) 2011, 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.
-// The Great Computer Language Shootout
-// http://shootout.alioth.debian.org/
+// The Computer Language Benchmarks Game
+// https://benchmarksgame-team.pages.debian.net/benchmarksgame/
 // Ported from JavaScript contributed by Isaac Gouy.
 // Description: Repeatedly access a tiny integer-sequence.
 
diff --git a/tests/language_2/implicit_creation/implicit_const_context_not_test.dart b/tests/language_2/implicit_creation/implicit_const_context_not_test.dart
new file mode 100644
index 0000000..7d69c0a
--- /dev/null
+++ b/tests/language_2/implicit_creation/implicit_const_context_not_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2019, 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";
+
+// Check places that are *not* supposed to be constant contexts,
+// but which do require constant values, do not introduce an implicit const.
+// Nested expressions still do.
+// (Also acts as regression test for http:/dartbug.com/36533)
+
+class C {
+  final v;
+
+  // Initializer of final field in class with const constructor.
+  // Can't use `const C()`, it's a cyclic constant dependency.
+  final i1 = []; //# 1: compile-time error
+  final i2 = const [];
+  final i3 = const [[]];
+
+  const C([this.v]);
+
+  // Initializer expression in generative const constructor.
+  const C.c1() : v = C(); //# 2: compile-time error
+  const C.c2() : v = const C();
+  const C.c3() : v = const C(C());
+
+  // Expression in redirecting generative const constuctor.
+  const C.r1() : this(C()); //# 3: compile-time error
+  const C.r2() : this(const C());
+  const C.r3() : this(const C(C()));
+
+  // Default value of positional optional parameter.
+  static List<C> foo([
+    p1 = C(), //# 4: compile-time error
+    p2 = const C(),
+    p3 = const C(C()),
+  ]) =>
+      [p2, p3];
+
+  // Default value of named optional parameter.
+  static List<C> bar({
+    p1 = C(), //# 5: compile-time error
+    p2 = const C(),
+    p3 = const C(C()),
+  }) =>
+      [p2, p3];
+}
+
+void main() {
+  var c = const C();
+  var cc = const C(C());
+
+  // Check that const constructors can be invoked without `const`,
+  // creating new instances every time.
+  var nc1 = C();
+  var nc2 = C.c2();
+  var nc3 = C.c3();
+  var nc4 = C.r2();
+  var nc5 = C.r3();
+  Expect.allDistinct([nc1, nc2, nc3, nc4, nc5, c, cc]);
+
+  // Check that const invocations create identical objects.
+  Expect.identical(c, C.c2().v);
+  Expect.identical(cc, C.c3().v);
+
+  Expect.identical(c, C.r2().v);
+  Expect.identical(cc, C.r3().v);
+
+  Expect.identical(const [], C().i2);
+  Expect.identical(const [[]], C().i3);
+
+  Expect.identical(c, C.foo()[0]);
+  Expect.identical(cc, C.foo()[1]);
+
+  Expect.identical(c, C.bar()[0]);
+  Expect.identical(cc, C.bar()[1]);
+}
diff --git a/tests/language_2/issue32353_2_test.dart b/tests/language_2/issue32353_2_test.dart
index c959089..19aff61 100644
--- a/tests/language_2/issue32353_2_test.dart
+++ b/tests/language_2/issue32353_2_test.dart
@@ -7,7 +7,7 @@
 // Error: 'D' can't implement both '#lib1::B<#lib1::D::X, #lib1::D::Y>' and
 // '#lib1::B<#lib1::D::X, #lib1::A>'
 // class D<X, Y> extends B<X, Y> with C<X> {}
-//       ^
+//       ~
 
 class A {}
 
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 3741571..4daa9a6 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -2,9 +2,6 @@
 # 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.
 
-[ $compiler == app_jit ]
-deferred_inheritance_constraints_test/redirecting_constructor: Crash
-
 [ $compiler == compare_analyzer_cfe ]
 const_native_factory_test: Fail # Issue 29763
 deferred_global_test: Fail # Issue 34503
@@ -24,6 +21,11 @@
 [ $compiler != dart2analyzer ]
 switch_case_warn_test: Skip # Analyzer only, see language_analyzer2.status
 
+[ $compiler == none ]
+invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34013
+library_env_test/has_no_mirror_support: RuntimeError, OK
+void/*: Skip # https://github.com/dart-lang/sdk/issues/34013
+
 [ $compiler == spec_parser ]
 double_literals/*: Skip # https://github.com/dart-lang/sdk/issues/34355
 invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34015
@@ -58,9 +60,6 @@
 partial_instantiation_static_bounds_check_test/02: MissingCompileTimeError # Issue 34327
 partial_instantiation_static_bounds_check_test/03: MissingCompileTimeError # Issue 34327
 
-[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
-built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
-
 [ $compiler != compare_analyzer_cfe && $compiler != dart2js && $compiler != spec_parser && !$fasta ]
 compile_time_constant_static5_test/11: CompileTimeError # Issue 30546
 compile_time_constant_static5_test/16: CompileTimeError # Issue 30546
@@ -93,14 +92,12 @@
 [ $compiler != dart2js && $compiler != dartdevc && !$checked ]
 function_type/*: Skip # Needs checked mode.
 
+[ $compiler != dartk && $compiler != dartkb && $compiler != dartkp && $mode == debug && $runtime == vm ]
+built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
+
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
-[ $compiler == app_jit || $compiler == none ]
-invalid_returns/*: Skip # https://github.com/dart-lang/sdk/issues/34013
-library_env_test/has_no_mirror_support: RuntimeError, OK
-void/*: Skip # https://github.com/dart-lang/sdk/issues/34013
-
 [ $hot_reload || $hot_reload_rollback ]
 cha_deopt1_test: Crash # Requires deferred libraries
 cha_deopt2_test: Crash # Requires deferred libraries
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index d6403c5..8f1b289 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -17,7 +17,6 @@
 bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-branch_canonicalization_test: RuntimeError
 call_method_as_cast_test/06: RuntimeError
 call_method_implicit_tear_off_implements_function_test/05: RuntimeError
 call_method_implicit_tear_off_implements_function_test/06: RuntimeError
@@ -37,10 +36,8 @@
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
 const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
 const_evaluation_test/01: RuntimeError
-const_list_test: RuntimeError
 const_map2_test/00: MissingCompileTimeError
 const_map3_test/00: MissingCompileTimeError
-const_map4_test: RuntimeError
 const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
 const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
 constructor12_test: RuntimeError
@@ -118,7 +115,6 @@
 library_env_test/has_mirror_support: Fail # mirrors not supported on web
 library_env_test/has_no_html_support: RuntimeError, OK
 library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
-list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 local_function2_test/none: RuntimeError
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
@@ -168,7 +164,6 @@
 modulo_test: RuntimeError # non JS number semantics
 named_parameters_default_eq_test/none: RuntimeError
 nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: RuntimeError
 no_main_test/01: CompileTimeError
 no_such_method_mock_test: RuntimeError
 null_no_such_method_test: CompileTimeError
@@ -198,10 +193,10 @@
 super_call4_test/01: MissingCompileTimeError
 super_test: RuntimeError
 tearoff_dynamic_test: RuntimeError
-truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
+truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
 type_constants_test/none: RuntimeError # Issue 35052
 type_error_test: RuntimeError
-type_literal_test: RuntimeError
+type_literal_canonicalization_test: RuntimeError
 type_promotion_more_specific_test/04: CompileTimeError
 vm/*: SkipByDesign # Tests for the VM.
 
@@ -269,7 +264,6 @@
 bit_operations_test/03: RuntimeError
 bit_operations_test/04: RuntimeError
 bit_operations_test/none: RuntimeError
-branch_canonicalization_test: RuntimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
 checked_method_error_order_test: RuntimeError
 class_cycle_test/02: MissingCompileTimeError
@@ -464,7 +458,6 @@
 mock_writable_final_private_field_test: RuntimeError # Issue 17526, 30847
 modulo_test: RuntimeError # non JS number semantics
 nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: Crash # Unsupported operation: Unsupported type parameter type node F.
 no_main_test/01: CompileTimeError
 not_enough_positional_arguments_test/00: MissingCompileTimeError
 not_enough_positional_arguments_test/01: MissingCompileTimeError
@@ -496,9 +489,9 @@
 stacktrace_test: RuntimeError # Issue 12698
 symbol_literal_test/01: MissingCompileTimeError
 tearoff_dynamic_test: RuntimeError
-truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
+truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
 type_check_const_function_typedef2_test: MissingCompileTimeError
-type_literal_test: RuntimeError
+type_literal_canonicalization_test: RuntimeError
 type_parameter_test/06: Crash # Internal Error: Unexpected type variable in static context.
 type_parameter_test/09: Crash # Internal Error: Unexpected type variable in static context.
 type_variable_scope_test/03: Crash # Internal Error: Unexpected type variable in static context.
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 26643dc..b2b9294 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -298,7 +298,6 @@
 bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-branch_canonicalization_test: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <1>) fails.
 built_in_identifier_prefix_test: CompileTimeError
 canonical_const2_test: RuntimeError # Ints and doubles are unified.; Expect.isFalse(true) fails.
 closure_call_wrong_argument_count_negative_test: Fail
@@ -307,7 +306,6 @@
 config_import_corelib_test: CompileTimeError
 const_evaluation_test/01: RuntimeError # dart:mirrors not supported in DDC
 const_list_test: RuntimeError # Expect.equals(expected: <false>, actual: <true>) fails.
-const_map4_test: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
 const_switch_test/02: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <0.0>) fails.
 const_switch_test/04: RuntimeError # Ints and doubles are unified.; Expect.equals(expected: <1>, actual: <1.0>) fails.
 constructor12_test: RuntimeError # Issue 29920; ReferenceError: JSArrayOfT is not defined
@@ -357,7 +355,6 @@
 library_env_test/has_io_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
 library_env_test/has_mirror_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
 library_env_test/has_no_html_support: RuntimeError, OK # Intended to fail, bool.fromEnvironment("dart.library.async") is false
-list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 local_function2_test/none: RuntimeError # ReferenceError: TToNull is not defined
 local_function3_test/none: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
 local_function_test/none: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 5953301..d17264f9 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -33,7 +33,6 @@
 config_import_test: RuntimeError
 const_list_test: RuntimeError
 const_locals_test: RuntimeError
-const_map4_test: RuntimeError
 const_nested_test: RuntimeError
 const_string_test: RuntimeError
 constructor12_test: RuntimeError
@@ -135,7 +134,6 @@
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
 
 [ $compiler == dartdevk ]
-mixin_method_override_test/G5: Skip # Issue 34354
 private_method_tearoff_test: RuntimeError
 
 [ $compiler == dartkp ]
@@ -236,7 +234,6 @@
 mixin_illegal_superclass_test/28: MissingCompileTimeError
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
 multiline_newline_test/04: MissingCompileTimeError
 multiline_newline_test/04r: MissingCompileTimeError
 multiline_newline_test/05: MissingCompileTimeError
@@ -275,21 +272,13 @@
 f_bounded_quantification4_test: CompileTimeError # Issue 34583
 issue31596_super_test/02: MissingCompileTimeError # Issue 31596
 issue31596_super_test/04: MissingCompileTimeError # Issue 31596
-issue34488_test/01: MissingCompileTimeError # Issue 34488
-issue34488_test/02: MissingCompileTimeError # Issue 34488
-issue34488_test/03: MissingCompileTimeError # Issue 34488
-issue34488_test/04: MissingCompileTimeError # Issue 34488
-issue34488_test/05: MissingCompileTimeError # Issue 34488
-issue34488_test/06: MissingCompileTimeError # Issue 34488
 mixin_declaration/mixin_declaration_invalid_override_test/08: MissingCompileTimeError
 mixin_declaration/mixin_declaration_superinvocation_application_test/04: MissingCompileTimeError
 mixin_declaration/mixin_declaration_superinvocation_application_test/05: MissingCompileTimeError
 mixin_declaration/mixin_declaration_superinvocation_application_test/06: MissingCompileTimeError
 mixin_declaration/mixin_declaration_superinvocation_application_test/07: MissingCompileTimeError
 mixin_declaration/mixin_declaration_superinvocation_application_test/08: MissingCompileTimeError
-mixin_method_override_test/G5: Crash # Issue 34354
 nnbd/*: Skip
-override_inheritance_field_test/42: MissingCompileTimeError
 regress_22976_test/*: CompileTimeError # Issue 31935
 set_literals/invalid_set_literal_test/08: MissingCompileTimeError # Requires constant evaluation
 set_literals/invalid_set_literal_test/09: MissingCompileTimeError # Requires constant evaluation
@@ -600,7 +589,6 @@
 config_import_test: RuntimeError # KernelVM bug: Configurable imports.
 const_evaluation_test: SkipByDesign
 const_list_test: RuntimeError
-const_map4_test: RuntimeError
 constructor12_test: RuntimeError
 constructor3_test: Fail, OK, Pass
 ct_const2_test: Skip # Incompatible flag: --compile_all
@@ -925,7 +913,6 @@
 const_dynamic_type_literal_test/02: RuntimeError # KernelVM bug: Constant map duplicated key.
 const_list_test: RuntimeError
 const_locals_test: RuntimeError
-const_map4_test: RuntimeError
 const_nested_test: RuntimeError # KernelVM bug: Constant evaluation.
 const_string_test: RuntimeError
 constructor12_test: RuntimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 7416230..4149ec3 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -18,15 +18,6 @@
 async_star/async_star_cancel_test: RuntimeError
 async_star/async_star_test: RuntimeError
 
-[ $compiler == precompiler && $runtime == dart_precompiled ]
-async_star/async_star_await_for_test: RuntimeError
-async_star/async_star_cancel_test: RuntimeError
-async_star/async_star_invalid_test/01: MissingCompileTimeError
-async_star/async_star_invalid_test/02: MissingCompileTimeError
-async_star/async_star_invalid_test/04: MissingCompileTimeError
-async_star/async_star_invalid_test/none: RuntimeError
-async_star/async_star_test: RuntimeError
-
 [ $runtime == dart_precompiled && $minified ]
 cyclic_type_test/*: Skip
 enum_duplicate_test/*: Skip # Uses Enum.toString()
diff --git a/tests/language_2/list_test.dart b/tests/language_2/list_test.dart
index 9108409..e5475c4 100644
--- a/tests/language_2/list_test.dart
+++ b/tests/language_2/list_test.dart
@@ -118,7 +118,7 @@
     Expect.equals(9, element);
 
     Expect.throws(() => new List(-1));
-    Expect.throws(() => new List(0x7fffffffffffffff));
+    Expect.throws(() => new List(0x7ffffffffffff000));
 
     List list = new List();
     Expect.throwsRangeError(list.removeLast);
diff --git a/tests/language_2/nested_generic_closure_test.dart b/tests/language_2/nested_generic_closure_test.dart
index 57a3f6d..1c5925c 100644
--- a/tests/language_2/nested_generic_closure_test.dart
+++ b/tests/language_2/nested_generic_closure_test.dart
@@ -2,7 +2,7 @@
 // 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.
 
-// VMOptions=--reify-generic-functions
+// TODO(37452): Avoid using unspecified 'toString' behaviour in language test.
 
 import 'package:expect/expect.dart';
 
@@ -25,11 +25,34 @@
 }
 
 main() {
-  Expect.equals("(<F>(F) => F) => void", foo.runtimeType.toString());
-  Expect.equals("<B>(<F>(F) => B) => B", bar.runtimeType.toString());
-  Expect.equals("<F>(F) => int", baz<int>().runtimeType.toString());
+  expectOne(
+    foo.runtimeType.toString(),
+    ["(<F>(F) => F) => void", "(<T1>(T1) => T1) => void"],
+  );
+  expectOne(
+    bar.runtimeType.toString(),
+    ["<B>(<F>(F) => B) => B", "<T1>(<T2>(T2) => T1) => T1"],
+  );
+  expectOne(
+    baz<int>().runtimeType.toString(),
+    ["<F>(F) => int", "<T1>(T1) => int"],
+  );
+
   var c = new C<bool>();
-  Expect.equals("(<F>(bool, F) => F) => void", c.foo.runtimeType.toString());
-  Expect.equals("<B>(<F>(bool, F) => B) => B", c.bar.runtimeType.toString());
-  Expect.equals("<F>(bool, F) => int", c.baz<int>().runtimeType.toString());
+  expectOne(
+    c.foo.runtimeType.toString(),
+    ["(<F>(bool, F) => F) => void", "(<T1>(bool, T1) => T1) => void"],
+  );
+  expectOne(
+    c.bar.runtimeType.toString(),
+    ["<B>(<F>(bool, F) => B) => B", "<T1>(<T2>(bool, T2) => T1) => T1"],
+  );
+  expectOne(
+    c.baz<int>().runtimeType.toString(),
+    ["<F>(bool, F) => int", "<T1>(bool, T1) => int"],
+  );
+}
+
+expectOne(String name, Iterable<String> names) {
+  Expect.isTrue(names.contains(name), '"$name" should be one of: ${names}');
 }
diff --git a/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart b/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
index 9757f79..2d6c7a6 100644
--- a/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
+++ b/tests/language_2/nnbd/static_errors/equals_parameter_made_nullable_at_invoke_test.dart
@@ -27,7 +27,7 @@
   // Caveat: it is NOT that the argument is promoted to non-null. Otherwise,
   // types which we can't cleanly promote, such as FutureOr<int?>, would not be
   // assignable in comparisons.
-  FutureOr<int?> foInt = Future.value(0);
+  FutureOr<int?> foInt;
 
   // Valid comparison.
   o == foInt;
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart
new file mode 100644
index 0000000..2043828
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_else_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v; //# none: compile-time error
+  if (b) {
+    // not assigned
+  } else {
+    v = 1;
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart
new file mode 100644
index 0000000..5eb19ce
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v;
+  if (b) {
+    v = 0;
+  } else {
+    v = 1;
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart
new file mode 100644
index 0000000..2b9496c
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_else_then_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v; //# none: compile-time error
+  if (b) {
+    v = 0;
+  } else {
+    // not assigned
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_test.dart
new file mode 100644
index 0000000..7c65fb5
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_if_then_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v; //# none: compile-time error
+  if (b) {
+    v = 0;
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
new file mode 100644
index 0000000..ba9f896
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_initializer_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+// This test check cases when the variable is only initialized (or not)
+// at its declaration, and there are no other assignments.
+
+void main() {
+  int v; v; //# 01: compile-time error
+  int v; //# 02: ok
+  int v = 0; v; //# 03: ok
+  late int v; v; //# 04: ok
+  late int v = 0; v; //# 05: ok
+  int? v; v; //# 06: ok
+  int? v = 0; v; //# 07: ok
+
+}
+
+f<T>(T a) {
+  T v; v; //# 08: compile-time error
+  T v; //# 09: ok
+  T v = a; v; //# 10: ok
+  late T v; v; //# 11: ok
+  late T v = a; v; //# 12: ok
+  T? v; v; //# 13: ok
+  T? v = a; v; //# 14: ok
+}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart
new file mode 100644
index 0000000..94968d3
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_catch_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+void main() {
+  int v;
+  try {
+    g();
+    v = 0;
+  } catch (_) {
+    v = 1;
+  }
+  v;
+}
+
+void g() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart
new file mode 100644
index 0000000..05a8676
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_try_catch_body_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+void main() {
+  int v; //# none: compile-time error
+  try {
+    g();
+    v = 0;
+  } catch (_) {
+    // not assigned
+  }
+  v;
+}
+
+void g() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_test.dart
new file mode 100644
index 0000000..8c9a408
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_after_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v;
+  while (true) {
+    v = 0;
+    if (b) break;
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_test.dart b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_test.dart
new file mode 100644
index 0000000..d0443ad
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_assigned_local_while_true_break_before_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// It is an error if a potentially non-nullable local variable which has no
+// initializer expression and is not marked `late` is used before it is
+// definitely assigned.
+
+f(bool b) {
+  int v; //# none: compile-time error
+  while (true) {
+    if (b) break;
+    v = 0;
+  }
+  v;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_test.dart
new file mode 100644
index 0000000..a70142e
--- /dev/null
+++ b/tests/language_2/nnbd/static_errors/not_initialized_non_nullable_static_field_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+// Test that it is an error if a static field non-nullable type has no
+// initializer expression.
+void main() {}
+
+class A {
+  static int v; //# 01: compile-time error
+  static int v = 0; //# 02: ok
+  static int? v; //# 03: ok
+  static int? v = 0; //# 04: ok
+  static dynamic v; //# 05: ok
+  static var v; //# 06: ok
+  static void v; //# 07: ok
+  static Never v; //# 08: compile-time error
+}
diff --git a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart b/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
deleted file mode 100644
index d4b2207..0000000
--- a/tests/language_2/nnbd/static_errors/not_initialized_potentially_non_nullable_local_test.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2019, 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.
-
-// SharedOptions=--enable-experiment=non-nullable
-
-// It is an error if a potentially non-nullable local variable which has no
-// initializer expression and is not marked `late` is used before it is
-// definitely assigned.
-// TODO(scheglov) Update once we implement definite assignment analysis.
-
-void main() {
-  int v; //# 01: compile-time error
-  int v = 0; //# 02: ok
-  late int v; //# 03: ok
-  late int v = 0; //# 04: ok
-  int? v; //# 05: ok
-  int? v = 0; //# 06: ok
-
-}
-
-f<T>(T a) {
-  T v; //# 07: compile-time error
-  T v = a; //# 08: ok
-  late T v; //# 09: ok
-  late T v = a; //# 10: ok
-  T? v; //# 11: ok
-  T? v = a; //# 12: ok
-}
diff --git a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
index b8265e3..059b2d5 100644
--- a/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
+++ b/tests/language_2/nnbd/syntax/required_modifier_error_test.dart
@@ -29,12 +29,9 @@
 // Out of order modifiers
 class C2 {
   void m({
-    covariant
-    required //# 07: compile-time error
-    int i2,
-    final
-    required //# 08: compile-time error
-    int i3,
+    required int i1,
+    covariant required int i2, //# 07: compile-time error
+    final required int i3, //# 08: compile-time error
   }) {
   }
 }
diff --git a/tests/language_2/nnbd/type_promotion/assignment_test.dart b/tests/language_2/nnbd/type_promotion/assignment_test.dart
new file mode 100644
index 0000000..ab93abb
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/assignment_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is String) {
+    x = 42;
+    x.length; //# none: compile-time error
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/conditional_both_test.dart b/tests/language_2/nnbd/type_promotion/conditional_both_test.dart
new file mode 100644
index 0000000..a663af58
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/conditional_both_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+  b ? ((x is String) || (throw 1)) : ((x is String) || (throw 2));
+  x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart b/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart
new file mode 100644
index 0000000..c5b7420
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_condition_is_not_type_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  do {
+    x.length; //# 01: compile-time error
+  } while (x is! String);
+  x.length; //# 02: ok
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart b/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart
new file mode 100644
index 0000000..83572cd
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_condition_is_type_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  do {
+    x.length; //# 01: compile-time error
+  } while (x is String);
+  x.length; //# 02: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart
new file mode 100644
index 0000000..06f0653
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/do_outer_is_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x.length;
+    } while (b);
+    x.length;
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart
new file mode 100644
index 0000000..3aaed04
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/for_outer_is_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b;) {
+      x.length;
+    }
+    x.length;
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
new file mode 100644
index 0000000..5f67881
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_is_type_mutated_in_closure_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      x.length; //# none: compile-time error
+    }
+
+    void h() {
+      x = 42;
+    }
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart
new file mode 100644
index 0000000..83200a7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_is_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      x.length;
+    }
+    x = 42;
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart b/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
new file mode 100644
index 0000000..a9a546f
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/function_expression_outer_is_type_assigned_outside_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  void Function() g;
+
+  if (x is String) {
+    x.length;
+
+    g = () {
+      x.length; //# 01: compile-time error
+    };
+  }
+
+  x = 42;
+  x.length; //# 02: compile-time error
+  g();
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart b/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart
new file mode 100644
index 0000000..4fb31b7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/if_is_not_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is! String) {
+    x.length; //# 01: compile-time error
+  } else {
+    x.length; //# 02: ok
+  }
+  x.length; //# 03: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/if_is_type_test.dart b/tests/language_2/nnbd/type_promotion/if_is_type_test.dart
new file mode 100644
index 0000000..dc97344
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/if_is_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is String) {
+    x.length; //# 01: ok
+  } else {
+    x.length; //# 02: compile-time error
+  }
+  x.length; //# 03: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/logical_or_throw_test.dart b/tests/language_2/nnbd/type_promotion/logical_or_throw_test.dart
new file mode 100644
index 0000000..e8c7e8b
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/logical_or_throw_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  x is String || (throw 42);
+  x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart
new file mode 100644
index 0000000..4a3bef4
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_assigned_body_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is! String) return;
+  x.length;
+  try {
+    x = 42;
+    g(); // might throw
+    if (x is! String) return;
+    x.length;
+  } catch (_) {}
+  x.length; //# 01: compile-time error
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_test.dart
new file mode 100644
index 0000000..41449de
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_catch_finally_outer_is_type_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is String) {
+    try {
+      x.length;
+    } catch (_) {
+      x.length;
+    } finally {
+      x.length;
+    }
+    x.length;
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_test.dart
new file mode 100644
index 0000000..9b2462c
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_catch_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    x.length;
+  } catch (_) {
+    if (x is! String) return;
+    x.length;
+  }
+  x.length;
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.dart b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.dart
new file mode 100644
index 0000000..3d8ca81
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_catch_is_not_type_exit_body_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    x.length;
+  } catch (_) {}
+  x.length; //# 01: compile-time error
+}
+
+void g() {}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_test.dart b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_test.dart
new file mode 100644
index 0000000..eeabbe7
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_body_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is String) {
+    try {
+      x.length;
+      x = 42;
+    } finally {
+      x.length; //# 01: compile-time error
+    }
+    x.length; //# 02: compile-time error
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_test.dart b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_test.dart
new file mode 100644
index 0000000..bca9b42
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/try_finally_outer_is_type_assigned_finally_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  if (x is String) {
+    try {
+      x.length;
+    } finally {
+      x.length;
+      x = 42;
+    }
+    x.length; //# 01: compile-time error
+  }
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart b/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart
new file mode 100644
index 0000000..8301ac9
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/while_condition_false_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  while (x is! String) {
+    x.length; //# 01: compile-time error
+  }
+  x.length;
+}
+
+void main() {}
diff --git a/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart b/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart
new file mode 100644
index 0000000..468b14e
--- /dev/null
+++ b/tests/language_2/nnbd/type_promotion/while_condition_true_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=non-nullable
+
+void f(Object x) {
+  while (x is String) {
+    x.length;
+  }
+  x.length; //# 01: compile-time error
+}
+
+void main() {}
diff --git a/tests/language_2/truncdiv_test.dart b/tests/language_2/truncdiv_test.dart
index f6b0cc3..bd043d1 100644
--- a/tests/language_2/truncdiv_test.dart
+++ b/tests/language_2/truncdiv_test.dart
@@ -16,8 +16,11 @@
       Expect.equals(i ~/ i, foo2(i));
     }
   }
-  Expect.throws(() => foo(12, 0), (e) => e is IntegerDivisionByZeroException);
-  Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
+  // We don't specify the exact exception type here, that is covered in
+  // truncdiv_zero_test. The correct answer is IntegerDivisionByZeroException,
+  // but the web platform has only one num type and can't distinguish between
+  // int and double, so it throws UnsupportedError (the behaviour for double).
+  Expect.throws(() => foo2(0));
 }
 
 foo(i, x) => i % x;
diff --git a/tests/language_2/truncdiv_zero_test.dart b/tests/language_2/truncdiv_zero_test.dart
new file mode 100644
index 0000000..34cecc3
--- /dev/null
+++ b/tests/language_2/truncdiv_zero_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, 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.
+// Dart test optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+import "truncdiv_test.dart" as truncdiv_test show foo, foo2;
+
+main() {
+  Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo(12, 0));
+  Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo2(0));
+}
diff --git a/tests/language_2/type_literal_canonicalization_test.dart b/tests/language_2/type_literal_canonicalization_test.dart
new file mode 100644
index 0000000..790f1b6
--- /dev/null
+++ b/tests/language_2/type_literal_canonicalization_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2019, 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";
+
+class Foo {}
+
+class Box<T> {
+  Type get typeArg => T;
+}
+
+/// A typedef that defines a non-generic function type.
+typedef int Func1(bool b);
+
+/// Semantically identical to [Func], but using the Dart 2 syntax.
+typedef Func2 = int Function(bool);
+
+main() {
+  // Literals are canonicalized.
+  Expect.identical(Foo, Foo);
+  Expect.identical(Box, Box);
+  Expect.identical(new Box<Foo>().typeArg, new Box<Foo>().typeArg);
+  Expect.identical(Func1, Func1);
+  Expect.identical(Func2, Func2);
+}
diff --git a/tests/language_2/type_literal_test.dart b/tests/language_2/type_literal_test.dart
index c21c95a..6eee895 100644
--- a/tests/language_2/type_literal_test.dart
+++ b/tests/language_2/type_literal_test.dart
@@ -69,18 +69,16 @@
       ["GenericTypedef2", "GenericTypedef2<dynamic>", "(dynamic) => int"]);
   testType(new Box<GenericTypedef<int>>().typeArg,
       ["GenericTypedef<int>", "(int) => int"]);
-  testType(GenericFunc, ["GenericFunc", "<T>(T) => int"]);
+  testType(GenericFunc, ["GenericFunc", "<T>(T) => int", "<T1>(T1) => int"]);
   testType(GenericTypedefAndFunc, [
     "GenericTypedefAndFunc",
     "GenericTypedefAndFunc<dynamic>",
-    "<T>(T) => dynamic"
+    "<T>(T) => dynamic",
+    "<T1>(T1) => dynamic",
   ]);
 
   // Literals are canonicalized.
-  Expect.identical(Foo, Foo);
-  Expect.identical(Box, Box);
-  Expect.identical(new Box<Foo>().typeArg, new Box<Foo>().typeArg);
-  Expect.identical(Func, Func);
+  // See type_literal_canonicalization_test.dart
 
   // Static member uses are not type literals.
   Foo.property = "value";
@@ -97,13 +95,18 @@
 }
 
 void testType(Type type, Object expectedToStringValues) {
+  Expect.isTrue(type is Type);
+  String text = type.toString();
+
+  // dart2js minified names should be tagged. We can still test types that don't
+  // contain minified names.
+  if (text.contains('minified:')) return;
+
   if (expectedToStringValues is List) {
-    var s = type.toString();
-    Expect.isTrue(expectedToStringValues.contains(s),
+    Expect.isTrue(expectedToStringValues.contains(text),
         'type `$type`.toString() should be one of: $expectedToStringValues.');
   } else {
     var string = expectedToStringValues as String;
-    Expect.equals(string, type.toString());
+    Expect.equals(string, text);
   }
-  Expect.isTrue(type is Type);
 }
diff --git a/tests/language_2/vm/reflect_core_vm_test.dart b/tests/language_2/vm/reflect_core_vm_test.dart
index e13f36e..75fff71 100644
--- a/tests/language_2/vm/reflect_core_vm_test.dart
+++ b/tests/language_2/vm/reflect_core_vm_test.dart
@@ -10,6 +10,6 @@
 main() {
   var s = "string";
   var im = reflect(s);
-  Expect.throwsNoSuchMethodError(
-      () => im.invoke(const Symbol("_setAt"), [0, 65]));
+  Expect.throwsNoSuchMethodError(() =>
+      im.invoke(MirrorSystem.getSymbol("_setAt", im.type.owner), [0, 65]));
 }
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 1e56403..666063e 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -16,42 +16,6 @@
 [ $runtime == chrome ]
 html/element_animate_test/timing_dict: RuntimeError # Issue 26730
 
-[ $runtime == dart_precompiled ]
-isolate/count_test: Skip # Isolate.spawnUri
-isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
-isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
-isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_6610_test: Skip # Isolate.spawnUri
-isolate/mandel_isolate_test: Skip # Isolate.spawnUri
-isolate/message2_test: Skip # Isolate.spawnUri
-isolate/message_test: Skip # Isolate.spawnUri
-isolate/mint_maker_test: Skip # Isolate.spawnUri
-isolate/nested_spawn2_test: Skip # Isolate.spawnUri
-isolate/nested_spawn_test: Skip # Isolate.spawnUri
-isolate/raw_port_test: Skip # Isolate.spawnUri
-isolate/request_reply_test: Skip # Isolate.spawnUri
-isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
-isolate/spawn_function_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
-isolate/stacktrace_message_test: Skip # Isolate.spawnUri
-isolate/static_function_test: Skip # Isolate.spawnUri
-isolate/unresolved_ports_test: Skip # Isolate.spawnUri
-
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Pass, Slow # Issue 12029
 mirrors/mirrors_reader_test: Timeout, Slow, RuntimeError # Issue 16589
@@ -184,21 +148,18 @@
 html/request_animation_frame_test: Skip # Times out. Issue 22167
 html/transition_event_test: Skip # Times out. Issue 22167
 
+[ $runtime != dart_precompiled && ($runtime != vm || $compiler != dartk && $compiler != none) ]
+isolate/vm_rehash_test: SkipByDesign
+
 [ !$preview_dart_2 && ($runtime == dart_precompiled || $runtime == vm) ]
 *: SkipByDesign # Deprecating all Dart1 modes of execution
 
-[ ($compiler != precompiler || $runtime != dart_precompiled) && ($runtime != vm || $compiler != dartk && $compiler != none) ]
-isolate/vm_rehash_test: SkipByDesign
-
 [ $arch == simarm || $arch == simarmv5te || $arch == simarmv6 ]
 convert/utf85_test: Skip # Pass, Slow Issue 12644.
 
 [ $arch != x64 || $compiler == dartkb || $runtime != vm ]
 isolate/int32_length_overflow_test: SkipSlow
 
-[ $compiler == app_jit || $mode == product || $runtime != vm ]
-isolate/checked_test: Skip # Unsupported.
-
 [ $compiler != none || $runtime != vm ]
 isolate/package_config_test: SkipByDesign # Uses Isolate.packageConfig
 isolate/package_resolve_test: SkipByDesign # Uses Isolate.resolvePackageUri
@@ -206,6 +167,9 @@
 isolate/scenarios/*: SkipByDesign # Use automatic package resolution, spawnFunction and .dart URIs.
 isolate/spawn_uri_fail_test: SkipByDesign # Uses dart:io.
 
+[ $mode == product || $runtime != vm ]
+isolate/checked_test: Skip # Unsupported.
+
 [ $runtime == chrome || $runtime == chromeOnAndroid ]
 html/webgl_1_test: Pass, Fail # Issue 8219
 
@@ -217,6 +181,46 @@
 isolate/isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to pass when we have wrapper-less tests.
 isolate/stacktrace_message_test: RuntimeError # Fails to send stacktrace object.
 
+# It makes no sense to run any test that uses spawnURI under the simulator
+# as that would involve running CFE (the front end) in simulator mode
+# to compile the URI file specified in spawnURI code.
+# These Isolate tests that use spawnURI are hence skipped on purpose.
+[ $runtime == dart_precompiled || $runtime == vm && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
+isolate/count_test: Skip # Isolate.spawnUri
+isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
+isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
+isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_6610_test: Skip # Isolate.spawnUri
+isolate/mandel_isolate_test: Skip # Isolate.spawnUri
+isolate/message2_test: Skip # Isolate.spawnUri
+isolate/message_test: Skip # Isolate.spawnUri
+isolate/mint_maker_test: Skip # Isolate.spawnUri
+isolate/nested_spawn2_test: Skip # Isolate.spawnUri
+isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/raw_port_test: Skip # Isolate.spawnUri
+isolate/request_reply_test: Skip # Isolate.spawnUri
+isolate/spawn_function_custom_class_test: Skip # Isolate.spawnUri
+isolate/spawn_function_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_exported_main_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
+isolate/stacktrace_message_test: Skip # Isolate.spawnUri
+isolate/static_function_test: Skip # Isolate.spawnUri
+isolate/unresolved_ports_test: Skip # Isolate.spawnUri
+
 [ $hot_reload || $hot_reload_rollback ]
 async/stream_transformer_test: Pass, Fail # Closure identity
 convert/chunked_conversion_utf88_test: SkipSlow
diff --git a/tests/lib_2/lib_2_app_jit.status b/tests/lib_2/lib_2_app_jit.status
index d219200..cb39a57 100644
--- a/tests/lib_2/lib_2_app_jit.status
+++ b/tests/lib_2/lib_2_app_jit.status
@@ -2,5 +2,5 @@
 # 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.
 
-[ $compiler == app_jit || $compiler == app_jitk ]
+[ $compiler == app_jitk ]
 mirrors/*: Skip # Issue 27929: Triage
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index 368c7ba..dd4bbaa 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -82,7 +82,6 @@
 js/null_test: RuntimeError # Issue 30652
 math/double_pow_test: RuntimeError # Issue 29922
 math/double_pow_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-math/low_test: RuntimeError # Issue 29922
 math/random_big_test: RuntimeError # Issue 29922
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
 mirrors/private_types_test: RuntimeError # Issue 29922
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index c52f96f..2c6f12b 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -48,15 +48,9 @@
 mirrors/redirecting_factory_test/01: CompileTimeError # Issue 34714
 mirrors/redirecting_factory_test/none: CompileTimeError # Issue 34714
 
-[ $arch == simdbc64 && $mode == debug && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-isolate/isolate_complex_messages_test: Crash # http://dartbug.com/33128
-
 [ $arch == simdbc64 && $hot_reload_rollback ]
 convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Uses --verify_before_gc --verify_after_gc --old_gen_growth_rate=1 flags
 
-[ $arch == simdbc64 && ($compiler == dartk || $compiler == dartkb) ]
-isolate/issue_24243_parent_isolate_test: RuntimeError # dartbug.com/35373
-
 [ $arch == x64 && $builder_tag == asan && $compiler == dartk ]
 mirrors/dynamic_load_test: Fail # Memory leak (issue 34724)
 
@@ -207,8 +201,6 @@
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
 [ ($arch == simarm || $arch == simarm64 || $arch == simdbc64) && ($compiler == dartk || $compiler == dartkb) ]
-isolate/mandel_isolate_test: Pass, Timeout
-isolate/nested_spawn2_test: Pass, RuntimeError # RuntimeError caused by timeout
 mirrors/library_uri_io_test: RuntimeError # Please triage.
 
 [ ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
diff --git a/tests/lib_2/lib_2_precompiled.status b/tests/lib_2/lib_2_precompiled.status
index 9a1e896..d93502d 100644
--- a/tests/lib_2/lib_2_precompiled.status
+++ b/tests/lib_2/lib_2_precompiled.status
@@ -2,35 +2,7 @@
 # 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.
 
-[ $compiler == precompiler ]
-async/async_no_await_zones_test: RuntimeError # Issue 33700
-convert/chunked_conversion_utf88_test: Pass, Timeout
-convert/utf85_test: Pass, Timeout
-html/*: SkipByDesign # dart:html not supported on AOT.
-isolate/count_test: SkipByDesign
-isolate/cross_isolate_message_test: SkipByDesign
-isolate/illegal_msg_function_test: SkipByDesign
-isolate/illegal_msg_mirror_test: SkipByDesign
-isolate/isolate_complex_messages_test: SkipByDesign
-isolate/mandel_isolate_test: SkipByDesign
-isolate/message2_test: SkipByDesign
-isolate/message_test: SkipByDesign
-isolate/mint_maker_test: SkipByDesign
-isolate/nested_spawn2_test: SkipByDesign
-isolate/nested_spawn_test: SkipByDesign
-isolate/raw_port_test: SkipByDesign
-isolate/request_reply_test: SkipByDesign
-isolate/spawn_function_custom_class_test: SkipByDesign
-isolate/spawn_function_test: SkipByDesign
-isolate/stacktrace_message_test: SkipByDesign
-isolate/static_function_test: SkipByDesign
-isolate/unresolved_ports_test: SkipByDesign
-js/datetime_roundtrip_test: CompileTimeError
-js/null_test: CompileTimeError
-js/prototype_access_test: CompileTimeError
-mirrors/*: SkipByDesign # Mirrors not supported on AOT.
-
-[ $compiler == app_jit || $compiler == none || $compiler == precompiler ]
+[ $compiler == none ]
 async/future_or_strong_test: RuntimeError
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
 isolate/compile_time_error_test/01: Skip # Issue 12587
diff --git a/tests/lib_2/math/low_test.dart b/tests/lib_2/math/low_test.dart
index 6014ef5..f7e9060 100644
--- a/tests/lib_2/math/low_test.dart
+++ b/tests/lib_2/math/low_test.dart
@@ -9,7 +9,7 @@
 import 'dart:math';
 
 void main() {
-  var n = (2 * (1 << 32)) ~/ 3;
+  var n = (2 * 0x100000000) ~/ 3;
   var n2 = n ~/ 2;
 
   var iterations = 200000;
diff --git a/tests/standalone_2/causal_async_stack_test.dart b/tests/standalone_2/causal_async_stack_test.dart
index faebf3e..eab14af 100644
--- a/tests/standalone_2/causal_async_stack_test.dart
+++ b/tests/standalone_2/causal_async_stack_test.dart
@@ -5,7 +5,12 @@
 
 import "package:expect/expect.dart";
 
+noop() async => Future.value(null);
+
 baz() async {
+  // Throw exception after the first continuation, when there is no
+  // original stack trace.
+  await noop();
   throw "Bad!";
 }
 
diff --git a/tests/standalone_2/http_launch_test.dart b/tests/standalone_2/http_launch_test.dart
index cb97f84..59f93c5 100644
--- a/tests/standalone_2/http_launch_test.dart
+++ b/tests/standalone_2/http_launch_test.dart
@@ -41,7 +41,7 @@
   final File file = new File(requestPath.toFilePath());
   file.exists().then((bool found) {
     if (found) {
-      file.openRead().pipe(request.response).catchError((e) {
+      file.openRead().cast<List<int>>().pipe(request.response).catchError((e) {
         _sendNotFound(request.response);
       });
     } else {
diff --git a/tests/standalone_2/io/file_input_stream_test.dart b/tests/standalone_2/io/file_input_stream_test.dart
index 4d48549..68c272d 100644
--- a/tests/standalone_2/io/file_input_stream_test.dart
+++ b/tests/standalone_2/io/file_input_stream_test.dart
@@ -22,8 +22,11 @@
   // File contains "Hello Dart\nwassup!\n"
   File file = new File(fileName);
   int linesRead = 0;
-  var lineStream =
-      file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+  var lineStream = file
+      .openRead()
+      .cast<List<int>>()
+      .transform(utf8.decoder)
+      .transform(new LineSplitter());
   lineStream.listen((line) {
     linesRead++;
     if (linesRead == 1) {
@@ -213,8 +216,11 @@
   // File contains 10 lines.
   File file = new File(fileName);
   Expect.equals(length, file.lengthSync());
-  var lineStream =
-      file.openRead().transform(utf8.decoder).transform(new LineSplitter());
+  var lineStream = file
+      .openRead()
+      .cast<List<int>>()
+      .transform(utf8.decoder)
+      .transform(new LineSplitter());
   int lineCount = 0;
   lineStream.listen((line) {
     lineCount++;
diff --git a/tests/standalone_2/io/file_stream_test.dart b/tests/standalone_2/io/file_stream_test.dart
index f5e5503..2d3577e 100644
--- a/tests/standalone_2/io/file_stream_test.dart
+++ b/tests/standalone_2/io/file_stream_test.dart
@@ -12,7 +12,11 @@
   asyncStart();
   Directory.systemTemp.createTemp('dart_file_stream').then((d) {
     var file = new File("${d.path}/file");
-    new File(Platform.executable).openRead().pipe(file.openWrite()).then((_) {
+    new File(Platform.executable)
+        .openRead()
+        .cast<List<int>>()
+        .pipe(file.openWrite())
+        .then((_) {
       var subscription;
       subscription = file.openRead().listen((data) {
         subscription.pause();
@@ -39,7 +43,11 @@
   asyncStart();
   Directory.systemTemp.createTemp('dart_file_stream').then((d) {
     var file = new File("${d.path}/file");
-    new File(Platform.executable).openRead().pipe(file.openWrite()).then((_) {
+    new File(Platform.executable)
+        .openRead()
+        .cast<List<int>>()
+        .pipe(file.openWrite())
+        .then((_) {
       // isEmpty will cancel the stream after first data event.
       file.openRead().isEmpty.then((empty) {
         Expect.isFalse(empty);
diff --git a/tests/standalone_2/io/file_test.dart b/tests/standalone_2/io/file_test.dart
index 74f57f7..8f18060 100644
--- a/tests/standalone_2/io/file_test.dart
+++ b/tests/standalone_2/io/file_test.dart
@@ -209,7 +209,7 @@
     var input = file.openRead();
     var output = outputFile.openWrite();
     Completer done = new Completer();
-    input.pipe(output).then((_) {
+    input.cast<List<int>>().pipe(output).then((_) {
       var copy = outputFile.openRead();
       int position = 0;
       copy.listen((d) {
diff --git a/tests/standalone_2/io/http_basic_test.dart b/tests/standalone_2/io/http_basic_test.dart
index 573e005..4f389ce 100644
--- a/tests/standalone_2/io/http_basic_test.dart
+++ b/tests/standalone_2/io/http_basic_test.dart
@@ -104,7 +104,7 @@
     var response = request.response;
     Expect.equals("POST", request.method);
     response.contentLength = request.contentLength;
-    request.pipe(response);
+    request.cast<List<int>>().pipe(response);
   }
 
   // Echo the request content back to the response.
diff --git a/tests/standalone_2/io/http_client_connect_test.dart b/tests/standalone_2/io/http_client_connect_test.dart
index 9c7cb67..284c441d 100644
--- a/tests/standalone_2/io/http_client_connect_test.dart
+++ b/tests/standalone_2/io/http_client_connect_test.dart
@@ -17,7 +17,7 @@
 void testGetEmptyRequest() {
   HttpServer.bind("127.0.0.1", 0).then((server) {
     server.listen((request) {
-      request.pipe(request.response);
+      request.cast<List<int>>().pipe(request.response);
     });
 
     var client = new HttpClient();
@@ -35,7 +35,7 @@
     var data = "lalala".codeUnits;
     server.listen((request) {
       request.response.add(data);
-      request.pipe(request.response);
+      request.cast<List<int>>().pipe(request.response);
     });
 
     var client = new HttpClient();
@@ -163,7 +163,7 @@
     HttpServer.bind("127.0.0.1", 0).then((server) {
       server.listen((request) {
         Expect.equals(method[1], request.method);
-        request.pipe(request.response);
+        request.cast<List<int>>().pipe(request.response);
       });
 
       Callback1 cb = method[0] as Callback1;
@@ -192,7 +192,7 @@
     HttpServer.bind("127.0.0.1", 0).then((server) {
       server.listen((request) {
         Expect.equals(method[1], request.method);
-        request.pipe(request.response);
+        request.cast<List<int>>().pipe(request.response);
       });
 
       Callback2 cb = method[0] as Callback2;
@@ -220,8 +220,10 @@
         .get("127.0.0.1", server.port, "/")
         .then((request) => request.close())
         .then((clientResponse) {
-      var iterator = new StreamIterator(
-          clientResponse.transform(utf8.decoder).transform(new LineSplitter()));
+      var iterator = new StreamIterator(clientResponse
+          .cast<List<int>>()
+          .transform(utf8.decoder)
+          .transform(new LineSplitter()));
       iterator.moveNext().then((hasValue) {
         Expect.isTrue(hasValue);
         Expect.equals('init', iterator.current);
diff --git a/tests/standalone_2/io/http_cross_process_test.dart b/tests/standalone_2/io/http_cross_process_test.dart
index 547cb92..598ac68 100644
--- a/tests/standalone_2/io/http_cross_process_test.dart
+++ b/tests/standalone_2/io/http_cross_process_test.dart
@@ -27,15 +27,14 @@
 Future makeServer() {
   return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) {
     server.listen((request) {
-      request.pipe(request.response);
+      request.cast<List<int>>().pipe(request.response);
     });
     return server;
   });
 }
 
 Future runClientProcess(int port) {
-  return Process
-      .run(
+  return Process.run(
           Platform.executable,
           []
             ..addAll(Platform.executableArguments)
diff --git a/tests/standalone_2/io/http_proxy_advanced_test.dart b/tests/standalone_2/io/http_proxy_advanced_test.dart
index c6d0af2..5f8758b 100644
--- a/tests/standalone_2/io/http_proxy_advanced_test.dart
+++ b/tests/standalone_2/io/http_proxy_advanced_test.dart
@@ -35,8 +35,9 @@
 
   Future<Server> start() {
     return (secure
-        ? HttpServer.bindSecure("localhost", 0, serverContext)
-        : HttpServer.bind("localhost", 0)).then((s) {
+            ? HttpServer.bindSecure("localhost", 0, serverContext)
+            : HttpServer.bind("localhost", 0))
+        .then((s) {
       server = s;
       server.listen(requestHandler);
       return this;
@@ -256,9 +257,11 @@
             clientRequest.headers
                 .add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
             // Copy all content.
-            return request.pipe(clientRequest);
+            return request.cast<List<int>>().pipe(clientRequest);
           }).then((clientResponse) {
-            (clientResponse as HttpClientResponse).pipe(request.response);
+            (clientResponse as HttpClientResponse)
+                .cast<List<int>>()
+                .pipe(request.response);
           });
         }
       });
diff --git a/tests/standalone_2/io/http_proxy_test.dart b/tests/standalone_2/io/http_proxy_test.dart
index 885af5d..b153ead 100644
--- a/tests/standalone_2/io/http_proxy_test.dart
+++ b/tests/standalone_2/io/http_proxy_test.dart
@@ -34,8 +34,9 @@
 
   Future<Server> start() {
     return (secure
-        ? HttpServer.bindSecure("localhost", 0, serverContext)
-        : HttpServer.bind("localhost", 0)).then((s) {
+            ? HttpServer.bindSecure("localhost", 0, serverContext)
+            : HttpServer.bind("localhost", 0))
+        .then((s) {
       server = s;
       server.listen(requestHandler);
       return this;
@@ -244,9 +245,11 @@
             clientRequest.headers
                 .add(HttpHeaders.viaHeader, "${viaPrefix}1.1 localhost:$port");
             // Copy all content.
-            return request.pipe(clientRequest);
+            return request.cast<List<int>>().pipe(clientRequest);
           }).then((clientResponse) {
-            (clientResponse as HttpClientResponse).pipe(request.response);
+            (clientResponse as HttpClientResponse)
+                .cast<List<int>>()
+                .pipe(request.response);
           });
         }
       });
diff --git a/tests/standalone_2/io/http_read_test.dart b/tests/standalone_2/io/http_read_test.dart
index aeb2174..5d32b15c 100644
--- a/tests/standalone_2/io/http_read_test.dart
+++ b/tests/standalone_2/io/http_read_test.dart
@@ -107,7 +107,7 @@
     var response = request.response;
     Expect.equals("POST", request.method);
     response.contentLength = request.contentLength;
-    request.pipe(response);
+    request.cast<List<int>>().pipe(response);
   }
 
   // Return a 404.
diff --git a/tests/standalone_2/io/http_reuse_server_port_test.dart b/tests/standalone_2/io/http_reuse_server_port_test.dart
index da90fe7..afcaf61 100644
--- a/tests/standalone_2/io/http_reuse_server_port_test.dart
+++ b/tests/standalone_2/io/http_reuse_server_port_test.dart
@@ -18,7 +18,7 @@
   HttpServer.bind("127.0.0.1", port).then((server) {
     int i = 0;
     server.listen((request) {
-      request.pipe(request.response);
+      request.cast<List<int>>().pipe(request.response);
       i++;
       if (!clean && i == 10) {
         int port = server.port;
diff --git a/tests/standalone_2/io/http_server_early_client_close2_test.dart b/tests/standalone_2/io/http_server_early_client_close2_test.dart
index 80bc51c..1a84dfd 100644
--- a/tests/standalone_2/io/http_server_early_client_close2_test.dart
+++ b/tests/standalone_2/io/http_server_early_client_close2_test.dart
@@ -18,6 +18,7 @@
       String name = Platform.script.toFilePath();
       new File(name)
           .openRead()
+          .cast<List<int>>()
           .pipe(request.response)
           .catchError((e) {/* ignore */});
     });
diff --git a/tests/standalone_2/io/http_server_early_client_close_test.dart b/tests/standalone_2/io/http_server_early_client_close_test.dart
index 4cacde0..59841f0 100644
--- a/tests/standalone_2/io/http_server_early_client_close_test.dart
+++ b/tests/standalone_2/io/http_server_early_client_close_test.dart
@@ -111,6 +111,7 @@
       String name = Platform.script.toFilePath();
       new File(name)
           .openRead()
+          .cast<List<int>>()
           .pipe(request.response)
           .catchError((e) {/* ignore */});
     });
diff --git a/tests/standalone_2/io/http_server_response_test.dart b/tests/standalone_2/io/http_server_response_test.dart
index baa729b..2f2e657 100644
--- a/tests/standalone_2/io/http_server_response_test.dart
+++ b/tests/standalone_2/io/http_server_response_test.dart
@@ -67,6 +67,7 @@
   testServerRequest((server, request) {
     new File("__nonexistent_file_")
         .openRead()
+        .cast<List<int>>()
         .pipe(request.response)
         .catchError((e) {
       server.close();
@@ -122,6 +123,7 @@
   testServerRequest((server, request) {
     new File("__nonexistent_file_")
         .openRead()
+        .cast<List<int>>()
         .pipe(request.response)
         .catchError((e) {
       server.close();
diff --git a/tests/standalone_2/io/https_server_test.dart b/tests/standalone_2/io/https_server_test.dart
index ad3cc51..fe151bc 100644
--- a/tests/standalone_2/io/https_server_test.dart
+++ b/tests/standalone_2/io/https_server_test.dart
@@ -69,6 +69,7 @@
       String name = Platform.script.toFilePath();
       new File(name)
           .openRead()
+          .cast<List<int>>()
           .pipe(request.response)
           .catchError((e) {/* ignore */});
     });
diff --git a/tests/standalone_2/io/pipe_server_test.dart b/tests/standalone_2/io/pipe_server_test.dart
index a9a3975..0b30e2e 100644
--- a/tests/standalone_2/io/pipe_server_test.dart
+++ b/tests/standalone_2/io/pipe_server_test.dart
@@ -45,7 +45,7 @@
     void connectHandler() {
       String srcFileName = getDataFilename("readline_test1.dat");
       Stream fileInput = new File(srcFileName).openRead();
-      fileInput.pipe(_socket).then((_) {
+      fileInput.cast<List<int>>().pipe(_socket).then((_) {
         var tempDir = Directory.systemTemp.createTempSync('dart_pipe_server');
         var dstFileName = tempDir.path + "/readline_test1.dat";
         var dstFile = new File(dstFileName);
diff --git a/tests/standalone_2/io/platform_resolved_executable_test.dart b/tests/standalone_2/io/platform_resolved_executable_test.dart
index 14be3b5..c6da572 100644
--- a/tests/standalone_2/io/platform_resolved_executable_test.dart
+++ b/tests/standalone_2/io/platform_resolved_executable_test.dart
@@ -23,7 +23,8 @@
     env['PATH'] = altPath;
   }
 
-  var processResult = Process.runSync(exePath, [scriptPath],
+  var processResult = Process.runSync(
+      exePath, [...Platform.executableArguments, scriptPath],
       includeParentEnvironment: false, runInShell: true, environment: env);
 
   if (processResult.exitCode != 0) {
diff --git a/tests/standalone_2/io/stream_pipe_test.dart b/tests/standalone_2/io/stream_pipe_test.dart
index 9f4067c..de11c0a 100644
--- a/tests/standalone_2/io/stream_pipe_test.dart
+++ b/tests/standalone_2/io/stream_pipe_test.dart
@@ -67,7 +67,7 @@
   String dstFileName = tempDir.path + "/readline_test1.dat";
   new File(dstFileName).createSync();
   var output = new File(dstFileName).openWrite();
-  srcStream.pipe(output).then((_) {
+  srcStream.cast<List<int>>().pipe(output).then((_) {
     bool result = compareFileContent(srcFileName, dstFileName);
     new File(dstFileName).deleteSync();
     tempDir.deleteSync();
@@ -92,7 +92,7 @@
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.addStream(srcStream).then((_) {
+  output.addStream(srcStream.cast<List<int>>()).then((_) {
     output.add([32]);
     output.close();
     output.done.then((_) {
@@ -131,9 +131,9 @@
   var dstFile = new File(dstFileName);
   dstFile.createSync();
   var output = dstFile.openWrite();
-  output.addStream(srcStream).then((_) {
+  output.addStream(srcStream.cast<List<int>>()).then((_) {
     var srcStream2 = srcFile.openRead();
-    output.addStream(srcStream2).then((_) {
+    output.addStream(srcStream2.cast<List<int>>()).then((_) {
       output.close();
       output.done.then((_) {
         var src = srcFile.openSync();
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index 5a8f844..fa9f5d7 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -26,15 +26,7 @@
 
 [ $compiler == dartkb ]
 io/dart_std_io_pipe_test: Pass, Timeout # Please triage
-io/platform_resolved_executable_test/00: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/01: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/02: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
-io/platform_resolved_executable_test/03: RuntimeError
-io/platform_resolved_executable_test/04: RuntimeError
-io/platform_resolved_executable_test/05: RuntimeError # Reruns the same script (dill file without AST) without passing --enable-interpreter or --use-bytecode-compiler.
 io/platform_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_fail_test: RuntimeError # Platform.script points to dill file.
-io/test_extension_test: RuntimeError # Platform.script points to dill file.
 no_lazy_dispatchers_test: SkipByDesign # KBC interpreter doesn't support --no_lazy_dispatchers
 
 [ $compiler == dartkp ]
diff --git a/tests/standalone_2/standalone_2_precompiled.status b/tests/standalone_2/standalone_2_precompiled.status
index 38d1e2c..672a30e 100644
--- a/tests/standalone_2/standalone_2_precompiled.status
+++ b/tests/standalone_2/standalone_2_precompiled.status
@@ -5,10 +5,6 @@
 [ $builder_tag == obfuscated ]
 dwarf_stack_trace_test: Pass, RuntimeError # Issue 35563
 
-[ $compiler == precompiler ]
-io/web_socket_test: Pass, RuntimeError # Issue 24674
-map_insert_remove_oom_test: Skip # Heap limit too low. Increasing iteration count to make a higher limit a meaningful test makes it too slow for simarm[64] bots.
-
 [ $runtime == dart_precompiled ]
 http_launch_test: Skip
 io/addlatexhash_test: Skip
@@ -49,6 +45,14 @@
 io/test_extension_fail_test: Skip
 io/test_extension_test: Skip
 io/windows_environment_test: Skip
+package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
+package/scenarios/invalid/invalid_utf8_test: Skip
+package/scenarios/invalid/non_existent_packages_file_test: Skip
+package/scenarios/invalid/same_package_twice_test: Skip
+package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
+package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
+package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
+package/scenarios/packages_option_only/packages_option_only_test: Skip
 
 [ $arch == arm && $mode == release && $runtime == dart_precompiled && $system == android ]
 io/socket_cancel_connect_test: RuntimeError # Issue 34142
@@ -60,18 +64,5 @@
 [ $runtime == dart_precompiled && $checked ]
 io/namespace_test: RuntimeError
 
-[ $compiler == app_jit || $compiler == precompiler ]
-io/compile_all_test: Skip # Incompatible flag --compile_all
-
-[ $compiler == app_jit || $runtime == dart_precompiled ]
-package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
-package/scenarios/invalid/invalid_utf8_test: Skip
-package/scenarios/invalid/non_existent_packages_file_test: Skip
-package/scenarios/invalid/same_package_twice_test: Skip
-package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
-package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
-package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
-package/scenarios/packages_option_only/packages_option_only_test: Skip
-
 [ $mode == product || $runtime == dart_precompiled ]
 no_assert_test: SkipByDesign # Requires checked mode.
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index e77465f..5919089 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -6,20 +6,6 @@
 link_natives_lazily_test: SkipByDesign # Not supported.
 no_allow_absolute_addresses_test: SkipByDesign # Not supported.
 
-[ $compiler == app_jit ]
-full_coverage_test: Skip # Platform.executable
-io/namespace_test: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/00: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/01: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/02: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/03: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/04: RuntimeError # Issue 33168
-io/platform_resolved_executable_test/05: RuntimeError # Issue 33168
-io/platform_test: Skip # Platform.executable
-io/test_extension_fail_test: Skip # Platform.executable
-io/test_extension_test: Skip # Platform.executable
-regress_26031_test: Skip # Platform.resolvedExecutable
-
 [ $system == android ]
 io/file_stat_test: Skip # Issue 26376
 io/file_system_watcher_test: Skip # Issue 26376
diff --git a/tools/VERSION b/tools/VERSION
index 1a2f417..0bb2831 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 5
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
-ABI_VERSION 5
-OLDEST_SUPPORTED_ABI_VERSION 3
+ABI_VERSION 7
+OLDEST_SUPPORTED_ABI_VERSION 5
diff --git a/tools/approve_results.dart b/tools/approve_results.dart
index 5912f3b..c9dcf7d 100755
--- a/tools/approve_results.dart
+++ b/tools/approve_results.dart
@@ -141,6 +141,7 @@
       throw new Exception("Failed to download $logUrl: ${response.statusCode}");
     }
     final contents = (await response
+            .cast<List<int>>()
             .transform(new Utf8Decoder())
             .timeout(const Duration(seconds: 60))
             .toList())
@@ -186,7 +187,7 @@
             ? await todoFallbackLoadLog(
                 changelistBuild["id"],
                 "download_previous_results/0/steps/gsutil_find_latest_build/0/logs/"
-                "raw_io.output_text_latest_/0",
+                    "raw_io.output_text_latest_/0",
                 "gsutil_find_latest_build/0/logs/raw_io.output_text_latest_/0")
             : await readFile(bot, "latest"))
         .trim();
@@ -278,6 +279,7 @@
       throw new Exception("Failed to request $url: ${response.statusCode}");
     }
     final text = await response
+        .cast<List<int>>()
         .transform(utf8.decoder)
         .join()
         .timeout(const Duration(seconds: 30));
@@ -368,9 +370,11 @@
   final testMatrixBots = <String>[];
   for (final builderConfiguration in builderConfigurations) {
     final steps = builderConfiguration["steps"];
-    // Only consider bots that use tools/test.py.
+    // Only consider bots that use tools/test.py or custom test runners.
     if (!steps.any((step) =>
-        step["script"] == null || step["script"] == "tools/test.py")) {
+        step["script"] == null ||
+        step["script"] == "tools/test.py" ||
+        step["testRunner"] == true)) {
       continue;
     }
     final builders = builderConfiguration["builders"].cast<String>();
@@ -460,6 +464,7 @@
       throw new Exception("Failed to request try runs for $gerrit");
     }
     final Map<String, dynamic> object = await response
+        .cast<List<int>>()
         .transform(new Utf8Decoder())
         .transform(new JsonDecoder())
         .first
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 8106385..5a0a741 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -60,6 +60,7 @@
       final request = await client.getUrl(url).timeout(timeout);
       final response = await request.close().timeout(timeout);
       object = await response
+          .cast<List<int>>()
           .transform(new Utf8Decoder())
           .transform(new JsonDecoder())
           .first
diff --git a/tools/bots/results.dart b/tools/bots/results.dart
index 65ae36f..c42d828 100644
--- a/tools/bots/results.dart
+++ b/tools/bots/results.dart
@@ -7,6 +7,9 @@
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
+import 'dart:math';
+
+import 'package:pool/pool.dart';
 
 /// The path to the gsutil script.
 String gsutilPy;
@@ -18,30 +21,36 @@
 const approvedResultsStoragePath =
     "gs://dart-test-results-approved-results/builders";
 
+/// Limit the number of concurrent subprocesses by half the number of cores.
+final gsutilPool = new Pool(max(1, Platform.numberOfProcessors ~/ 2));
+
 /// Runs gsutil with the provided [arguments] and returns the standard output.
 /// Returns null if the requested URL didn't exist.
 Future<String> runGsutil(List<String> arguments) async {
-  final processResult = await Process.run(
-      "python", [gsutilPy]..addAll(arguments),
-      runInShell: Platform.isWindows);
-  if (processResult.exitCode != 0) {
-    if (processResult.exitCode == 1 &&
-            processResult.stderr.contains("No URLs matched") ||
-        processResult.stderr.contains("One or more URLs matched no objects")) {
-      return null;
+  return gsutilPool.withResource(() async {
+    final processResult = await Process.run(
+        "python", [gsutilPy]..addAll(arguments),
+        runInShell: Platform.isWindows);
+    if (processResult.exitCode != 0) {
+      if (processResult.exitCode == 1 &&
+              processResult.stderr.contains("No URLs matched") ||
+          processResult.stderr
+              .contains("One or more URLs matched no objects")) {
+        return null;
+      }
+      String error = "Failed to run: python $gsutilPy $arguments\n"
+          "exitCode: ${processResult.exitCode}\n"
+          "stdout:\n${processResult.stdout}\n"
+          "stderr:\n${processResult.stderr}";
+      if (processResult.exitCode == 1 &&
+          processResult.stderr.contains("401 Anonymous caller")) {
+        error =
+            "\n\nYou need to authenticate by running:\npython $gsutilPy config\n";
+      }
+      throw new Exception(error);
     }
-    String error = "Failed to run: python $gsutilPy $arguments\n"
-        "exitCode: ${processResult.exitCode}\n"
-        "stdout:\n${processResult.stdout}\n"
-        "stderr:\n${processResult.stderr}";
-    if (processResult.exitCode == 1 &&
-        processResult.stderr.contains("401 Anonymous caller")) {
-      error =
-          "\n\nYou need to authenticate by running:\npython $gsutilPy config\n";
-    }
-    throw new Exception(error);
-  }
-  return processResult.stdout;
+    return processResult.stdout;
+  });
 }
 
 /// Returns the contents of the provided cloud storage [path], or null if it
@@ -111,6 +120,7 @@
   final results = <Map<String, dynamic>>[];
   final lines = new File(path)
       .openRead()
+      .cast<List<int>>()
       .transform(utf8.decoder)
       .transform(new LineSplitter());
   await for (final line in lines) {
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 3530395..5836ea1 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -277,6 +277,20 @@
       "options": {
         "host-checked": true
     }},
+    "dart2js-new-rti-(linux|mac|win)-x64-d8": {
+      "options": {
+        "builder-tag": "new_rti",
+        "dart2js-options": ["--experiment-new-rti"],
+        "host-checked": true
+    }},
+    "dart2js-new-rti-minified-csp-(linux|mac|win)-x64-d8": {
+      "options": {
+        "builder-tag": "new_rti",
+        "csp": true,
+        "dart2js-options": ["--experiment-new-rti"],
+        "minified": true,
+        "use-sdk": true
+    }},
     "dartkp-android-(debug|product|release)-(arm|arm64)": {
       "options": {
         "use-elf": true
@@ -1238,6 +1252,47 @@
     },
     {
       "builders": [
+        "dart2js-rti-linux-x64-d8"
+      ],
+      "meta": {
+        "description": "dart2js-d8 tests with new-RTI enabled"
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": ["dart2js_bot"]
+        },
+        {
+          "name": "dart2js new-rti tests",
+          "arguments": [
+            "-ndart2js-new-rti-linux-x64-d8",
+            "--dart2js-batch",
+            "language_2",
+            "corelib_2",
+            "dart2js_native",
+            "dart2js_extra"
+          ],
+          "shards": 6,
+          "fileset": "dart2js_hostasserts"
+        },
+        {
+          "name": "dart2js new-rti minified+csp tests",
+          "arguments": [
+            "-ndart2js-new-rti-minified-csp-linux-x64-d8",
+            "--dart2js-batch",
+            "language_2",
+            "corelib_2",
+            "dart2js_native",
+            "dart2js_extra"
+          ],
+          "shards": 6,
+          "fileset": "dart2js"
+        }
+      ]
+    },
+    {
+      "builders": [
         "dart2js-strong-linux-x64-chrome",
         "dart2js-strong-linux-x64-firefox",
         "dart2js-strong-mac-x64-chrome",
@@ -1518,14 +1573,14 @@
     {
       "builders": ["dart-sdk-win"],
       "meta": {
-        "description": "This configuration is used by the sdk-builders for Windows."
+        "description": "This configuration is used by the sdk-builders for Windows. It also adds CQ coverage for building on Windows."
       },
       "steps": [
         {
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": ["--arch=ia32,x64",
-                        "--mode=release", "create_sdk"]
+                        "--mode=release", "create_sdk", "runtime_kernel"]
         },
         {
           "name": "build gen_kernel.dart.snapshot and dart2aot",
diff --git a/tools/dart2js/class_generator/class_generator.dart b/tools/dart2js/class_generator/class_generator.dart
index 55bcdad..50af327 100644
--- a/tools/dart2js/class_generator/class_generator.dart
+++ b/tools/dart2js/class_generator/class_generator.dart
@@ -140,7 +140,7 @@
       File measuring = new File("${dir.path}/measuring.js");
       IOSink sink = measuring.openWrite();
       sink.writeln("var start = new Date();");
-      await sink.addStream(new File(fileName).openRead());
+      await sink.addStream(new File(fileName).openRead().cast<List<int>>());
       sink.writeln("print(new Date() - start)");
       String command;
       List<String> args;
diff --git a/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart b/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
index b97460c..51b958c 100644
--- a/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
+++ b/tools/dart2js/sourceMapViewer/bin/source_map_viewer.dart
@@ -47,7 +47,11 @@
   }
 
   Uri uri = sourceMapFile.resolve(path);
-  new File.fromUri(uri).openRead().pipe(request.response).catchError((e) {
+  new File.fromUri(uri)
+      .openRead()
+      .cast<List<int>>()
+      .pipe(request.response)
+      .catchError((e) {
     print("Error: $e");
     request.response.close();
   });
diff --git a/tools/dom/scripts/CSSPropertyNames.in b/tools/dom/scripts/CSSPropertyNames.in
index 27e9fb1..39b49ad 100644
--- a/tools/dom/scripts/CSSPropertyNames.in
+++ b/tools/dom/scripts/CSSPropertyNames.in
@@ -2,6 +2,7 @@
 // https://codereview.chromium.org/444453006/ has been committed, in which case
 // it will be pulled in from DEPS!
 // Copied from http://trac.webkit.org/browser/trunk/WebCore/css/CSSPropertyNames.in
+// via. http://web.archive.org/web/20100722083519/http://trac.webkit.org/browser/trunk/WebCore/css/CSSPropertyNames.in
 //
 // CSS property names
 //
diff --git a/tools/dom/src/KeyCode.dart b/tools/dom/src/KeyCode.dart
index e9dca60..a51d062 100644
--- a/tools/dom/src/KeyCode.dart
+++ b/tools/dom/src/KeyCode.dart
@@ -15,7 +15,7 @@
 abstract class KeyCode {
   // These constant names were borrowed from Closure's Keycode enumeration
   // class.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keycodes.js.source.html
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keycodes.js
   static const int WIN_KEY_FF_LINUX = 0;
   static const int MAC_ENTER = 3;
   static const int BACKSPACE = 8;
diff --git a/tools/dom/src/KeyboardEventStream.dart b/tools/dom/src/KeyboardEventStream.dart
index fea4654..48f7a68 100644
--- a/tools/dom/src/KeyboardEventStream.dart
+++ b/tools/dom/src/KeyboardEventStream.dart
@@ -10,7 +10,7 @@
  */
 class _KeyboardEventHandler extends EventStreamProvider<KeyEvent> {
   // This code inspired by Closure's KeyHandling library.
-  // http://closure-library.googlecode.com/svn/docs/closure_goog_events_keyhandler.js.source.html
+  // https://github.com/google/closure-library/blob/master/closure/goog/events/keyhandler.js
 
   /**
    * The set of keys that have been pressed down without seeing their
@@ -35,7 +35,7 @@
   /**
    * An enumeration of key identifiers currently part of the W3C draft for DOM3
    * and their mappings to keyCodes.
-   * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+   * https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/keyset.html#KeySet-Set
    */
   static const Map<String, int> _keyIdentifier = const {
     'Up': KeyCode.UP,
diff --git a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
index 12f29c3..3ee9b43 100644
--- a/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLInputElement.darttemplate
@@ -44,7 +44,7 @@
 
 // Interfaces representing the InputElement APIs which are supported
 // for the various types of InputElement. From:
-// http://www.w3.org/html/wg/drafts/html/master/forms.html#the-input-element.
+// https://w3c.github.io/html/sec-forms.html#the-input-element.
 
 /**
  * Exposes the functionality common between all InputElement types.
diff --git a/tools/experimental_features.yaml b/tools/experimental_features.yaml
index 1a82f0f..7bd3a0f 100644
--- a/tools/experimental_features.yaml
+++ b/tools/experimental_features.yaml
@@ -83,14 +83,13 @@
   help: "Triple-shift operator"
 
 #
-# Flags below this line are either retired or rejected, cannot be specified
+# Flags below this line are shipped, retired, or rejected, cannot be specified
 # on the command line, and will eventually be removed.
 #
 
 control-flow-collections:
   help: "Control Flow Collections"
   enabledIn: '2.2.2'
-  expired: true
 
 set-literals:
   help: "Set Literals"
@@ -100,4 +99,3 @@
 spread-collections:
   help: "Spread Collections"
   enabledIn: '2.2.2'
-  expired: true
\ No newline at end of file
diff --git a/tools/gardening/lib/src/luci_api.dart b/tools/gardening/lib/src/luci_api.dart
index bf808f0..93d9b6f 100644
--- a/tools/gardening/lib/src/luci_api.dart
+++ b/tools/gardening/lib/src/luci_api.dart
@@ -97,7 +97,7 @@
       response.drain();
       throw new HttpException(response.reasonPhrase, uri: uri);
     }
-    return response.transform(utf8.decoder).join();
+    return response.cast<List<int>>().transform(utf8.decoder).join();
   }
 
   /// [_makePostRequest] performs a post request to [uri], where the posted
diff --git a/tools/gardening/lib/src/util.dart b/tools/gardening/lib/src/util.dart
index 4dd25e0..0cee8c7 100644
--- a/tools/gardening/lib/src/util.dart
+++ b/tools/gardening/lib/src/util.dart
@@ -88,9 +88,13 @@
     throw new HttpException(uri, response.statusCode);
   }
   if (timeout != null) {
-    return response.timeout(timeout).transform(utf8.decoder).join();
+    return response
+        .timeout(timeout)
+        .cast<List<int>>()
+        .transform(utf8.decoder)
+        .join();
   } else {
-    return response.transform(utf8.decoder).join();
+    return response.cast<List<int>>().transform(utf8.decoder).join();
   }
 }
 
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
deleted file mode 100644
index b0ef7d7..0000000
--- a/tools/patch_sdk.dart
+++ /dev/null
@@ -1,831 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2015, 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.
-
-/// Command line tool to merge the SDK libraries and our patch files.
-/// This is currently designed as an offline tool, but we could automate it.
-
-import 'dart:io';
-import 'dart:isolate' show RawReceivePort;
-import 'dart:async';
-import 'dart:math' as math;
-import 'dart:convert' show jsonEncode;
-
-// ignore: deprecated_member_use
-import 'package:analyzer/analyzer.dart'
-    show parseCompilationUnit, parseDirectives;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-import 'package:path/path.dart' as path;
-import 'package:front_end/src/api_prototype/front_end.dart';
-import 'package:front_end/src/base/processed_options.dart';
-import 'package:front_end/src/kernel_generator_impl.dart';
-import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
-import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
-import 'package:front_end/src/fasta/kernel/utils.dart'
-    show writeComponentToFile;
-import 'package:kernel/target/targets.dart';
-import 'package:vm/target/vm.dart' show VmTarget;
-import 'package:vm/target/flutter.dart' show FlutterTarget;
-
-/// Set of input files that were read by this script to generate patched SDK.
-/// We will dump it out into the depfile for ninja to use.
-///
-/// For more information see GN and Ninja references:
-///    https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-dependencies-for-actions
-///    https://ninja-build.org/manual.html#_depfile
-///
-final deps = new Set<Uri>();
-
-/// Create [File] object from the given path and register it as a dependency.
-File getInputFile(String path, {canBeMissing: false}) {
-  final file = new File(path);
-  if (!file.existsSync()) {
-    if (!canBeMissing)
-      throw "patch_sdk.dart expects all inputs to exist, missing: $path";
-    return null;
-  }
-  deps.add(Uri.base.resolveUri(file.uri));
-  return file;
-}
-
-/// Read the given file synchronously as a string and register this path as
-/// a dependency.
-String readInputFile(String path, {canBeMissing: false}) =>
-    getInputFile(path, canBeMissing: canBeMissing)?.readAsStringSync();
-
-Future main(List<String> argv) async {
-  var port = new RawReceivePort();
-  try {
-    await _main(argv);
-  } finally {
-    port.close();
-  }
-}
-
-void usage(String mode) {
-  var base = path.fromUri(Platform.script);
-  final self = path.relative(base);
-  print('Usage: $self $mode SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES');
-
-  final repositoryDir = path.relative(path.dirname(path.dirname(base)));
-  final sdkExample = path.relative(path.join(repositoryDir, 'sdk'));
-  final patchExample = path.relative(
-      path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch'));
-  final outExample = path.relative(
-      path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk'));
-  final packagesExample = path.relative(path.join(repositoryDir, '.packages'));
-  print('For example:');
-  print('\$ $self vm $sdkExample $patchExample $outExample $packagesExample');
-
-  exit(1);
-}
-
-const validModes = const ['vm', 'flutter', 'runner'];
-String mode;
-bool get forVm => mode == 'vm';
-bool get forFlutter => mode == 'flutter';
-bool get forRunner => mode == 'runner';
-
-Future _main(List<String> argv) async {
-  if (argv.isEmpty) usage('[${validModes.join('|')}]');
-  mode = argv.first;
-  if (!validModes.contains(mode)) usage('[${validModes.join('|')}]');
-  if (argv.length != 5) usage(mode);
-
-  var input = argv[1];
-  var sdkLibIn = path.join(input, 'lib');
-  var patchIn = argv[2];
-  var outDir = argv[3];
-  var outDirUri = Uri.base.resolveUri(new Uri.directory(outDir));
-  var sdkOut = path.join(outDir, 'lib');
-  var packagesFile = argv[4];
-
-  await new Directory.fromUri(outDirUri).delete(recursive: true);
-
-  // Parse libraries.dart
-  var libContents = readInputFile(path.join(
-      sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'));
-  libContents = _updateLibraryMetadata(sdkOut, libContents);
-  var sdkLibraries = _getSdkLibraries(libContents);
-
-  var locations = <String, Map<String, String>>{};
-
-  // Enumerate core libraries and apply patches
-  for (SdkLibrary library in sdkLibraries) {
-    if (library.isDart2JsLibrary) continue;
-    _applyPatch(library, sdkLibIn, patchIn, sdkOut, locations);
-  }
-
-  _copyExtraLibraries(sdkOut, locations);
-
-  final Uri platform = outDirUri.resolve('platform.dill.tmp');
-  final Uri librariesJson = outDirUri.resolve("lib/libraries.json");
-  final Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile));
-  TargetFlags flags = new TargetFlags(legacyMode: true);
-  Target target;
-
-  switch (mode) {
-    case 'vm':
-      target = new VmTarget(flags);
-      break;
-
-    case 'flutter':
-    case 'flutter_release':
-      target = new FlutterTarget(flags);
-      break;
-
-    case 'dart2js':
-      target = new Dart2jsTarget("dart2js", flags);
-      break;
-
-    default:
-      throw "Unknown mode: $mode";
-  }
-
-  _writeSync(
-      librariesJson.toFilePath(),
-      jsonEncode({
-        mode: {"libraries": locations}
-      }));
-
-  await compilePlatform(outDirUri, target, packages, platform);
-
-  // We generate a dependency file for GN to properly regenerate the patched sdk
-  // folder, outline.dill and platform.dill files when necessary: either when
-  // the sdk sources change or when this script is updated. In particular:
-  //
-  //  - sdk changes: we track the actual sources we are compiling. If we are
-  //    building the dart2js sdk, this includes the dart2js-specific patch
-  //    files.
-  //
-  //    These files are tracked by [deps] and passed below to [writeDepsFile] in
-  //    the extraDependencies argument.
-  //
-  //  - script updates: we track this script file and any code it imports (even
-  //    sdk libraries). Note that this script runs on the standalone VM, so any
-  //    sdk library used by this script indirectly depends on a VM-specific
-  //    patch file.
-  //
-  //    These set of files is discovered by `getDependencies` below, and the
-  //    [platformForDeps] is always the VM-specific `platform.dill` file.
-  var platformForDeps = platform;
-  var sdkDir = outDirUri;
-  if (forFlutter || forRunner) {
-    // Note: this fails if `$root_out_dir/vm_platform.dill` doesn't exist.  The
-    // target to build the flutter patched sdk depends on
-    // //runtime/vm:kernel_platform_files to ensure this file exists.
-    platformForDeps = outDirUri.resolve('../vm_platform.dill');
-    sdkDir = null;
-  }
-  deps.addAll(await getDependencies(Platform.script,
-      sdk: sdkDir, packages: packages, platform: platformForDeps));
-  await writeDepsFile(
-      librariesJson, Uri.base.resolveUri(new Uri.file("$outDir.d")), deps);
-}
-
-/// Generates an outline.dill and platform.dill file containing the result of
-/// compiling a platform's SDK.
-///
-/// Returns a list of dependencies read by the compiler. This list can be used
-/// to create GN dependency files.
-Future<List<Uri>> compilePlatform(
-    Uri patchedSdk, Target target, Uri packages, Uri output) async {
-  var options = new CompilerOptions()
-    ..setExitCodeOnProblem = true
-    ..legacyMode = true
-    ..compileSdk = true
-    ..sdkRoot = patchedSdk
-    ..packagesFileUri = packages
-    ..target = target;
-
-  var inputs = [Uri.parse('dart:core')];
-  var result = await generateKernel(
-      new ProcessedOptions(options: options, inputs: inputs),
-      buildSummary: true,
-      buildComponent: true);
-  await writeComponentToFile(result.component, output);
-  return result.deps;
-}
-
-Future writeDepsFile(
-    Uri output, Uri depsFile, Iterable<Uri> allDependencies) async {
-  if (allDependencies.isEmpty) return;
-  String toRelativeFilePath(Uri uri) {
-    // Ninja expects to find file names relative to the current working
-    // directory. We've tried making them relative to the deps file, but that
-    // doesn't work for downstream projects. Making them absolute also
-    // doesn't work.
-    //
-    // We can test if it works by running ninja twice, for example:
-    //
-    //     ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
-    //     ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain
-    //
-    // The second time, ninja should say:
-    //
-    //     ninja: Entering directory `xcodebuild/ReleaseX64'
-    //     ninja: no work to do.
-    //
-    // It's broken if it says something like this:
-    //
-    //     ninja explain: expected depfile 'patched_sdk.d' to mention
-    //     'patched_sdk/platform.dill', got
-    //     '/.../xcodebuild/ReleaseX64/patched_sdk/platform.dill'
-    return Uri.parse(relativizeUri(uri, base: Uri.base)).toFilePath();
-  }
-
-  StringBuffer sb = new StringBuffer();
-  sb.write(toRelativeFilePath(output));
-  sb.write(":");
-  for (Uri uri in allDependencies) {
-    sb.write(" ");
-    sb.write(toRelativeFilePath(uri));
-  }
-  sb.writeln();
-  await new File.fromUri(depsFile).writeAsString("$sb");
-}
-
-/// Updates the contents of
-/// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include
-/// declarations for vm internal libraries.
-String _updateLibraryMetadata(String sdkOut, String libContents) {
-  if (!forVm && !forFlutter && !forRunner) return libContents;
-  var extraLibraries = new StringBuffer();
-  extraLibraries.write('''
-  "_builtin": const LibraryInfo(
-      "_builtin/_builtin.dart",
-      categories: "Client,Server",
-      implementation: true,
-      documented: false,
-      platforms: VM_PLATFORM),
-
-  "profiler": const LibraryInfo(
-      "profiler/profiler.dart",
-      maturity: Maturity.DEPRECATED,
-      documented: false),
-
-  "_vmservice": const LibraryInfo(
-      "vmservice/vmservice.dart",
-      categories: "Client,Server",
-      implementation: true,
-      documented: false,
-      platforms: VM_PLATFORM),
-
-  "vmservice_io": const LibraryInfo(
-      "vmservice_io/vmservice_io.dart",
-      categories: "Client,Server",
-      implementation: true,
-      documented: false,
-      platforms: VM_PLATFORM),
-  ''');
-
-  if (forFlutter) {
-    extraLibraries.write('''
-      "ui": const LibraryInfo(
-          "ui/ui.dart",
-          categories: "Client,Server",
-          implementation: true,
-          documented: false,
-          platforms: VM_PLATFORM),
-  ''');
-  }
-
-  if (forRunner) {
-    extraLibraries.write('''
-      "fuchsia.builtin": const LibraryInfo(
-          "fuchsia.builtin/builtin.dart",
-          categories: "Client,Server",
-          implementation: true,
-          documented: false,
-          platforms: VM_PLATFORM),
-  ''');
-    extraLibraries.write('''
-      "zircon": const LibraryInfo(
-          "zircon/zircon.dart",
-          categories: "Client,Server",
-          implementation: true,
-          documented: false,
-          platforms: VM_PLATFORM),
-  ''');
-    extraLibraries.write('''
-      "fuchsia": const LibraryInfo(
-          "fuchsia/fuchsia.dart",
-          categories: "Client,Server",
-          implementation: true,
-          documented: false,
-          platforms: VM_PLATFORM),
-  ''');
-  }
-
-  libContents = libContents.replaceAll(
-      ' libraries = const {', ' libraries = const { $extraLibraries');
-  _writeSync(
-      path.join(
-          sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'),
-      libContents);
-  return libContents;
-}
-
-/// Copy internal libraries that are developed outside the sdk folder into the
-/// patched_sdk folder. For the VM< this includes files under 'runtime/bin/',
-/// for flutter, this is includes also the ui library.
-_copyExtraLibraries(String sdkOut, Map<String, Map<String, String>> locations) {
-  var base = path.fromUri(Platform.script);
-  var dartDir = path.dirname(path.dirname(path.absolute(base)));
-
-  var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', 'builtin.dart');
-  var builtinLibraryOut = path.join(sdkOut, '_builtin', '_builtin.dart');
-  _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn));
-  addLocation(locations, '_builtin', path.join('_builtin', '_builtin.dart'));
-  for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) {
-    var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file);
-    var libraryOut = path.join(sdkOut, 'vmservice_io', file);
-    _writeSync(libraryOut, readInputFile(libraryIn));
-  }
-  addLocation(locations, 'vmservice_io',
-      path.join('vmservice_io', 'vmservice_io.dart'));
-  addLocation(
-      locations, '_vmservice', path.join('vmservice', 'vmservice.dart'));
-
-  if (forFlutter) {
-    // Flutter repo has this layout:
-    //  engine/src/
-    //       third_party/dart/
-    //       [third_party/]flutter/
-    var srcDir = path
-        .dirname(path.dirname(path.dirname(path.dirname(path.absolute(base)))));
-    var flutterDir = new Directory(path.join(srcDir, 'flutter'));
-    if (!flutterDir.existsSync()) {
-      // In Fuchsia Flutter is under 'third_party'.
-      flutterDir = new Directory(path.join(srcDir, 'third_party', 'flutter'));
-    }
-    var uiLibraryInDir = new Directory(path.join(flutterDir.path, 'lib', 'ui'));
-    for (var file in uiLibraryInDir.listSync()) {
-      if (!file.path.endsWith('.dart')) continue;
-      var name = path.basename(file.path);
-      var uiLibraryOut = path.join(sdkOut, 'ui', name);
-      _writeSync(uiLibraryOut, readInputFile(file.path));
-    }
-    addLocation(locations, 'ui', path.join('ui', 'ui.dart'));
-  }
-
-  if (forRunner) {
-    var gnRoot = path
-        .dirname(path.dirname(path.dirname(path.dirname(path.absolute(base)))));
-
-    var builtinLibraryInDir = new Directory(
-        path.join(gnRoot, 'topaz', 'runtime', 'dart_runner', 'embedder'));
-    for (var file in builtinLibraryInDir.listSync()) {
-      if (!file.path.endsWith('.dart')) continue;
-      var name = path.basename(file.path);
-      var builtinLibraryOut = path.join(sdkOut, 'fuchsia.builtin', name);
-      _writeSync(builtinLibraryOut, readInputFile(file.path));
-    }
-    addLocation(locations, 'fuchsia.builtin',
-        path.join('fuchsia.builtin', 'builtin.dart'));
-
-    var zirconLibraryInDir = new Directory(
-        path.join(gnRoot, 'topaz', 'public', 'dart-pkg', 'zircon', 'lib'));
-    for (var file in zirconLibraryInDir.listSync(recursive: true)) {
-      if (!file.path.endsWith('.dart')) continue;
-      var name = file.path.substring(zirconLibraryInDir.path.length + 1);
-      var zirconLibraryOut = path.join(sdkOut, 'zircon', name);
-      _writeSync(zirconLibraryOut, readInputFile(file.path));
-    }
-    addLocation(locations, 'zircon', path.join('zircon', 'zircon.dart'));
-
-    var fuchsiaLibraryInDir = new Directory(
-        path.join(gnRoot, 'topaz', 'public', 'dart-pkg', 'fuchsia', 'lib'));
-    for (var file in fuchsiaLibraryInDir.listSync(recursive: true)) {
-      if (!file.path.endsWith('.dart')) continue;
-      var name = file.path.substring(fuchsiaLibraryInDir.path.length + 1);
-      var fuchsiaLibraryOut = path.join(sdkOut, 'fuchsia', name);
-      _writeSync(fuchsiaLibraryOut, readInputFile(file.path));
-    }
-    addLocation(locations, 'fuchsia', path.join('fuchsia', 'fuchsia.dart'));
-  }
-}
-
-_applyPatch(SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut,
-    Map<String, Map<String, String>> locations) {
-  var libraryOut = path.join(sdkLibIn, library.path);
-  var libraryIn = libraryOut;
-
-  var libraryFile = getInputFile(libraryIn, canBeMissing: true);
-  if (libraryFile != null) {
-    addLocation(locations, Uri.parse(library.shortName).path,
-        path.relative(libraryOut, from: sdkLibIn));
-    var outPaths = <String>[libraryOut];
-    var libraryContents = libraryFile.readAsStringSync();
-
-    int inputModifyTime = libraryFile.lastModifiedSync().millisecondsSinceEpoch;
-    var partFiles = <File>[];
-    for (var part in parseDirectives(libraryContents).directives) {
-      if (part is PartDirective) {
-        var partPath = part.uri.stringValue;
-        outPaths.add(path.join(path.dirname(libraryOut), partPath));
-
-        var partFile =
-            getInputFile(path.join(path.dirname(libraryIn), partPath));
-        partFiles.add(partFile);
-        inputModifyTime = math.max(inputModifyTime,
-            partFile.lastModifiedSync().millisecondsSinceEpoch);
-      }
-    }
-
-    // See if we can find a patch file.
-    var patchPath = path.join(
-        patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart');
-
-    var patchFile = getInputFile(patchPath, canBeMissing: true);
-    if (patchFile != null) {
-      inputModifyTime = math.max(
-          inputModifyTime, patchFile.lastModifiedSync().millisecondsSinceEpoch);
-    }
-
-    // Compute output paths
-    outPaths = outPaths
-        .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn)))
-        .toList();
-
-    // Compare output modify time with input modify time.
-    bool needsUpdate = false;
-    for (var outPath in outPaths) {
-      var outFile = new File(outPath);
-      if (!outFile.existsSync() ||
-          outFile.lastModifiedSync().millisecondsSinceEpoch < inputModifyTime) {
-        needsUpdate = true;
-        break;
-      }
-    }
-
-    if (needsUpdate) {
-      var contents = <String>[libraryContents];
-      contents.addAll(partFiles.map((f) => f.readAsStringSync()));
-      if (patchFile != null) {
-        var patchContents = patchFile.readAsStringSync();
-        contents = _patchLibrary(patchFile.path, contents, patchContents);
-      }
-
-      for (var i = 0; i < outPaths.length; i++) {
-        _writeSync(outPaths[i], contents[i]);
-      }
-    }
-  }
-}
-
-/// Writes a file, creating the directory if needed.
-void _writeSync(String filePath, String contents) {
-  var outDir = new Directory(path.dirname(filePath));
-  if (!outDir.existsSync()) outDir.createSync(recursive: true);
-
-  new File(filePath).writeAsStringSync(contents);
-}
-
-/// Merges dart:* library code with code from *_patch.dart file.
-///
-/// Takes a list of the library's parts contents, with the main library contents
-/// first in the list, and the contents of the patch file.
-///
-/// The result will have `@patch` implementations merged into the correct place
-/// (e.g. the class or top-level function declaration) and all other
-/// declarations introduced by the patch will be placed into the main library
-/// file.
-///
-/// This is purely a syntactic transformation. Unlike dart2js patch files, there
-/// is no semantic meaning given to the *_patch files, and they do not magically
-/// get their own library scope, etc.
-///
-/// Editorializing: the dart2js approach requires a Dart front end such as
-/// package:analyzer to semantically model a feature beyond what is specified
-/// in the Dart language. Since this feature is only for the convenience of
-/// writing the dart:* libraries, and not a tool given to Dart developers, it
-/// seems like a non-ideal situation. Instead we keep the preprocessing simple.
-List<String> _patchLibrary(
-    String name, List<String> partsContents, String patchContents) {
-  var results = <StringEditBuffer>[];
-
-  // Parse the patch first. We'll need to extract bits of this as we go through
-  // the other files.
-  final patchFinder = new PatchFinder.parseAndVisit(name, patchContents);
-
-  // Merge `external` declarations with the corresponding `@patch` code.
-  for (var partContent in partsContents) {
-    var partEdits = new StringEditBuffer(partContent);
-    var partUnit = parseCompilationUnit(partContent);
-    partUnit.accept(new PatchApplier(partEdits, patchFinder));
-    results.add(partEdits);
-  }
-
-  if (patchFinder.patches.length != patchFinder.applied.length) {
-    print('Some elements marked as @patch do not have corresponding elements:');
-    for (var patched in patchFinder.patches.keys) {
-      if (!patchFinder.applied.contains(patched)) {
-        print('*** ${patched}');
-      }
-    }
-    throw "Failed to apply all @patch-es";
-  }
-
-  return new List<String>.from(results.map((e) => e.toString()));
-}
-
-final String injectedCidFields = [
-  'Array',
-  'ExternalOneByteString',
-  'GrowableObjectArray',
-  'ImmutableArray',
-  'OneByteString',
-  'TwoByteString',
-].map((name) => "static final int cid${name} = 0;").join('\n');
-
-/// Merge `@patch` declarations into `external` declarations.
-class PatchApplier extends GeneralizingAstVisitor {
-  final StringEditBuffer edits;
-  final PatchFinder patch;
-
-  bool _isLibrary = true; // until proven otherwise.
-
-  PatchApplier(this.edits, this.patch);
-
-  @override
-  visitCompilationUnit(CompilationUnit node) {
-    super.visitCompilationUnit(node);
-    if (_isLibrary) _mergeUnpatched(node);
-  }
-
-  void _merge(AstNode node, int pos) {
-    var code = patch.contents.substring(node.offset, node.end);
-
-    // We inject a number of static fields into dart:internal.ClassID class.
-    // These fields represent various VM class ids and are only used to
-    // make core libraries compile. Kernel reader will actually ignore these
-    // fields and instead inject concrete constants into this class.
-    if (node is ClassDeclaration && node.name.name == 'ClassID') {
-      code = code.replaceFirst(new RegExp(r'}$'), injectedCidFields + '}');
-    }
-    edits.insert(pos, '\n' + code);
-  }
-
-  /// Merges directives and declarations that are not `@patch` into the library.
-  void _mergeUnpatched(CompilationUnit unit) {
-    // Merge imports from the patch
-    // TODO(jmesserly): remove duplicate imports
-
-    // To patch a library, we must have a library directive
-    var libDir = unit.directives.first as LibraryDirective;
-    int importPos = unit.directives
-        .lastWhere((d) => d is ImportDirective, orElse: () => libDir)
-        .end;
-    for (var d in patch.unit.directives.where((d) => d is ImportDirective)) {
-      _merge(d, importPos);
-    }
-
-    int partPos = unit.directives.last.end;
-    for (var d in patch.unit.directives.where((d) => d is PartDirective)) {
-      _merge(d, partPos);
-    }
-
-    // Merge declarations from the patch
-    int declPos = edits.original.length;
-    for (var d in patch.mergeDeclarations) {
-      _merge(d, declPos);
-    }
-  }
-
-  @override
-  visitPartOfDirective(PartOfDirective node) {
-    _isLibrary = false;
-  }
-
-  @override
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    _maybePatch(node);
-  }
-
-  /// Merge patches and extensions into the class
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    node.members.forEach(_maybePatch);
-
-    var mergeMembers = patch.mergeMembers[_qualifiedName(node)];
-    if (mergeMembers == null) return;
-
-    // Merge members from the patch
-    var pos = node.members.last.end;
-    for (var member in mergeMembers) {
-      var code = patch.contents.substring(member.offset, member.end);
-      edits.insert(pos, '\n\n  ' + code);
-    }
-  }
-
-  void _maybePatch(AstNode node) {
-    if (node is FieldDeclaration) return;
-
-    var externalKeyword = (node as dynamic).externalKeyword;
-
-    var name = _qualifiedName(node);
-    var patchNode = patch.patches[name];
-    if (patchNode == null) {
-      if (externalKeyword != null) {
-        print('warning: patch not found for $name: $node');
-        exitCode = 1;
-      }
-      return;
-    }
-    patch.applied.add(name);
-
-    Annotation patchMeta = patchNode.metadata.lastWhere(_isPatchAnnotation);
-    int start = patchMeta.endToken.next.offset;
-    var code = patch.contents.substring(start, patchNode.end);
-
-    // For some node like static fields, the node's offset doesn't include
-    // the external keyword. Also starting from the keyword lets us preserve
-    // documentation comments.
-    edits.replace(externalKeyword?.offset ?? node.offset, node.end, code);
-  }
-}
-
-class PatchFinder extends GeneralizingAstVisitor {
-  final String contents;
-  final CompilationUnit unit;
-
-  final Map patches = <String, Declaration>{};
-  final Map mergeMembers = <String, List<ClassMember>>{};
-  final List mergeDeclarations = <CompilationUnitMember>[];
-  final Set<String> applied = new Set<String>();
-
-  PatchFinder.parseAndVisit(String name, String contents)
-      : contents = contents,
-        unit = parseCompilationUnit(contents, name: name) {
-    visitCompilationUnit(unit);
-  }
-
-  @override
-  visitCompilationUnitMember(CompilationUnitMember node) {
-    mergeDeclarations.add(node);
-  }
-
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    if (_isPatch(node)) {
-      var members = <ClassMember>[];
-      for (var member in node.members) {
-        if (_isPatch(member)) {
-          patches[_qualifiedName(member)] = member;
-        } else {
-          members.add(member);
-        }
-      }
-      if (members.isNotEmpty) {
-        mergeMembers[_qualifiedName(node)] = members;
-      }
-    } else {
-      mergeDeclarations.add(node);
-    }
-  }
-
-  @override
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    if (_isPatch(node)) {
-      patches[_qualifiedName(node)] = node;
-    } else {
-      mergeDeclarations.add(node);
-    }
-  }
-
-  @override
-  visitFunctionBody(node) {} // skip method bodies
-}
-
-String _qualifiedName(Declaration node) {
-  var parent = node.parent;
-  var className = '';
-  if (parent is ClassDeclaration) {
-    className = parent.name.name + '.';
-  }
-  var name = (node as dynamic).name;
-  name = (name != null ? name.name : '');
-
-  var accessor = '';
-  if (node is MethodDeclaration) {
-    if (node.isGetter)
-      accessor = 'get:';
-    else if (node.isSetter) accessor = 'set:';
-  }
-  return className + accessor + name;
-}
-
-bool _isPatch(AnnotatedNode node) => node.metadata.any(_isPatchAnnotation);
-
-bool _isPatchAnnotation(Annotation m) =>
-    m.name.name == 'patch' && m.constructorName == null && m.arguments == null;
-
-/// Editable string buffer.
-///
-/// Applies a series of edits (insertions, removals, replacements) using
-/// original location information, and composes them into the edited string.
-///
-/// For example, starting with a parsed AST with original source locations,
-/// this type allows edits to be made without regards to other edits.
-class StringEditBuffer {
-  final String original;
-  final _edits = <_StringEdit>[];
-
-  /// Creates a new transaction.
-  StringEditBuffer(this.original);
-
-  bool get hasEdits => _edits.length > 0;
-
-  /// Edit the original text, replacing text on the range [begin] and
-  /// exclusive [end] with the [replacement] string.
-  void replace(int begin, int end, String replacement) {
-    _edits.add(new _StringEdit(begin, end, replacement));
-  }
-
-  /// Insert [string] at [offset].
-  /// Equivalent to `replace(offset, offset, string)`.
-  void insert(int offset, String string) => replace(offset, offset, string);
-
-  /// Remove text from the range [begin] to exclusive [end].
-  /// Equivalent to `replace(begin, end, '')`.
-  void remove(int begin, int end) => replace(begin, end, '');
-
-  /// Applies all pending [edit]s and returns a new string.
-  ///
-  /// This method is non-destructive: it does not discard existing edits or
-  /// change the [original] string. Further edits can be added and this method
-  /// can be called again.
-  ///
-  /// Throws [UnsupportedError] if the edits were overlapping. If no edits were
-  /// made, the original string will be returned.
-  String toString() {
-    var sb = new StringBuffer();
-    if (_edits.length == 0) return original;
-
-    // Sort edits by start location.
-    _edits.sort();
-
-    int consumed = 0;
-    for (var edit in _edits) {
-      if (consumed > edit.begin) {
-        sb = new StringBuffer();
-        sb.write('overlapping edits. Insert at offset ');
-        sb.write(edit.begin);
-        sb.write(' but have consumed ');
-        sb.write(consumed);
-        sb.write(' input characters. List of edits:');
-        for (var e in _edits) {
-          sb.write('\n    ');
-          sb.write(e);
-        }
-        throw new UnsupportedError(sb.toString());
-      }
-
-      // Add characters from the original string between this edit and the last
-      // one, if any.
-      var betweenEdits = original.substring(consumed, edit.begin);
-      sb.write(betweenEdits);
-      sb.write(edit.replace);
-      consumed = edit.end;
-    }
-
-    // Add any text from the end of the original string that was not replaced.
-    sb.write(original.substring(consumed));
-    return sb.toString();
-  }
-}
-
-class _StringEdit implements Comparable<_StringEdit> {
-  final int begin;
-  final int end;
-  final String replace;
-
-  _StringEdit(this.begin, this.end, this.replace);
-
-  int get length => end - begin;
-
-  String toString() => '(Edit @ $begin,$end: "$replace")';
-
-  int compareTo(_StringEdit other) {
-    int diff = begin - other.begin;
-    if (diff != 0) return diff;
-    return end - other.end;
-  }
-}
-
-List<SdkLibrary> _getSdkLibraries(String contents) {
-  var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(false);
-  parseCompilationUnit(contents).accept(libraryBuilder);
-  return libraryBuilder.librariesMap.sdkLibraries;
-}
-
-void addLocation(Map<String, Map<String, String>> locations, String libraryName,
-    String libraryPath) {
-  assert(locations[libraryName] == null);
-  locations[libraryName] = {'uri': '${path.toUri(libraryPath)}'};
-}
diff --git a/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch b/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
new file mode 100644
index 0000000..d4fdc59
--- /dev/null
+++ b/tools/patches/flutter-engine/67ab3be10d35d994641da167cc806f20a7ffa679.patch
@@ -0,0 +1,232 @@
+diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc
+index b649ca834..e181dd55b 100644
+--- a/runtime/dart_isolate.cc
++++ b/runtime/dart_isolate.cc
+@@ -163,7 +163,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
+   }
+ 
+   auto* isolate_data = static_cast<std::shared_ptr<DartIsolate>*>(
+-      Dart_IsolateGroupData(dart_isolate));
++      Dart_IsolateData(dart_isolate));
+   if (isolate_data->get() != this) {
+     return false;
+   }
+@@ -174,7 +174,7 @@ bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
+   // We are entering a new scope (for the first time since initialization) and
+   // we want to restore the current scope to null when we exit out of this
+   // method. This balances the implicit Dart_EnterIsolate call made by
+-  // Dart_CreateIsolateGroup (which calls the Initialize).
++  // Dart_CreateIsolate (which calls the Initialize).
+   Dart_ExitIsolate();
+ 
+   tonic::DartIsolateScope scope(isolate());
+@@ -636,8 +636,8 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
+   return service_isolate->isolate();
+ }
+ 
+-// |Dart_IsolateGroupCreateCallback|
+-Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback(
++// |Dart_IsolateCreateCallback|
++Dart_Isolate DartIsolate::DartIsolateCreateCallback(
+     const char* advisory_script_uri,
+     const char* advisory_script_entrypoint,
+     const char* package_root,
+@@ -720,16 +720,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
+   }
+ 
+   // Create the Dart VM isolate and give it the embedder object as the baton.
+-  Dart_Isolate isolate = Dart_CreateIsolateGroup(
++  Dart_Isolate isolate = Dart_CreateIsolate(
+       advisory_script_uri,         //
+       advisory_script_entrypoint,  //
+       (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(),
+       (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(),
+       (*embedder_isolate)->GetSharedSnapshot()->GetDataMapping(),
+       (*embedder_isolate)->GetSharedSnapshot()->GetInstructionsMapping(), flags,
+-      embedder_isolate.get(),  // isolate_group_data
+-      embedder_isolate.get(),  // isolate_data
+-      error);
++      embedder_isolate.get(), error);
+ 
+   if (isolate == nullptr) {
+     FML_DLOG(ERROR) << *error;
+@@ -772,15 +770,14 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
+ 
+ // |Dart_IsolateShutdownCallback|
+ void DartIsolate::DartIsolateShutdownCallback(
+-    std::shared_ptr<DartIsolate>* isolate_group_data,
+-    std::shared_ptr<DartIsolate>* isolate_data) {
+-  isolate_group_data->get()->OnShutdownCallback();
++    std::shared_ptr<DartIsolate>* embedder_isolate) {
++  embedder_isolate->get()->OnShutdownCallback();
+ }
+ 
+-// |Dart_IsolateGroupCleanupCallback|
+-void DartIsolate::DartIsolateGroupCleanupCallback(
+-    std::shared_ptr<DartIsolate>* isolate_group_data) {
+-  delete isolate_group_data;
++// |Dart_IsolateCleanupCallback|
++void DartIsolate::DartIsolateCleanupCallback(
++    std::shared_ptr<DartIsolate>* embedder_isolate) {
++  delete embedder_isolate;
+ }
+ 
+ fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
+diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h
+index 453810b1b..407852dc2 100644
+--- a/runtime/dart_isolate.h
++++ b/runtime/dart_isolate.h
+@@ -156,8 +156,8 @@ class DartIsolate : public UIDartState {
+ 
+   void OnShutdownCallback();
+ 
+-  // |Dart_IsolateGroupCreateCallback|
+-  static Dart_Isolate DartIsolateGroupCreateCallback(
++  // |Dart_IsolateCreateCallback|
++  static Dart_Isolate DartIsolateCreateCallback(
+       const char* advisory_script_uri,
+       const char* advisory_script_entrypoint,
+       const char* package_root,
+@@ -186,12 +186,11 @@ class DartIsolate : public UIDartState {
+ 
+   // |Dart_IsolateShutdownCallback|
+   static void DartIsolateShutdownCallback(
+-      std::shared_ptr<DartIsolate>* isolate_group_data,
+-      std::shared_ptr<DartIsolate>* isolate_data);
++      std::shared_ptr<DartIsolate>* embedder_isolate);
+ 
+-  // |Dart_IsolateGroupCleanupCallback|
+-  static void DartIsolateGroupCleanupCallback(
+-      std::shared_ptr<DartIsolate>* isolate_group_data);
++  // |Dart_IsolateCleanupCallback|
++  static void DartIsolateCleanupCallback(
++      std::shared_ptr<DartIsolate>* embedder_isolate);
+ 
+   FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate);
+ };
+diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc
+index 555d0c9ee..903e74b15 100644
+--- a/runtime/dart_vm.cc
++++ b/runtime/dart_vm.cc
+@@ -366,13 +366,12 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
+     params.vm_snapshot_data = vm_data_->GetVMSnapshot().GetDataMapping();
+     params.vm_snapshot_instructions =
+         vm_data_->GetVMSnapshot().GetInstructionsMapping();
+-    params.create_group = reinterpret_cast<decltype(params.create_group)>(
+-        DartIsolate::DartIsolateGroupCreateCallback);
+-    params.shutdown_isolate =
+-        reinterpret_cast<decltype(params.shutdown_isolate)>(
+-            DartIsolate::DartIsolateShutdownCallback);
+-    params.cleanup_group = reinterpret_cast<decltype(params.cleanup_group)>(
+-        DartIsolate::DartIsolateGroupCleanupCallback);
++    params.create = reinterpret_cast<decltype(params.create)>(
++        DartIsolate::DartIsolateCreateCallback);
++    params.shutdown = reinterpret_cast<decltype(params.shutdown)>(
++        DartIsolate::DartIsolateShutdownCallback);
++    params.cleanup = reinterpret_cast<decltype(params.cleanup)>(
++        DartIsolate::DartIsolateCleanupCallback);
+     params.thread_exit = ThreadExitCallback;
+     params.get_service_assets = GetVMServiceAssetsArchiveCallback;
+     params.entropy_source = dart::bin::GetEntropy;
+diff --git a/shell/platform/fuchsia/dart/dart_component_controller.cc b/shell/platform/fuchsia/dart/dart_component_controller.cc
+index c8e7cc5ab..1c4f71050 100644
+--- a/shell/platform/fuchsia/dart/dart_component_controller.cc
++++ b/shell/platform/fuchsia/dart/dart_component_controller.cc
+@@ -324,13 +324,12 @@ bool DartComponentController::CreateIsolate(
+   auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState(
+       namespace_fd, [this](Dart_Handle result) { MessageEpilogue(result); }));
+ 
+-  isolate_ = Dart_CreateIsolateGroup(
++  isolate_ = Dart_CreateIsolate(
+       url_.c_str(), label_.c_str(), isolate_snapshot_data,
+       isolate_snapshot_instructions, shared_snapshot_data,
+-      shared_snapshot_instructions, nullptr /* flags */,
+-      state /* isolate_group_data */, state /* isolate_data */, &error);
++      shared_snapshot_instructions, nullptr /* flags */, state, &error);
+   if (!isolate_) {
+-    FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", error);
++    FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", error);
+     return false;
+   }
+ 
+diff --git a/shell/platform/fuchsia/dart/dart_runner.cc b/shell/platform/fuchsia/dart/dart_runner.cc
+index b9ded3ac4..200500d2c 100644
+--- a/shell/platform/fuchsia/dart/dart_runner.cc
++++ b/shell/platform/fuchsia/dart/dart_runner.cc
+@@ -61,13 +61,13 @@ const char* kDartVMArgs[] = {
+     // clang-format on
+ };
+ 
+-Dart_Isolate IsolateGroupCreateCallback(const char* uri,
+-                                        const char* name,
+-                                        const char* package_root,
+-                                        const char* package_config,
+-                                        Dart_IsolateFlags* flags,
+-                                        void* callback_data,
+-                                        char** error) {
++Dart_Isolate IsolateCreateCallback(const char* uri,
++                                   const char* name,
++                                   const char* package_root,
++                                   const char* package_config,
++                                   Dart_IsolateFlags* flags,
++                                   void* callback_data,
++                                   char** error) {
+   if (std::string(uri) == DART_VM_SERVICE_ISOLATE_NAME) {
+ #if defined(DART_PRODUCT)
+     *error = strdup("The service isolate is not implemented in product mode");
+@@ -81,7 +81,7 @@ Dart_Isolate IsolateGroupCreateCallback(const char* uri,
+   return NULL;
+ }
+ 
+-void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
++void IsolateShutdownCallback(void* callback_data) {
+   // The service isolate (and maybe later the kernel isolate) doesn't have an
+   // async loop.
+   auto dispatcher = async_get_default_dispatcher();
+@@ -92,8 +92,8 @@ void IsolateShutdownCallback(void* isolate_group_data, void* isolate_data) {
+   }
+ }
+ 
+-void IsolateGroupCleanupCallback(void* isolate_group_data) {
+-  delete static_cast<std::shared_ptr<tonic::DartState>*>(isolate_group_data);
++void IsolateCleanupCallback(void* callback_data) {
++  delete static_cast<std::shared_ptr<tonic::DartState>*>(callback_data);
+ }
+ 
+ void RunApplication(
+@@ -167,9 +167,9 @@ DartRunner::DartRunner() : context_(sys::ComponentContext::Create()) {
+   params.vm_snapshot_data = vm_snapshot_data_.address();
+   params.vm_snapshot_instructions = vm_snapshot_instructions_.address();
+ #endif
+-  params.create_group = IsolateGroupCreateCallback;
+-  params.shutdown_isolate = IsolateShutdownCallback;
+-  params.cleanup_group = IsolateGroupCleanupCallback;
++  params.create = IsolateCreateCallback;
++  params.shutdown = IsolateShutdownCallback;
++  params.cleanup = IsolateCleanupCallback;
+   params.entropy_source = EntropySource;
+ #if !defined(DART_PRODUCT)
+   params.get_service_assets = GetVMServiceAssetsArchiveCallback;
+diff --git a/shell/platform/fuchsia/dart/service_isolate.cc b/shell/platform/fuchsia/dart/service_isolate.cc
+index 5287d638f..2e6eda265 100644
+--- a/shell/platform/fuchsia/dart/service_isolate.cc
++++ b/shell/platform/fuchsia/dart/service_isolate.cc
+@@ -123,14 +123,14 @@ Dart_Isolate CreateServiceIsolate(const char* uri,
+ #endif
+ 
+   auto state = new std::shared_ptr<tonic::DartState>(new tonic::DartState());
+-  Dart_Isolate isolate = Dart_CreateIsolateGroup(
++  Dart_Isolate isolate = Dart_CreateIsolate(
+       uri, DART_VM_SERVICE_ISOLATE_NAME, mapped_isolate_snapshot_data.address(),
+       mapped_isolate_snapshot_instructions.address(),
+       mapped_shared_snapshot_data.address(),
+-      mapped_shared_snapshot_instructions.address(), nullptr /* flags */,
+-      state /* isolate_group_data */, state /* isolate_data */, error);
++      mapped_shared_snapshot_instructions.address(), nullptr /* flags */, state,
++      error);
+   if (!isolate) {
+-    FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolateGroup failed: %s", *error);
++    FX_LOGF(ERROR, LOG_TAG, "Dart_CreateIsolate failed: %s", *error);
+     return nullptr;
+   }
+ 
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index 7bb4919..f8d3053 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -15,6 +15,7 @@
 
 scriptDir = os.path.dirname(os.path.realpath(__file__))
 outDir = os.path.join(scriptDir, '..', 'out', 'ReleaseX64')
+abiDir = os.path.join(outDir, 'dart-sdk', 'lib', '_internal', 'abiversions')
 
 
 # Info about a running test.
@@ -61,13 +62,19 @@
   return Test(cmd, resultFile, logFile, version)
 
 
+# Returns whether the dill files exist for an ABI version.
+def abiVersionExists(version):
+  return os.path.isdir(os.path.join(abiDir, str(version)))
+
+
 # Build tests for every supported version, and return a list of Test objects.
 def buildAllTests():
   abi_version = int(utils.GetAbiVersion())
   oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
   tests = [buildTest(None)]
   for version in xrange(oldest_abi_version, abi_version + 1):
-    tests.append(buildTest(version))
+    if abiVersionExists(version):
+      tests.append(buildTest(version))
   return tests
 
 
@@ -150,7 +157,6 @@
 def diffAllResults(tests):
   allResults = readAllTestFiles(tests, lambda test: test.resultFile)
   allLogs = readAllTestFiles(tests, lambda test: test.logFile)
-  anyDiff = False
   logDir = os.path.join(outDir, 'logs')
   makeDirs(logDir)
   resultFileName = os.path.join(logDir, 'results.json')
@@ -163,14 +169,13 @@
         if diffs:
           logRecords = allLogs[name] if name in allLogs else []
           logFile.write(json.dumps(makeLog(diffs, results, logRecords)) + '\n')
-          anyDiff = True
-  return anyDiff
 
 
 def main():
   tests = buildAllTests()
   runAllTests(tests)
-  return 1 if diffAllResults(tests) else 0
+  diffAllResults(tests)
+  return 0
 
 
 if __name__ == '__main__':
diff --git a/tools/test.dart b/tools/test.dart
index edb0f8c..4c181a0 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -261,6 +261,7 @@
   final request = await client.getUrl(requestUrl);
   final response = await request.close();
   final Map<String, dynamic> object = await response
+      .cast<List<int>>()
       .transform(new Utf8Decoder())
       .transform(new JsonDecoder())
       .first;
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 3ca1729..e8d91fc 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -250,11 +250,7 @@
     /// Build a map of uris to digests.
     final inputDigests = <Uri, List<int>>{};
     for (var input in inputs) {
-      var uri = Uri.parse(input.path);
-      if (uri.scheme.isEmpty) {
-        uri = Uri.parse('file://${input.path}');
-      }
-      inputDigests[uri] = input.digest;
+      inputDigests[_toUri(input.path)] = input.digest;
     }
 
     // TODO(sigmund): add support for experiments with the incremental compiler.
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index f40512c..07e8087 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("../../utils/compile_platform.gni")
-import("../../utils/generate_patch_sdk.gni")
 import("../create_timestamp.gni")
 import("../application_snapshot.gni")
 
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index e56bbfd..6069ad1 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -87,6 +87,7 @@
       "$abs_main",
       "-m",
       "-o$abs_output",
+      "--no-source-maps",
     ]
   }
 }
diff --git a/utils/generate_patch_sdk.gni b/utils/generate_patch_sdk.gni
deleted file mode 100644
index f947fb9..0000000
--- a/utils/generate_patch_sdk.gni
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (c) 2017, 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("../build/dart/dart_action.gni")
-
-_dart_root = get_path_info("..", "abspath")
-
-# Template to generate a patched_sdk folder.
-#
-# This template expects four arguments:
-#   - mode: vm or dart2js (whether to build an sdk for the vm or for dart2js)
-#   - input_patches_dir: directory containing the input library files.
-#   - patched_sdk_dir: the output location
-#   - deps: extra dependencies that must be built ahead of time.
-template("generate_patched_sdk") {
-  assert(defined(invoker.input_patches_dir),
-         "Need input_patches_dir in $target_name")
-  assert(defined(invoker.patched_sdk_dir),
-         "Need patched_sdk_dir in $target_name")
-  assert(defined(invoker.mode), "Need mode in $target_name")
-
-  prebuilt_dart_action(target_name) {
-    forward_variables_from(invoker, [
-      "deps",
-    ])
-
-    depfile = "$root_out_dir/${target_name}_patched_sdk.d"
-
-    script = "$_dart_root/tools/patch_sdk.dart"
-
-    if (defined(invoker.outputs)) {
-      outputs = invoker.outputs
-    } else {
-      outputs = [
-        # Instead of listing all outputs we list those consumed by
-        # other BUILD rules.
-        "$root_out_dir/${invoker.patched_sdk_dir}/platform.dill",
-        "$root_out_dir/${invoker.patched_sdk_dir}/outline.dill",
-      ]
-    }
-
-    args = [
-      invoker.mode,
-      rebase_path("$_dart_root/sdk"),
-      rebase_path(invoker.input_patches_dir),
-      rebase_path("$root_out_dir/${invoker.patched_sdk_dir}", root_build_dir),
-      rebase_path("$_dart_root/.packages"),
-    ]
-  }
-}