Version 2.12.0-259.0.dev

Merge commit 'ac520f984d8e1286250af5fa67630ef6e963fabc' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index eb075b1..3daa83f 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -354,8 +354,9 @@
     },
     {
       "name": "js_runtime",
-      "rootUri": "../sdk/lib/_internal/js_runtime",
-      "packageUri": "lib/"
+      "rootUri": "../pkg/js_runtime",
+      "packageUri": "lib/",
+      "languageVersion": "2.12"
     },
     {
       "name": "json_rpc_2",
diff --git a/.packages b/.packages
index d31bc9b..badd487 100644
--- a/.packages
+++ b/.packages
@@ -54,7 +54,7 @@
 intl:third_party/pkg/intl/lib
 js:pkg/js/lib
 js_ast:pkg/js_ast/lib
-js_runtime:sdk/lib/_internal/js_runtime/lib
+js_runtime:pkg/js_runtime/lib
 json_rpc_2:third_party/pkg/json_rpc_2/lib
 kernel:pkg/kernel/lib
 linter:third_party/pkg/linter/lib
diff --git a/DEPS b/DEPS
index 2c8fd54..00cb7f7 100644
--- a/DEPS
+++ b/DEPS
@@ -106,7 +106,7 @@
   "fixnum_rev": "16d3890c6dc82ca629659da1934e412292508bba",
   "file_rev": "0e09370f581ab6388d46fda4cdab66638c0171a1",
   "glob_rev": "7c0ef8d4fa086f6b185c4dd724b700e7d7ad8f79",
-  "html_rev": "137be8db5d5b7f00530fca1591292849ce6779c9",
+  "html_rev": "7f31979303f916f2aabb9e2091950798abdd9ca1",
   "http_io_rev": "2fa188caf7937e313026557713f7feffedd4978b",
   "http_multi_server_rev" : "e8c8be7f15b4fb50757ff5bf29766721fbe24fe4",
   "http_parser_rev": "5dd4d16693242049dfb43b5efa429fedbf932e98",
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 8b4b43a..717c136 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -14,6 +14,7 @@
 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/source/source_range.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -109,9 +110,6 @@
     if (_addIdentifierRegion_function(node)) {
       return;
     }
-    if (_addIdentifierRegion_functionTypeAlias(node)) {
-      return;
-    }
     if (_addIdentifierRegion_importPrefix(node)) {
       return;
     }
@@ -127,6 +125,9 @@
     if (_addIdentifierRegion_parameter(node)) {
       return;
     }
+    if (_addIdentifierRegion_typeAlias(node)) {
+      return;
+    }
     if (_addIdentifierRegion_typeParameter(node)) {
       return;
     }
@@ -268,14 +269,6 @@
     return _addRegion_node(node, type);
   }
 
-  bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) {
-    var element = node.writeOrReadElement;
-    if (element is! FunctionTypeAliasElement) {
-      return false;
-    }
-    return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS);
-  }
-
   bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) {
     // should be declaration
     var parent = node.parent;
@@ -385,6 +378,17 @@
     return _addRegion_node(node, type, semanticTokenModifiers: modifiers);
   }
 
+  bool _addIdentifierRegion_typeAlias(SimpleIdentifier node) {
+    var element = node.writeOrReadElement;
+    if (element is TypeAliasElement) {
+      var type = element.aliasedType is FunctionType
+          ? HighlightRegionType.FUNCTION_TYPE_ALIAS
+          : HighlightRegionType.TYPE_ALIAS;
+      return _addRegion_node(node, type);
+    }
+    return false;
+  }
+
   bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
     var element = node.writeOrReadElement;
     if (element is! TypeParameterElement) {
@@ -743,13 +747,14 @@
   @override
   void visitGenericFunctionType(GenericFunctionType node) {
     computer._addRegion_token(
-        node.functionKeyword, HighlightRegionType.KEYWORD);
+        node.functionKeyword, HighlightRegionType.BUILT_IN);
     super.visitGenericFunctionType(node);
   }
 
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
-    computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(
+        node.typedefKeyword, HighlightRegionType.BUILT_IN);
     super.visitGenericTypeAlias(node);
   }
 
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index e276893..3ac8da4 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -22,7 +22,7 @@
 
 @reflectiveTest
 class AnalysisNotificationHighlightsTest extends HighlightsTestSupport
-    with WithNullSafetyServerAnalysisMixin {
+    with WithNonFunctionTypeAliasesMixin {
   Future<void> test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
@@ -186,6 +186,18 @@
     assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
   }
 
+  Future<void> test_BUILT_IN_Function() async {
+    addTestFile('''
+typedef F = void Function();
+
+void f(void Function() a, Function b) {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'Function();');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'Function() a');
+    assertNoRegion(HighlightRegionType.BUILT_IN, 'Function b');
+  }
+
   Future<void> test_BUILT_IN_get() async {
     addTestFile('''
 get aaa => 1;
@@ -380,11 +392,15 @@
   Future<void> test_BUILT_IN_typedef() async {
     addTestFile('''
 typedef A();
+typedef B = void Function();
+typedef C = List<int>;
 main() {
   var typedef = 42;
 }''');
     await prepareHighlights();
     assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef B =');
+    assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef C =');
     assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
   }
 
@@ -583,13 +599,15 @@
 
   Future<void> test_FUNCTION_TYPE_ALIAS() async {
     addTestFile('''
-typedef FFF(p);
-main(FFF fff) {
-}
+typedef A();
+typedef B = void Function();
+void f(A a, B b) {}
 ''');
     await prepareHighlights();
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
-    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'A();');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'A a');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'B = ');
+    assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'B b');
   }
 
   Future<void> test_GETTER() async {
@@ -1111,6 +1129,26 @@
     assertHasRegion(HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE, 'V2 = 3');
   }
 
+  Future<void> test_TYPE_ALIAS_dynamicType() async {
+    addTestFile('''
+typedef A = dynamic;
+void f(A a) {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_ALIAS, 'A =');
+    assertHasRegion(HighlightRegionType.TYPE_ALIAS, 'A a');
+  }
+
+  Future<void> test_TYPE_ALIAS_interfaceType() async {
+    addTestFile('''
+typedef A = List<int>;
+void f(A a) {}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.TYPE_ALIAS, 'A =');
+    assertHasRegion(HighlightRegionType.TYPE_ALIAS, 'A a');
+  }
+
   Future<void> test_TYPE_NAME_DYNAMIC() async {
     addTestFile('''
 dynamic main() {
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index adb4cc3..5614cd3 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -228,7 +228,19 @@
   }
 }
 
-mixin WithNullSafetyServerAnalysisMixin on AbstractAnalysisTest {
+mixin WithNonFunctionTypeAliasesMixin on AbstractAnalysisTest {
+  @override
+  void createProject({Map<String, String> packageRoots}) {
+    addAnalysisOptionsFile('''
+analyzer:
+  enable-experiment:
+    - nonfunction-type-aliases
+''');
+    super.createProject(packageRoots: packageRoots);
+  }
+}
+
+mixin WithNullSafetyMixin on AbstractAnalysisTest {
   @override
   void createProject({Map<String, String> packageRoots}) {
     addAnalysisOptionsFile('''
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 6130688..2bee3dc 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -559,6 +559,8 @@
   HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT,
   HintCode.RECEIVER_OF_TYPE_NEVER,
   HintCode.RETURN_OF_DO_NOT_STORE,
+  HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR,
+  HintCode.RETURN_TYPE_INVALID_FOR_CATCH_ERROR,
   HintCode.SDK_VERSION_AS_EXPRESSION_IN_CONST_CONTEXT,
   HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE,
   HintCode.SDK_VERSION_BOOL_OPERATOR_IN_CONST_CONTEXT,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 3671aa9..c427645 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -1746,6 +1746,27 @@
       correction: "Annotate '{1}' with 'doNotStore'.");
 
   /**
+   * Parameters:
+   * 0: the return type as declared in the return statement
+   * 1: the expected return type as defined by the type of the Future
+   */
+  static const HintCode RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR = HintCode(
+    'RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR',
+    "A value of type '{0}' can't be returned by the 'onError' handler because "
+        "it must be assignable to '{1}'.",
+  );
+
+  /**
+   * Parameters:
+   * 0: the return type of the function
+   * 1: the expected return type as defined by the type of the Future
+   */
+  static const HintCode RETURN_TYPE_INVALID_FOR_CATCH_ERROR = HintCode(
+      'RETURN_TYPE_INVALID_FOR_CATCH_ERROR',
+      "The return type '{0}' isn't assignable to '{1}', as required by "
+          "'Future.catchError'.");
+
+  /**
    * No parameters.
    */
   // #### Description
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
index fc07690..38e717a 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_name_resolver.dart
@@ -144,12 +144,7 @@
   NullabilitySuffix _getNullability(TypeName node) {
     if (isNonNullableByDefault) {
       if (node.question != null) {
-        if (identical(node, classHierarchy_typeName)) {
-          _reportInvalidNullableType(node);
-          return NullabilitySuffix.none;
-        } else {
-          return NullabilitySuffix.question;
-        }
+        return NullabilitySuffix.question;
       } else {
         return NullabilitySuffix.none;
       }
@@ -275,33 +270,6 @@
     }
   }
 
-  /// Given a [typeName] that has a question mark, report an error and return
-  /// `true` if it appears in a location where a nullable type is not allowed.
-  void _reportInvalidNullableType(TypeName typeName) {
-    AstNode parent = typeName.parent;
-    if (parent is ExtendsClause || parent is ClassTypeAlias) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE,
-        typeName,
-      );
-    } else if (parent is ImplementsClause) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE,
-        typeName,
-      );
-    } else if (parent is OnClause) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE,
-        typeName,
-      );
-    } else if (parent is WithClause) {
-      errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE,
-        typeName,
-      );
-    }
-  }
-
   void _resolveToElement(TypeName node, Element element) {
     if (element == null) {
       node.type = dynamicType;
@@ -316,7 +284,9 @@
       return;
     }
 
-    node.type = _instantiateElement(node, element);
+    var type = _instantiateElement(node, element);
+    type = _verifyNullability(node, type);
+    node.type = type;
   }
 
   /// We parse `foo.bar` as `prefix.Name` with the expectation that `prefix`
@@ -367,6 +337,42 @@
     }
   }
 
+  /// If the [node] appears in a location where a nullable type is not allowed,
+  /// but the [type] is nullable (because the question mark was specified,
+  /// or the type alias is nullable), report an error, and return the
+  /// corresponding non-nullable type.
+  DartType _verifyNullability(TypeName node, DartType type) {
+    if (identical(node, classHierarchy_typeName)) {
+      if (type.nullabilitySuffix == NullabilitySuffix.question) {
+        var parent = node.parent;
+        if (parent is ExtendsClause || parent is ClassTypeAlias) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE,
+            node,
+          );
+        } else if (parent is ImplementsClause) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE,
+            node,
+          );
+        } else if (parent is OnClause) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE,
+            node,
+          );
+        } else if (parent is WithClause) {
+          errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE,
+            node,
+          );
+        }
+        return (type as TypeImpl).withNullability(NullabilitySuffix.none);
+      }
+    }
+
+    return type;
+  }
+
   DartType _verifyTypeAliasForContext(
     TypeName node,
     TypeAliasElement element,
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 4085b7a..cbb6ab5 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -23,6 +23,7 @@
 import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
 import 'package:analyzer/src/dart/resolver/exit_detector.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/error/catch_error_verifier.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/deprecated_member_use_verifier.dart';
 import 'package:analyzer/src/error/must_call_super_verifier.dart';
@@ -72,6 +73,8 @@
 
   final MustCallSuperVerifier _mustCallSuperVerifier;
 
+  final CatchErrorVerifier _catchErrorVerifier;
+
   /// The [WorkspacePackage] in which [_currentLibrary] is declared.
   final WorkspacePackage _workspacePackage;
 
@@ -109,6 +112,8 @@
         _deprecatedVerifier =
             DeprecatedMemberUseVerifier(workspacePackage, _errorReporter),
         _mustCallSuperVerifier = MustCallSuperVerifier(_errorReporter),
+        _catchErrorVerifier =
+            CatchErrorVerifier(_errorReporter, typeProvider, typeSystem),
         _workspacePackage = workspacePackage {
     _deprecatedVerifier.pushInDeprecatedValue(_currentLibrary.hasDeprecated);
     _inDoNotStoreMember = _currentLibrary.hasDoNotStore;
@@ -588,6 +593,7 @@
   void visitMethodInvocation(MethodInvocation node) {
     _deprecatedVerifier.methodInvocation(node);
     _checkForNullAwareHints(node, node.operator);
+    _catchErrorVerifier.verifyMethodInvocation(node);
     super.visitMethodInvocation(node);
   }
 
diff --git a/pkg/analyzer/lib/src/error/catch_error_verifier.dart b/pkg/analyzer/lib/src/error/catch_error_verifier.dart
new file mode 100644
index 0000000..a9fa26d
--- /dev/null
+++ b/pkg/analyzer/lib/src/error/catch_error_verifier.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2021, 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/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/error/return_type_verifier.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+
+/// Reports on invalid functions passed to [Future.catchError].
+class CatchErrorVerifier {
+  final ErrorReporter _errorReporter;
+
+  final TypeProvider _typeProvider;
+
+  final TypeSystem _typeSystem;
+
+  final ReturnTypeVerifier _returnTypeVerifier;
+
+  CatchErrorVerifier(this._errorReporter, this._typeProvider, this._typeSystem)
+      : _returnTypeVerifier = ReturnTypeVerifier(
+          typeProvider: _typeProvider,
+          typeSystem: _typeSystem,
+          errorReporter: _errorReporter,
+        );
+  void verifyMethodInvocation(MethodInvocation node) {
+    // TODO(https://github.com/dart-lang/sdk/issues/35825): Verify the
+    // parameters of a function passed to `Future.catchError` as well.
+    var target = node.realTarget;
+    if (target == null) {
+      return;
+    }
+    var methodName = node.methodName;
+    if (!(methodName.name == 'catchError' &&
+        target.staticType.isDartAsyncFuture)) {
+      return;
+    }
+    if (node.argumentList.arguments.isEmpty) {
+      return;
+    }
+    var callback = node.argumentList.arguments.first;
+    if (callback is NamedExpression) {
+      // This implies that no positional arguments are passed.
+      return;
+    }
+    var targetType = target.staticType as InterfaceType;
+    var targetFutureType = targetType.typeArguments.first;
+    var expectedReturnType = _typeProvider.futureOrType2(targetFutureType);
+    if (callback is FunctionExpression) {
+      var catchErrorOnErrorExecutable = EnclosingExecutableContext(
+          callback.declaredElement,
+          isAsynchronous: true,
+          catchErrorOnErrorReturnType: expectedReturnType);
+      var returnStatementVerifier =
+          _ReturnStatementVerifier(_returnTypeVerifier);
+      _returnTypeVerifier.enclosingExecutable = catchErrorOnErrorExecutable;
+      callback.body.accept(returnStatementVerifier);
+    } else {
+      var callbackType = callback.staticType;
+      if (callbackType is FunctionType) {
+        _checkReturnType(expectedReturnType, callbackType.returnType, callback);
+      }
+    }
+  }
+
+  void _checkReturnType(
+      DartType expectedType, DartType functionReturnType, Expression callback) {
+    if (!_typeSystem.isAssignableTo(functionReturnType, expectedType)) {
+      _errorReporter.reportErrorForNode(
+        HintCode.RETURN_TYPE_INVALID_FOR_CATCH_ERROR,
+        callback,
+        [functionReturnType, expectedType],
+      );
+    }
+  }
+}
+
+/// Visits a function body, looking for return statements.
+class _ReturnStatementVerifier extends RecursiveAstVisitor<void> {
+  final ReturnTypeVerifier _returnTypeVerifier;
+  _ReturnStatementVerifier(this._returnTypeVerifier);
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _returnTypeVerifier.verifyExpressionFunctionBody(node);
+    super.visitExpressionFunctionBody(node);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // Do not visit within [node]. We have no interest in return statements
+    // within.
+  }
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    _returnTypeVerifier.verifyReturnStatement(node);
+    super.visitReturnStatement(node);
+  }
+}
diff --git a/pkg/analyzer/lib/src/error/return_type_verifier.dart b/pkg/analyzer/lib/src/error/return_type_verifier.dart
index af65202..ce9f2eb 100644
--- a/pkg/analyzer/lib/src/error/return_type_verifier.dart
+++ b/pkg/analyzer/lib/src/error/return_type_verifier.dart
@@ -155,7 +155,13 @@
     var S = expression.staticType;
 
     void reportTypeError() {
-      if (enclosingExecutable.isClosure) {
+      if (enclosingExecutable.catchErrorOnErrorReturnType != null) {
+        _errorReporter.reportErrorForNode(
+          HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR,
+          expression,
+          [S, T],
+        );
+      } else if (enclosingExecutable.isClosure) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
           expression,
@@ -256,7 +262,13 @@
     var S = expression.staticType;
 
     void reportTypeError() {
-      if (enclosingExecutable.isClosure) {
+      if (enclosingExecutable.catchErrorOnErrorReturnType != null) {
+        _errorReporter.reportErrorForNode(
+          HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR,
+          expression,
+          [S, T],
+        );
+      } else if (enclosingExecutable.isClosure) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_CLOSURE,
           expression,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e54f009..b275202 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -53,6 +53,12 @@
   final bool inFactoryConstructor;
   final bool inStaticMethod;
 
+  /// If this [EnclosingExecutableContext] is the first argument in a method
+  /// invocation of [Future.catchError], returns the return type expected for
+  /// `Future<T>.catchError`'s `onError` parameter, which is `FutureOr<T>`,
+  /// otherwise `null`.
+  final InterfaceType catchErrorOnErrorReturnType;
+
   /// The return statements that have a value.
   final List<ReturnStatement> _returnsWith = [];
 
@@ -63,8 +69,10 @@
   /// for the kind of the function body, e.g. not `Future` for `async`.
   bool hasLegalReturnType = true;
 
-  EnclosingExecutableContext(this.element)
-      : isAsynchronous = element != null && element.isAsynchronous,
+  EnclosingExecutableContext(this.element,
+      {bool isAsynchronous, this.catchErrorOnErrorReturnType})
+      : isAsynchronous =
+            isAsynchronous ?? (element != null && element.isAsynchronous),
         isConstConstructor = element is ConstructorElement && element.isConst,
         isGenerativeConstructor =
             element is ConstructorElement && !element.isFactory,
@@ -104,7 +112,7 @@
 
   bool get isSynchronous => !isAsynchronous;
 
-  DartType get returnType => element.returnType;
+  DartType get returnType => catchErrorOnErrorReturnType ?? element.returnType;
 
   static bool _inFactoryConstructor(ExecutableElement element) {
     if (element is ConstructorElement) {
@@ -747,12 +755,12 @@
   void visitFunctionExpression(FunctionExpression node) {
     _isInLateLocalVariable.add(false);
 
-    if (node.parent is! FunctionDeclaration) {
+    if (node.parent is FunctionDeclaration) {
+      super.visitFunctionExpression(node);
+    } else {
       _withEnclosingExecutable(node.declaredElement, () {
         super.visitFunctionExpression(node);
       });
-    } else {
-      super.visitFunctionExpression(node);
     }
 
     _isInLateLocalVariable.removeLast();
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 88fe551..36be56b 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -43,6 +43,8 @@
     throw 0;
   }
 
+  Future<T> catchError(Function onError, {bool test(Object error)});
+
   Future<R> then<R>(FutureOr<R> onValue(T value));
 
   Future<T> whenComplete(action());
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart
index ccdffe5..aab024e 100644
--- a/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_extends_clause_test.dart
@@ -15,7 +15,7 @@
 
 @reflectiveTest
 class NullableTypeInExtendsClauseTest extends PubPackageResolutionTest
-    with WithNullSafetyMixin {
+    with WithNonFunctionTypeAliasesMixin {
   test_class_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -32,6 +32,26 @@
     ]);
   }
 
+  test_class_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A;
+class C extends B? {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 42, 2),
+    ]);
+  }
+
+  test_class_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A?;
+class C extends B {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 43, 1),
+    ]);
+  }
+
   test_classAlias_withClass_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -50,6 +70,28 @@
     ]);
   }
 
+  test_classAlias_withClass_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+typedef C = A;
+class D = C? with B;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 47, 2),
+    ]);
+  }
+
+  test_classAlias_withClass_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+typedef C = A?;
+class D = C with B;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 48, 1),
+    ]);
+  }
+
   test_classAlias_withMixin_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -67,4 +109,26 @@
       error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 32, 2),
     ]);
   }
+
+  test_classAlias_withMixin_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+mixin B {}
+typedef C = A;
+class D = C? with B;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 47, 2),
+    ]);
+  }
+
+  test_classAlias_withMixin_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+mixin B {}
+typedef C = A?;
+class D = C with B;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_EXTENDS_CLAUSE, 48, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart
index 9e9d5a8..2238940 100644
--- a/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_implements_clause_test.dart
@@ -15,7 +15,7 @@
 
 @reflectiveTest
 class NullableTypeInImplementsClauseTest extends PubPackageResolutionTest
-    with WithNullSafetyMixin {
+    with WithNonFunctionTypeAliasesMixin {
   test_class_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -32,6 +32,26 @@
     ]);
   }
 
+  test_class_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A;
+class C implements B? {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, 45, 2),
+    ]);
+  }
+
+  test_class_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A?;
+class C implements B {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, 46, 1),
+    ]);
+  }
+
   test_mixin_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -47,4 +67,24 @@
       error(CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, 30, 2),
     ]);
   }
+
+  test_mixin_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A;
+mixin C implements B? {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, 45, 2),
+    ]);
+  }
+
+  test_mixin_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A?;
+mixin C implements B {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS_CLAUSE, 46, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart
index 98a243c..d987fba 100644
--- a/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_on_clause_test.dart
@@ -15,7 +15,7 @@
 
 @reflectiveTest
 class NullableTypeInOnClauseTest extends PubPackageResolutionTest
-    with WithNullSafetyMixin {
+    with WithNonFunctionTypeAliasesMixin {
   test_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -31,4 +31,24 @@
       error(CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE, 22, 2),
     ]);
   }
+
+  test_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A;
+mixin C on B? {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE, 37, 2),
+    ]);
+  }
+
+  test_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A?;
+mixin C on B {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_ON_CLAUSE, 38, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart b/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart
index ba235ef..ea7d118 100644
--- a/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/nullable_type_in_with_clause_test.dart
@@ -15,7 +15,7 @@
 
 @reflectiveTest
 class NullableTypeInWithClauseTest extends PubPackageResolutionTest
-    with WithNullSafetyMixin {
+    with WithNonFunctionTypeAliasesMixin {
   test_class_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -32,6 +32,26 @@
     ]);
   }
 
+  test_class_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A;
+class C with B? {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 39, 2),
+    ]);
+  }
+
+  test_class_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+typedef B = A?;
+class C with B {}
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 40, 1),
+    ]);
+  }
+
   test_classAlias_withClass_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -50,6 +70,28 @@
     ]);
   }
 
+  test_classAlias_withClass_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+typedef C = B;
+class D = A with C?;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 54, 2),
+    ]);
+  }
+
+  test_classAlias_withClass_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+class B {}
+typedef C = B?;
+class D = A with C;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 55, 1),
+    ]);
+  }
+
   test_classAlias_withMixin_nonNullable() async {
     await assertNoErrorsInCode('''
 class A {}
@@ -67,4 +109,26 @@
       error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 39, 2),
     ]);
   }
+
+  test_classAlias_withMixin_nullable_alias() async {
+    await assertErrorsInCode('''
+class A {}
+mixin B {}
+typedef C = B;
+class D = A with C?;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 54, 2),
+    ]);
+  }
+
+  test_classAlias_withMixin_nullable_alias2() async {
+    await assertErrorsInCode('''
+class A {}
+mixin B {}
+typedef C = B?;
+class D = A with C;
+''', [
+      error(CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE, 55, 1),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_from_catch_error_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_from_catch_error_test.dart
new file mode 100644
index 0000000..51b7617
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_from_catch_error_test.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2021, 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/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReturnOfInvalidTypeForCatchErrorTest);
+    defineReflectiveTests(ReturnOfInvalidTypeForCatchErrorWithNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class ReturnOfInvalidTypeForCatchErrorTest extends PubPackageResolutionTest {
+  test_async_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) async => 0);
+}
+''');
+  }
+
+  test_blockFunctionBody_async_emptyReturn_nonVoid() async {
+    await assertErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) async {
+    return;
+  });
+}
+''', [
+      error(CompileTimeErrorCode.RETURN_WITHOUT_VALUE, 69, 6),
+    ]);
+  }
+
+  test_blockFunctionBody_async_emptyReturn_void() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future) {
+  future.catchError((e, st) async {
+    return;
+  });
+}
+''');
+  }
+
+  test_blockFunctionBody_emptyReturn_dynamic() async {
+    await assertNoErrorsInCode('''
+void f(Future<dynamic> future) {
+  future.catchError((e, st) {
+    return;
+  });
+}
+''');
+  }
+
+  test_blockFunctionBody_emptyReturn_nonVoid() async {
+    await assertErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) {
+    return;
+  });
+}
+''', [
+      error(CompileTimeErrorCode.RETURN_WITHOUT_VALUE, 63, 6),
+    ]);
+  }
+
+  test_blockFunctionBody_emptyReturn_void() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future) {
+  future.catchError((e, st) {
+    return;
+  });
+}
+''');
+  }
+
+  test_blockFunctionBody_invalidReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) {
+    if (1 == 2) {
+      return 7;
+    } else {
+      return 0.5;
+    }
+  });
+}
+''', [
+      error(HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR, 119, 3),
+    ]);
+  }
+
+  test_blockFunctionBody_withLocalFunction_expression_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) {
+    double g() => 0.5;
+    if (g() == 0.5) return 0;
+    return 1;
+  });
+}
+''');
+  }
+
+  test_blockFunctionBody_withLocalFunction_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) {
+    double g() {
+      return 0.5;
+    }
+    if (g() == 0.5) return 0;
+    return 1;
+  });
+}
+''');
+  }
+
+  test_expressionFunctionBody_invalidReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) => 'c');
+}
+''', [
+      error(HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR, 60, 3),
+    ]);
+  }
+
+  test_Null_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<Null> future) {
+  future.catchError((e, st) => null);
+}
+''');
+  }
+
+  test_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future) {
+  future.catchError((e, st) => 0);
+}
+''');
+  }
+
+  test_void_okReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future) {
+  future.catchError((e, st) => 0);
+}
+''');
+  }
+
+  test_voidReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int> future, void Function() g) {
+  future.catchError((e, st) => g());
+}
+''', [
+      error(HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR, 79, 3),
+    ]);
+  }
+}
+
+@reflectiveTest
+class ReturnOfInvalidTypeForCatchErrorWithNullSafetyTest
+    extends ReturnOfInvalidTypeForCatchErrorTest with WithNullSafetyMixin {
+  test_nullableType_emptyBody() async {
+    await assertNoErrorsInCode('''
+void f(Future<int?> future) {
+  future.catchError((e, st) {});
+}
+''');
+  }
+
+  test_nullableType_emptyReturn() async {
+    await assertErrorsInCode('''
+void f(Future<int?> future) {
+  future.catchError((e, st) {
+    return;
+  });
+}
+''', [
+      error(CompileTimeErrorCode.RETURN_WITHOUT_VALUE, 64, 6),
+    ]);
+  }
+
+  test_nullableType_invalidReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int?> future) {
+  future.catchError((e, st) => '');
+}
+''', [
+      error(HintCode.RETURN_OF_INVALID_TYPE_FROM_CATCH_ERROR, 61, 2),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/return_type_invalid_for_catch_error_test.dart b/pkg/analyzer/test/src/diagnostics/return_type_invalid_for_catch_error_test.dart
new file mode 100644
index 0000000..ddd5ed2
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/return_type_invalid_for_catch_error_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2021, 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/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReturnTypeInvalidForCatchErrorTest);
+    defineReflectiveTests(ReturnTypeInvalidForCatchErrorWithNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class ReturnTypeInvalidForCatchErrorTest extends PubPackageResolutionTest {
+  test_dynamic_returnTypeIsUnrelatedFuture() async {
+    await assertNoErrorsInCode('''
+void f(
+    Future<dynamic> future, Future<String> Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_dynamic_unrelatedReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<dynamic> future, String Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_invalidReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int> future, String Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''', [
+      error(HintCode.RETURN_TYPE_INVALID_FOR_CATCH_ERROR, 90, 2),
+    ]);
+  }
+
+  test_returnTypeIsFuture() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future, Future<int> Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_returnTypeIsFutureOr() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+void f(Future<int> future, FutureOr<int> Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_sameReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<int> future, int Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_void_returnTypeIsUnrelatedFuture() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future, Future<String> Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+
+  test_void_unrelatedReturnType() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future, String Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''');
+  }
+}
+
+@reflectiveTest
+class ReturnTypeInvalidForCatchErrorWithNullSafetyTest
+    extends ReturnTypeInvalidForCatchErrorTest with WithNullSafetyMixin {
+  test_nullableReturnType() async {
+    await assertErrorsInCode('''
+void f(Future<int> future, String? Function(dynamic, StackTrace) cb) {
+  future.catchError(cb);
+}
+''', [
+      error(HintCode.RETURN_TYPE_INVALID_FOR_CATCH_ERROR, 91, 2),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/return_without_value_test.dart b/pkg/analyzer/test/src/diagnostics/return_without_value_test.dart
index 6d33a0d..9a31d66 100644
--- a/pkg/analyzer/test/src/diagnostics/return_without_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_without_value_test.dart
@@ -36,6 +36,16 @@
     ]);
   }
 
+  test_catchError_futureOfVoid() async {
+    await assertNoErrorsInCode('''
+void f(Future<void> future) {
+  future.catchError((e) {
+    return;
+  });
+}
+''');
+  }
+
   test_factoryConstructor() async {
     await assertErrorsInCode('''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 58ee594..6d808e0 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -536,7 +536,11 @@
     as return_in_generative_constructor;
 import 'return_in_generator_test.dart' as return_in_generator;
 import 'return_of_do_not_store_test.dart' as return_of_do_not_store;
+import 'return_of_invalid_type_from_catch_error_test.dart'
+    as return_of_invalid_type_from_catch_error;
 import 'return_of_invalid_type_test.dart' as return_of_invalid_type;
+import 'return_type_invalid_for_catch_error_test.dart'
+    as return_type_invalid_for_catch_error;
 import 'return_without_value_test.dart' as return_without_value;
 import 'sdk_version_as_expression_in_const_context_test.dart'
     as sdk_version_as_expression_in_const_context;
@@ -1012,7 +1016,9 @@
     return_in_generative_constructor.main();
     return_in_generator.main();
     return_of_do_not_store.main();
+    return_of_invalid_type_from_catch_error.main();
     return_of_invalid_type.main();
+    return_type_invalid_for_catch_error.main();
     return_without_value.main();
     set_element_from_deferred_library.main();
     sdk_version_as_expression_in_const_context.main();
diff --git a/pkg/analyzer_plugin/doc/tutorial/assists.md b/pkg/analyzer_plugin/doc/tutorial/assists.md
index dd38b78..2be0e4d 100644
--- a/pkg/analyzer_plugin/doc/tutorial/assists.md
+++ b/pkg/analyzer_plugin/doc/tutorial/assists.md
@@ -102,7 +102,7 @@
   // ...
 
   @override
-  List<AssistContributor> getAssistContributors(AnalysisDriver driver) {
+  List<AssistContributor> getAssistContributors(String path) {
     return <AssistContributor>[MyAssistContributor()];
   }
 }
diff --git a/pkg/analyzer_plugin/doc/tutorial/fixes.md b/pkg/analyzer_plugin/doc/tutorial/fixes.md
index efe2537..b77e517 100644
--- a/pkg/analyzer_plugin/doc/tutorial/fixes.md
+++ b/pkg/analyzer_plugin/doc/tutorial/fixes.md
@@ -117,8 +117,7 @@
   // ...
 
   @override
-  List<FixContributor> getFixContributors(
-      AnalysisDriverGeneric driver) {
+  List<FixContributor> getFixContributors(String path) {
     return <FixContributor>[MyFixContributor()];
   }
 }
diff --git a/pkg/analyzer_plugin/doc/tutorial/package_structure.md b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
index 1963892..c2443ec 100644
--- a/pkg/analyzer_plugin/doc/tutorial/package_structure.md
+++ b/pkg/analyzer_plugin/doc/tutorial/package_structure.md
@@ -56,7 +56,7 @@
 
 If a listed host package can be found (via the `.packages` file associated with
 the target package), then the tool looks in the host package for the folder
-`<host_package>/tools/analysis_plugin`. If that directory exists and contains a
+`<host_package>/tools/analyzer_plugin`. If that directory exists and contains a
 valid bootstrap package, then the bootstrap package is run as a plugin.
 
 ## Bootstrap Package Structure
diff --git a/pkg/analyzer_plugin/lib/plugin/plugin.dart b/pkg/analyzer_plugin/lib/plugin/plugin.dart
index 9759368..cdf8829 100644
--- a/pkg/analyzer_plugin/lib/plugin/plugin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/plugin.dart
@@ -95,7 +95,8 @@
   /// Return the SDK manager used to manage SDKs.
   DartSdkManager get sdkManager => _sdkManager;
 
-  /// Return the version number of this plugin, encoded as a string.
+  /// Return the version number of the plugin spec required by this plugin,
+  /// encoded as a string.
   String get version;
 
   /// Handle the fact that the file with the given [path] has been modified.
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 8a61bf9..0f826c1 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -26,7 +26,7 @@
   js_ast:
     path: ../js_ast
   js_runtime:
-    path: ../../sdk/lib/_internal/js_runtime
+    path: ../js_runtime
 
 dev_dependencies:
   # Published packages - repo version ensured via dependency_overrides
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index f3f6e63..021db07 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -157,7 +157,16 @@
         commonOptions['outputFile'].flag,
         help: commonOptions['outputFile'].help,
         abbr: commonOptions['outputFile'].abbr,
+      )
+      ..addOption(
+        commonOptions['verbosity'].flag,
+        help: commonOptions['verbosity'].help,
+        abbr: commonOptions['verbosity'].abbr,
+        defaultsTo: commonOptions['verbosity'].defaultsTo,
+        allowed: commonOptions['verbosity'].allowed,
+        allowedHelp: commonOptions['verbosity'].allowedHelp,
       );
+
     addExperimentalFlags(argParser, verbose);
   }
 
@@ -189,6 +198,10 @@
     List<String> args = [];
     args.add('--snapshot-kind=$formatName');
     args.add('--snapshot=${path.canonicalize(outputFile)}');
+
+    String verbosity = argResults[commonOptions['verbosity'].flag];
+    args.add('--verbosity=$verbosity');
+
     if (enabledExperiments.isNotEmpty) {
       args.add("--enable-experiment=${enabledExperiments.join(',')}");
     }
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 80ca891..2825b49 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -8,6 +8,8 @@
 import 'dart:io';
 
 import 'package:args/args.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show Verbosity;
 import 'package:path/path.dart';
 import 'package:pub/pub.dart';
 
@@ -91,6 +93,13 @@
       ..addFlag(
         'enable-asserts',
         help: 'Enable assert statements.',
+      )
+      ..addOption(
+        'verbosity',
+        help: 'Sets the verbosity level of the compilation.',
+        defaultsTo: Verbosity.defaultValue,
+        allowed: Verbosity.allowedValues,
+        allowedHelp: Verbosity.allowedValuesHelp,
       );
 
     if (verbose) {
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 5aaf14c..61ebc76 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -236,7 +236,7 @@
         reason: 'File not found: $outFile');
   });
 
-  test('Compile exe with warning', () {
+  test('Compile exe with warnings', () {
     final p = project(mainSrc: '''
 void main() {
   int i = 0;
@@ -334,6 +334,33 @@
         reason: 'File not found: $outFile');
   });
 
+  test('Compile exe without warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+  int i = 0;
+  i?.isEven;
+}
+''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'exe',
+        '--verbosity=error',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
   test('Compile JS with sound null safety', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -405,6 +432,33 @@
         reason: 'File not found: $outFile');
   });
 
+  test('Compile JS without warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+  int i = 0;
+  i?.isEven;
+}
+''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'js',
+        '--verbosity=error',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
   test('Compile AOT snapshot with sound null safety', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -476,6 +530,61 @@
         reason: 'File not found: $outFile');
   });
 
+  test('Compile AOT snapshot without warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+  int i = 0;
+  i?.isEven;
+}
+''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'aot-snapshot',
+        '--verbosity=error',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
+  test('Compile AOT snapshot with warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+  int i = 0;
+  i?.isEven;
+}
+''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'aot-snapshot',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stdout, contains('Warning: '));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
   test('Compile kernel with sound null safety', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -523,6 +632,82 @@
         reason: 'File not found: $outFile');
   });
 
+  test('Compile kernel without info', () {
+    final p = project(mainSrc: '''void main() {}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'kernel',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
+  });
+
+  test('Compile kernel without warning', () {
+    final p = project(mainSrc: '''
+void main() {
+    int i;
+    i?.isEven;
+}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'kernel',
+        '--verbosity=error',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, contains('must be assigned before it can be used'));
+    expect(result.exitCode, 254);
+  });
+
+  test('Compile kernel with warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+    int i = 0;
+    i?.isEven;
+}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'mydill'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'kernel',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, contains('Warning:'));
+    expect(result.exitCode, 0);
+  });
+
   test('Compile JIT snapshot with sound null safety', () {
     final p = project(mainSrc: '''void main() {}''');
     final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -569,4 +754,80 @@
     expect(File(outFile).existsSync(), true,
         reason: 'File not found: $outFile');
   });
+
+  test('Compile JIT snapshot without info', () {
+    final p = project(mainSrc: '''void main() {}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'jit-snapshot',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+    expect(File(outFile).existsSync(), true,
+        reason: 'File not found: $outFile');
+  });
+
+  test('Compile JIT snapshot without warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+    int i;
+    i?.isEven;
+}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'jit-snapshot',
+        '--verbosity=error',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, contains('must be assigned before it can be used'));
+    expect(result.exitCode, 254);
+  });
+
+  test('Compile JIT snapshot with warnings', () {
+    final p = project(mainSrc: '''
+void main() {
+    int i = 0;
+    i?.isEven;
+}''');
+    final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+    final outFile = path.canonicalize(path.join(p.dirPath, 'myjit'));
+
+    var result = p.runSync(
+      [
+        'compile',
+        'jit-snapshot',
+        '--verbosity=warning',
+        '-o',
+        outFile,
+        inFile,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, contains('Warning:'));
+    expect(result.exitCode, 0);
+  });
 }
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index 59bffba..12c07d3 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -9,6 +9,8 @@
 
 import '../utils.dart';
 
+const String soundNullSafetyMessage = 'Info: Compiling with sound null safety';
+
 void main() {
   group('run', run, timeout: longTimeout);
 }
@@ -279,4 +281,21 @@
     expect(result.stderr, isEmpty);
     expect(result.exitCode, 0);
   });
+
+  test('without verbose CFE info', () {
+    final p = project(mainSrc: '''void main() {}''');
+
+    var result = p.runSync(
+      [
+        'run',
+        '--verbosity=warning',
+        p.relativeFilePath,
+      ],
+    );
+
+    expect(result.stdout,
+        predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
 }
diff --git a/pkg/js_runtime/README.md b/pkg/js_runtime/README.md
new file mode 100644
index 0000000..5f60952
--- /dev/null
+++ b/pkg/js_runtime/README.md
@@ -0,0 +1,9 @@
+# Package `js_runtime`:
+
+This package contains code that is shared between the dart2js compiler and the
+dart2js runtime libraries.
+
+*Important*: all code under the `lib/shared/` must be kept in sync with the
+runtime at all times (in `sdk/lib/_internal/js_runtime/lib/shared`). The
+`test/in_sync_test.dart` test verifies this.
+
diff --git a/pkg/js_runtime/lib/shared/async_await_error_codes.dart b/pkg/js_runtime/lib/shared/async_await_error_codes.dart
new file mode 100644
index 0000000..f87406b
--- /dev/null
+++ b/pkg/js_runtime/lib/shared/async_await_error_codes.dart
@@ -0,0 +1,10 @@
+// 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.
+
+/// Contains error codes that transformed async/async* functions use to
+/// communicate with js_helper functions.
+
+const int SUCCESS = 0;
+const int ERROR = 1;
+const int STREAM_WAS_CANCELED = 2;
diff --git a/pkg/js_runtime/lib/shared/embedded_names.dart b/pkg/js_runtime/lib/shared/embedded_names.dart
new file mode 100644
index 0000000..e80fb6a
--- /dev/null
+++ b/pkg/js_runtime/lib/shared/embedded_names.dart
@@ -0,0 +1,281 @@
+// 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.
+
+/// Contains the names of globals that are embedded into the output by the
+/// compiler.
+///
+/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from
+/// the `_foreign_helper` library.
+///
+/// This library is shared between the compiler and the runtime system.
+library dart2js._embedded_names;
+
+/// The name of the property that is used to find the native superclass of
+/// an extended class.
+///
+/// Every class that extends a native class has this property set on its
+/// native class.
+const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag";
+
+/// The name of the static-function property name.
+///
+/// This property is set for all tear-offs of static functions, and provides
+/// the static function's unique (potentially minified) name.
+const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name';
+
+/// The name of a property on the constructor function of Dart Object
+/// and interceptor types, used for caching Rti types.
+const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache';
+
+/// The name of the embedded global for metadata.
+///
+/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded
+/// global.
+const METADATA = 'metadata';
+
+/// A list of types used in the program e.g. for reflection or encoding of
+/// function types.
+///
+/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
+const TYPES = 'types';
+
+/// Returns a function that maps a name of a class to its type.
+///
+/// This embedded global is used by the runtime when computing the internal
+/// runtime-type-information (rti) object.
+const GET_TYPE_FROM_NAME = 'getTypeFromName';
+
+/// A JS map from mangled global names to their unmangled names.
+///
+/// If the program does not use reflection, this embedded global may be empty
+/// (but not null or undefined).
+const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames';
+
+/// A JS map from mangled instance names to their unmangled names.
+///
+/// This embedded global is mainly used for reflection, but is also used to
+/// map const-symbols (`const Symbol('x')`) to the mangled instance names.
+///
+/// This embedded global may be empty (but not null or undefined).
+const MANGLED_NAMES = 'mangledNames';
+
+/// A JS map from dispatch tags (usually constructor names of DOM classes) to
+/// interceptor class. This map is used to find the correct interceptor for
+/// native classes.
+///
+/// This embedded global is used for natives.
+const INTERCEPTORS_BY_TAG = 'interceptorsByTag';
+
+/// A JS map from dispatch tags (usually constructor names of DOM classes) to
+/// booleans. Every tag entry of [INTERCEPTORS_BY_TAG] has a corresponding
+/// entry in the leaf-tags map.
+///
+/// A tag-entry is true, when a class can be treated as leaf class in the
+/// hierarchy. That is, even though it might have subclasses, all subclasses
+/// have the same code for the used methods.
+///
+/// This embedded global is used for natives.
+const LEAF_TAGS = 'leafTags';
+
+/// A JS function that returns the isolate tag for a given name.
+///
+/// This function uses the [ISOLATE_TAG] (below) to construct a name that is
+/// unique per isolate.
+///
+/// This embedded global is used for natives.
+// TODO(floitsch): should we rename this variable to avoid confusion with
+//    [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
+const GET_ISOLATE_TAG = 'getIsolateTag';
+
+/// A string that is different for each running isolate.
+///
+/// When this embedded global is initialized a global variable is used to
+/// ensure that no other running isolate uses the same isolate-tag string.
+///
+/// This embedded global is used for natives.
+// TODO(floitsch): should we rename this variable to avoid confusion with
+//    [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
+const ISOLATE_TAG = 'isolateTag';
+
+/// An embedded global that contains the property used to store type information
+/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
+/// is a String).
+const ARRAY_RTI_PROPERTY = 'arrayRti';
+
+/// This embedded global (a function) returns the isolate-specific dispatch-tag
+/// that is used to accelerate interceptor calls.
+const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
+
+/// An embedded global that maps a [Type] to the [Interceptor] and constructors
+/// for that type.
+///
+/// More documentation can be found in the interceptors library (close to its
+/// use).
+const TYPE_TO_INTERCEPTOR_MAP = "typeToInterceptorMap";
+
+/// The current script's URI when the program was loaded.
+///
+/// This embedded global is set at startup, just before invoking `main`.
+const CURRENT_SCRIPT = 'currentScript';
+
+/// Contains a map from load-ids to lists of part indexes.
+///
+/// To load the deferred library that is represented by the load-id, the runtime
+/// must load all associated URIs (named in DEFERRED_PART_URIS) and initialize
+/// all the loaded hunks (DEFERRED_PART_HASHES).
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_LIBRARY_PARTS = 'deferredLibraryParts';
+
+/// Contains a list of URIs (Strings), indexed by part.
+///
+/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_PART_URIS = 'deferredPartUris';
+
+/// Contains a list of hashes, indexed by part.
+///
+/// The lists in the DEFERRED_LIBRARY_PARTS map contain indexes into this list.
+///
+/// The hashes are associated with the URIs of the load-ids (see
+/// [DEFERRED_PART_URIS]). They are SHA1 (or similar) hashes of the code that
+/// must be loaded. By using cryptographic hashes we can (1) handle loading in
+/// the same web page the parts from multiple Dart applications (2) avoid
+/// loading similar code multiple times.
+///
+/// This embedded global is only used for deferred loading.
+const DEFERRED_PART_HASHES = 'deferredPartHashes';
+
+/// Initialize a loaded hunk.
+///
+/// Once a hunk (the code from a deferred URI) has been loaded it must be
+/// initialized. Calling this function with the corresponding hash (see
+/// [DEFERRED_LIBRARY_HASHES]) initializes the code.
+///
+/// This embedded global is only used for deferred loading.
+const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
+
+/// Returns, whether a hunk (identified by its hash) has already been loaded.
+///
+/// This embedded global is only used for deferred loading.
+const IS_HUNK_LOADED = 'isHunkLoaded';
+
+/// Returns, whether a hunk (identified by its hash) has already been
+/// initialized.
+///
+/// This embedded global is only used for deferred loading.
+const IS_HUNK_INITIALIZED = 'isHunkInitialized';
+
+/// A set (implemented as map to booleans) of hunks (identified by hashes) that
+/// have already been initialized.
+///
+/// This embedded global is only used for deferred loading.
+///
+/// This global is an emitter-internal embedded global, and not used by the
+/// runtime. The constant remains in this file to make sure that other embedded
+/// globals don't clash with it.
+const DEFERRED_INITIALIZED = 'deferredInitialized';
+
+/// A 'Universe' object used by 'dart:_rti'.
+///
+/// This embedded global is used for --experiment-new-rti.
+const RTI_UNIVERSE = 'typeUniverse';
+
+/// Names that are supported by [JS_GET_NAME].
+// TODO(herhut): Make entries lower case (as in fields) and find a better name.
+enum JsGetName {
+  GETTER_PREFIX,
+  SETTER_PREFIX,
+  CALL_PREFIX,
+  CALL_PREFIX0,
+  CALL_PREFIX1,
+  CALL_PREFIX2,
+  CALL_PREFIX3,
+  CALL_PREFIX4,
+  CALL_PREFIX5,
+  CALL_CATCH_ALL,
+  REQUIRED_PARAMETER_PROPERTY,
+  DEFAULT_VALUES_PROPERTY,
+  CALL_NAME_PROPERTY,
+  DEFERRED_ACTION_PROPERTY,
+
+  /// Prefix used for generated type argument substitutions on classes.
+  OPERATOR_AS_PREFIX,
+
+  /// Prefix used for generated type test property on classes.
+  OPERATOR_IS_PREFIX,
+
+  /// Name used for generated function types on classes and methods.
+  SIGNATURE_NAME,
+
+  /// Name of JavaScript property used to store runtime-type information on
+  /// instances of parameterized classes.
+  RTI_NAME,
+
+  /// String representation of the type of the Future class.
+  FUTURE_CLASS_TYPE_NAME,
+
+  /// Field name used for determining if an object or its interceptor has
+  /// JavaScript indexing behavior.
+  IS_INDEXABLE_FIELD_NAME,
+
+  /// String representation of the type of the null class.
+  NULL_CLASS_TYPE_NAME,
+
+  /// String representation of the type of the object class.
+  OBJECT_CLASS_TYPE_NAME,
+
+  /// Property name for Rti._as field.
+  RTI_FIELD_AS,
+
+  /// Property name for Rti._is field.
+  RTI_FIELD_IS,
+}
+
+enum JsBuiltin {
+  /// Returns the JavaScript constructor function for Dart's Object class.
+  /// This can be used for type tests, as in
+  ///
+  ///     var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
+  ///     if (JS('bool', '# instanceof #', obj, constructor))
+  ///       ...
+  dartObjectConstructor,
+
+  /// Returns the JavaScript constructor function for the runtime's Closure
+  /// class, the base class of all closure objects.  This can be used for type
+  /// tests, as in
+  ///
+  ///     var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
+  ///     if (JS('bool', '# instanceof #', obj, constructor))
+  ///       ...
+  dartClosureConstructor,
+
+  /// Returns true if the given type is a type argument of a js-interop class
+  /// or a supertype of a js-interop class.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
+  isJsInteropTypeArgument,
+
+  /// Returns the metadata of the given [index].
+  ///
+  ///     JS_BUILTIN('returns:var;effects:none;depends:none',
+  ///                JsBuiltin.getMetadata, index);
+  getMetadata,
+
+  /// Returns the type of the given [index].
+  ///
+  ///     JS_BUILTIN('returns:var;effects:none;depends:none',
+  ///                JsBuiltin.getType, index);
+  getType,
+}
+
+/// Names of fields of the Rti Universe object.
+class RtiUniverseFieldNames {
+  static String evalCache = 'eC';
+  static String typeRules = 'tR';
+  static String erasedTypes = 'eT';
+  static String typeParameterVariances = 'tPV';
+  static String sharedEmptyArray = 'sEA';
+}
diff --git a/pkg/js_runtime/lib/shared/recipe_syntax.dart b/pkg/js_runtime/lib/shared/recipe_syntax.dart
new file mode 100644
index 0000000..c183861
--- /dev/null
+++ b/pkg/js_runtime/lib/shared/recipe_syntax.dart
@@ -0,0 +1,237 @@
+// 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.
+
+/// Constants and predicates used for encoding and decoding type recipes.
+///
+/// This library is shared between the compiler and the runtime system.
+library dart2js._recipe_syntax;
+
+abstract class Recipe {
+  Recipe._();
+
+  // Operators.
+
+  static const int separator = _comma;
+  static const String separatorString = _commaString;
+
+  static const int toType = _semicolon;
+  static const String toTypeString = _semicolonString;
+
+  static const int pushErased = _hash;
+  static const String pushErasedString = _hashString;
+  static const int pushDynamic = _at;
+  static const String pushDynamicString = _atString;
+  static const int pushVoid = _tilde;
+  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 requiredNameSeparator = _exclamation;
+  static const String requiredNameSeparatorString = _exclamationString;
+
+  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.
+
+  static bool isDigit(int code) => code >= _digit0 && code <= _digit9;
+  static int digitValue(int code) => code - _digit0;
+
+  static bool isIdentifierStart(int ch) =>
+      (((ch | 32) - _lowercaseA) & 0xffff) < 26 ||
+      (ch == _underscore) ||
+      (ch == _dollar);
+
+  static const int period = _period;
+
+  // Private names.
+
+  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 String _greaterThanString = '>';
+  static const int _question = 0x3F;
+  static const String _questionString = '?';
+  static const int _at = 0x40;
+  static const String _atString = '@';
+
+  static const int _uppercaseA = 0x41;
+  static const int _uppercaseZ = 0x5A;
+
+  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("pushErased", pushErased, pushErasedString);
+    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("requiredNameSeparator", requiredNameSeparator,
+        requiredNameSeparatorString);
+    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/pkg/js_runtime/pubspec.yaml b/pkg/js_runtime/pubspec.yaml
new file mode 100644
index 0000000..e707d77
--- /dev/null
+++ b/pkg/js_runtime/pubspec.yaml
@@ -0,0 +1,12 @@
+name: js_runtime
+# This package is not intended for consumption on pub.dev. DO NOT publish.
+publish_to: none
+
+environment:
+  sdk: '>=2.12.0 <3.0.0'
+
+dev_dependencies:
+  expect:
+    path: ../expect
+  _fe_analyzer_shared:
+    path: ../_fe_analyzer_shared
diff --git a/pkg/js_runtime/test/in_sync_test.dart b/pkg/js_runtime/test/in_sync_test.dart
new file mode 100644
index 0000000..4dbef635
--- /dev/null
+++ b/pkg/js_runtime/test/in_sync_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2020, 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 = 2.9
+
+/// Test to verify that this package is in-sync with dart2js runtime libraries.
+import 'dart:io';
+
+import 'package:_fe_analyzer_shared/src/util/relativize.dart';
+import 'package:expect/expect.dart';
+
+void main(List<String> argv) {
+  var packageDir = Platform.script.resolve('../lib/shared/');
+  var sdkDir = Platform.script
+      .resolve('../../../sdk/lib/_internal/js_runtime/lib/shared/');
+  var rPackageDir =
+      relativizeUri(Directory.current.uri, packageDir, Platform.isWindows);
+  var rSdkDir =
+      relativizeUri(Directory.current.uri, sdkDir, Platform.isWindows);
+
+  for (var file in Directory.fromUri(sdkDir).listSync()) {
+    if (file is File) {
+      var filename = file.uri.pathSegments.last;
+      var packageFile = File.fromUri(packageDir.resolve(filename));
+      Expect.isTrue(
+          packageFile.existsSync(),
+          "$filename not in sync. Please update it by running:\n"
+          "  cp $rSdkDir$filename $rPackageDir$filename");
+      var original = file.readAsBytesSync();
+      var copy = packageFile.readAsBytesSync();
+      Expect.listEquals(
+          original,
+          copy,
+          "$filename not in sync. Please update it by running:\n"
+          "  cp $rSdkDir$filename $rPackageDir$filename");
+    }
+  }
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 6b93319..da7fa09 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -173,6 +173,7 @@
 dev_compiler/test/options/*: SkipByDesign
 front_end/test/hot_reload_e2e_test: Skip
 frontend_server/test/*: SkipByDesign # Only meant to run on vm
+js_runtime/test/*: SkipByDesign # Only meant to run on vm
 vm/test/*: SkipByDesign # Only meant to run on vm
 vm_service/test/*: SkipByDesign # Uses dart:io
 vm_snapshot_analysis/test/*: SkipByDesign # Only meant to run on vm
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 2a57c7b..a558085 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -89,7 +89,6 @@
 CompilerOptions setupCompilerOptions(
     FileSystem fileSystem,
     Uri platformKernelPath,
-    bool suppressWarnings,
     bool enableAsserts,
     int nullSafety,
     List<String> experimentalFlags,
@@ -132,10 +131,10 @@
           errors.addAll(message.plainTextFormatted);
           break;
         case Severity.warning:
-          printToStdErr = !suppressWarnings;
+          printToStdErr = true;
           break;
         case Severity.info:
-          printToStdOut = !suppressWarnings;
+          printToStdOut = true;
           break;
         case Severity.context:
         case Severity.ignored:
@@ -157,7 +156,6 @@
   final int isolateId;
   final FileSystem fileSystem;
   final Uri platformKernelPath;
-  final bool suppressWarnings;
   final bool enableAsserts;
   final int nullSafety;
   final List<String> experimentalFlags;
@@ -175,8 +173,7 @@
   CompilerOptions options;
 
   Compiler(this.isolateId, this.fileSystem, this.platformKernelPath,
-      {this.suppressWarnings: false,
-      this.enableAsserts: false,
+      {this.enableAsserts: false,
       this.nullSafety: kNullSafetyOptionUnspecified,
       this.experimentalFlags: null,
       this.supportCodeCoverage: false,
@@ -201,7 +198,6 @@
     options = setupCompilerOptions(
         fileSystem,
         platformKernelPath,
-        suppressWarnings,
         enableAsserts,
         nullSafety,
         experimentalFlags,
@@ -294,15 +290,13 @@
 
   IncrementalCompilerWrapper(
       int isolateId, FileSystem fileSystem, Uri platformKernelPath,
-      {bool suppressWarnings: false,
-      bool enableAsserts: false,
+      {bool enableAsserts: false,
       int nullSafety: kNullSafetyOptionUnspecified,
       List<String> experimentalFlags: null,
       String packageConfig: null,
       String invocationModes: '',
       String verbosityLevel: Verbosity.defaultValue})
       : super(isolateId, fileSystem, platformKernelPath,
-            suppressWarnings: suppressWarnings,
             enableAsserts: enableAsserts,
             nullSafety: nullSafety,
             experimentalFlags: experimentalFlags,
@@ -317,14 +311,12 @@
       int isolateId,
       FileSystem fileSystem,
       Uri platformKernelPath,
-      {bool suppressWarnings: false,
-      bool enableAsserts: false,
+      {bool enableAsserts: false,
       List<String> experimentalFlags: null,
       String packageConfig: null,
       String invocationModes: ''}) {
     IncrementalCompilerWrapper result = IncrementalCompilerWrapper(
         isolateId, fileSystem, platformKernelPath,
-        suppressWarnings: suppressWarnings,
         enableAsserts: enableAsserts,
         experimentalFlags: experimentalFlags,
         packageConfig: packageConfig,
@@ -353,7 +345,6 @@
   Future<IncrementalCompilerWrapper> clone(int isolateId) async {
     IncrementalCompilerWrapper clone = IncrementalCompilerWrapper(
         isolateId, fileSystem, platformKernelPath,
-        suppressWarnings: suppressWarnings,
         enableAsserts: enableAsserts,
         nullSafety: nullSafety,
         experimentalFlags: experimentalFlags,
@@ -384,7 +375,6 @@
   SingleShotCompilerWrapper(
       int isolateId, FileSystem fileSystem, Uri platformKernelPath,
       {this.requireMain: false,
-      bool suppressWarnings: false,
       bool enableAsserts: false,
       int nullSafety: kNullSafetyOptionUnspecified,
       List<String> experimentalFlags: null,
@@ -392,7 +382,6 @@
       String invocationModes: '',
       String verbosityLevel: Verbosity.defaultValue})
       : super(isolateId, fileSystem, platformKernelPath,
-            suppressWarnings: suppressWarnings,
             enableAsserts: enableAsserts,
             nullSafety: nullSafety,
             experimentalFlags: experimentalFlags,
@@ -428,8 +417,7 @@
 
 Future<Compiler> lookupOrBuildNewIncrementalCompiler(int isolateId,
     List sourceFiles, Uri platformKernelPath, List<int> platformKernel,
-    {bool suppressWarnings: false,
-    bool enableAsserts: false,
+    {bool enableAsserts: false,
     int nullSafety: kNullSafetyOptionUnspecified,
     List<String> experimentalFlags: null,
     String packageConfig: null,
@@ -461,7 +449,6 @@
       // isolate was shut down. Message should be handled here in this script.
       compiler = new IncrementalCompilerWrapper(
           isolateId, fileSystem, platformKernelPath,
-          suppressWarnings: suppressWarnings,
           enableAsserts: enableAsserts,
           nullSafety: nullSafety,
           experimentalFlags: experimentalFlags,
@@ -516,10 +503,9 @@
   final bool isStatic = request[9];
   final List dillData = request[10];
   final int blobLoadCount = request[11];
-  final bool suppressWarnings = request[12];
-  final bool enableAsserts = request[13];
+  final bool enableAsserts = request[12];
   final List<String> experimentalFlags =
-      request[14] != null ? request[14].cast<String>() : null;
+      request[13] != null ? request[13].cast<String>() : null;
 
   IncrementalCompilerWrapper compiler = isolateCompilers[isolateId];
 
@@ -599,7 +585,6 @@
       try {
         compiler = new IncrementalCompilerWrapper.forExpressionCompilationOnly(
             component, isolateId, fileSystem, null,
-            suppressWarnings: suppressWarnings,
             enableAsserts: enableAsserts,
             experimentalFlags: experimentalFlags,
             packageConfig: dotPackagesFile);
@@ -761,17 +746,14 @@
   final bool snapshot = request[5];
   final int nullSafety = request[6];
   final List sourceFiles = request[8];
-  final bool suppressWarnings = request[9];
-  final bool enableAsserts = request[10];
+  final bool enableAsserts = request[9];
   final List<String> experimentalFlags =
-      request[11] != null ? request[11].cast<String>() : null;
-  final String packageConfig = request[12];
-  final String multirootFilepaths = request[13];
-  final String multirootScheme = request[14];
-  final String workingDirectory = request[15];
-  // TODO(johnniwinther,bkonyi): Pass verbosity from command line arguments.
-  final String verbosityLevel = Verbosity.defaultValue;
-
+      request[10] != null ? request[10].cast<String>() : null;
+  final String packageConfig = request[11];
+  final String multirootFilepaths = request[12];
+  final String multirootScheme = request[13];
+  final String workingDirectory = request[14];
+  final String verbosityLevel = request[15];
   Uri platformKernelPath = null;
   List<int> platformKernel = null;
   if (request[3] is String) {
@@ -834,7 +816,6 @@
         fileSystem,
         platformKernelPath,
         false,
-        false,
         nullSafety,
         experimentalFlags,
         packagesUri,
@@ -860,7 +841,6 @@
   if (incremental) {
     compiler = await lookupOrBuildNewIncrementalCompiler(
         isolateId, sourceFiles, platformKernelPath, platformKernel,
-        suppressWarnings: suppressWarnings,
         enableAsserts: enableAsserts,
         nullSafety: nullSafety,
         experimentalFlags: experimentalFlags,
@@ -875,7 +855,6 @@
     compiler = new SingleShotCompilerWrapper(
         isolateId, fileSystem, platformKernelPath,
         requireMain: false,
-        suppressWarnings: suppressWarnings,
         enableAsserts: enableAsserts,
         nullSafety: nullSafety,
         experimentalFlags: experimentalFlags,
@@ -1029,13 +1008,13 @@
     kNullSafetyOptionUnspecified /* null safety */,
     1 /* isolateId chosen randomly */,
     [] /* source files */,
-    false /* suppress warnings */,
     false /* enable asserts */,
     null /* experimental_flags */,
     null /* package_config */,
     null /* multirootFilepaths */,
     null /* multirootScheme */,
     null /* original working directory */,
+    'all' /* CFE logging mode */,
   ];
   await _processLoadRequest(request);
 }
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 0a6bc48..6935447 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -191,7 +191,7 @@
 
   return Dart_CompileToKernel(sanitized_uri, platform_strong_dill,
                               platform_strong_dill_size, incremental, snapshot,
-                              package_config);
+                              package_config, verbosity());
 }
 
 void DFE::CompileAndReadScript(const char* script_uri,
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 0c38270..b381f9c 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -42,6 +42,11 @@
   }
   bool use_incremental_compiler() const { return use_incremental_compiler_; }
 
+  void set_verbosity(Dart_KernelCompilationVerbosityLevel verbosity) {
+    verbosity_ = verbosity;
+  }
+  Dart_KernelCompilationVerbosityLevel verbosity() const { return verbosity_; }
+
   // Returns the platform binary file name if the path to
   // kernel binaries was set using SetKernelBinaries.
   const char* GetPlatformBinaryFilename();
@@ -115,6 +120,8 @@
   bool use_dfe_;
   bool use_incremental_compiler_;
   char* frontend_filename_;
+  Dart_KernelCompilationVerbosityLevel verbosity_ =
+      Dart_KernelCompilationVerbosityLevel_All;
 
   // Kernel binary specified on the cmd line.
   uint8_t* application_kernel_buffer_;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 12e64808..cddacb8 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1283,6 +1283,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // Load vm_platform_strong.dill for dart:* source support.
   dfe.Init();
+  dfe.set_verbosity(Options::verbosity_level());
   if (script_name != nullptr) {
     uint8_t* application_kernel_buffer = NULL;
     intptr_t application_kernel_buffer_size = 0;
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index d019ce4..517029d 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -34,7 +34,13 @@
     NULL,
 };
 
+// These strings must match the enum VerbosityLevel in main_options.h.
+static const char* kVerbosityLevelNames[] = {
+    "error", "warning", "info", "all", nullptr,
+};
+
 SnapshotKind Options::gen_snapshot_kind_ = kNone;
+VerbosityLevel Options::verbosity_ = kAll;
 bool Options::enable_vm_service_ = false;
 
 #define OPTION_FIELD(variable) Options::variable##_
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 2ab8598..adec23c 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -63,7 +63,9 @@
 // In main_options.cc there must be a list of strings that matches the enum
 // called k{enum_type}Names. The field is not automatically declared in
 // main_options.cc. It must be explicitly declared.
-#define ENUM_OPTIONS_LIST(V) V(snapshot_kind, SnapshotKind, gen_snapshot_kind)
+#define ENUM_OPTIONS_LIST(V)                                                   \
+  V(snapshot_kind, SnapshotKind, gen_snapshot_kind)                            \
+  V(verbosity, VerbosityLevel, verbosity)
 
 // Callbacks passed to DEFINE_CB_OPTION().
 #define CB_OPTIONS_LIST(V)                                                     \
@@ -79,6 +81,14 @@
   kAppJIT,
 };
 
+// This enum must match the strings in kVerbosityLevelNames in main_options.cc.
+enum VerbosityLevel {
+  kError,
+  kWarning,
+  kInfo,
+  kAll,
+};
+
 static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
 static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
 static constexpr int INVALID_VM_SERVICE_SERVER_PORT = -1;
@@ -131,6 +141,9 @@
   static const char* vm_service_server_ip() { return vm_service_server_ip_; }
   static int vm_service_server_port() { return vm_service_server_port_; }
 
+  static Dart_KernelCompilationVerbosityLevel verbosity_level() {
+    return VerbosityLevelToDartAPI(verbosity_);
+  }
 #if !defined(DART_PRECOMPILED_RUNTIME)
   static DFE* dfe() { return dfe_; }
   static void set_dfe(DFE* dfe) { dfe_ = dfe; }
@@ -169,6 +182,22 @@
   static DFE* dfe_;
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
+  static Dart_KernelCompilationVerbosityLevel VerbosityLevelToDartAPI(
+      VerbosityLevel level) {
+    switch (level) {
+      case kError:
+        return Dart_KernelCompilationVerbosityLevel_Error;
+      case kWarning:
+        return Dart_KernelCompilationVerbosityLevel_Warning;
+      case kInfo:
+        return Dart_KernelCompilationVerbosityLevel_Info;
+      case kAll:
+        return Dart_KernelCompilationVerbosityLevel_All;
+      default:
+        UNREACHABLE();
+    }
+  }
+
   // VM Service argument processing.
   static const char* vm_service_server_ip_;
   static bool enable_vm_service_;
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index aae9199..b4415cf 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3525,6 +3525,13 @@
   intptr_t kernel_size;
 } Dart_KernelCompilationResult;
 
+typedef enum {
+  Dart_KernelCompilationVerbosityLevel_Error = 0,
+  Dart_KernelCompilationVerbosityLevel_Warning,
+  Dart_KernelCompilationVerbosityLevel_Info,
+  Dart_KernelCompilationVerbosityLevel_All,
+} Dart_KernelCompilationVerbosityLevel;
+
 DART_EXPORT bool Dart_IsKernelIsolate(Dart_Isolate isolate);
 DART_EXPORT bool Dart_KernelIsolateIsRunning();
 DART_EXPORT Dart_Port Dart_KernelPort();
@@ -3541,6 +3548,9 @@
  * This is used by the frontend to determine if compilation related information
  * should be printed to console (e.g., null safety mode).
  *
+ * \param verbosity Specifies the logging behavior of the kernel compilation
+ * service.
+ *
  * \return Returns the result of the compilation.
  *
  * On a successful compilation the returned [Dart_KernelCompilationResult] has
@@ -3559,7 +3569,8 @@
                      const intptr_t platform_kernel_size,
                      bool incremental_compile,
                      bool snapshot_compile,
-                     const char* package_config);
+                     const char* package_config,
+                     Dart_KernelCompilationVerbosityLevel verbosity);
 
 typedef struct {
   const char* uri;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 2f53e5d..1cc6888 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -6095,7 +6095,8 @@
                      intptr_t platform_kernel_size,
                      bool incremental_compile,
                      bool snapshot_compile,
-                     const char* package_config) {
+                     const char* package_config,
+                     Dart_KernelCompilationVerbosityLevel verbosity) {
   API_TIMELINE_DURATION(Thread::Current());
 
   Dart_KernelCompilationResult result = {};
@@ -6105,7 +6106,8 @@
 #else
   result = KernelIsolate::CompileToKernel(
       script_uri, platform_kernel, platform_kernel_size, 0, NULL,
-      incremental_compile, snapshot_compile, package_config);
+      incremental_compile, snapshot_compile, package_config, NULL, NULL,
+      verbosity);
   if (result.status == Dart_KernelCompilationStatus_Ok) {
     Dart_KernelCompilationResult accept_result =
         KernelIsolate::AcceptCompilation();
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 36bfb1b..168cb76 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -31,10 +31,6 @@
 #define Z (T->zone())
 
 DEFINE_FLAG(bool, trace_kernel, false, "Trace Kernel service requests.");
-DEFINE_FLAG(bool,
-            suppress_fe_warnings,
-            false,
-            "Suppress warnings from the FE.");
 DEFINE_FLAG(charp,
             kernel_multiroot_filepaths,
             NULL,
@@ -621,10 +617,6 @@
     num_blob_loads.type = Dart_CObject_kInt64;
     num_blob_loads.value.as_int64 = source->num_blob_loads_;
 
-    Dart_CObject suppress_warnings;
-    suppress_warnings.type = Dart_CObject_kBool;
-    suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
-
     Dart_CObject enable_asserts;
     enable_asserts.type = Dart_CObject_kBool;
     enable_asserts.value.as_bool = isolate_group->asserts();
@@ -656,7 +648,6 @@
                                    &is_static_object,
                                    &dills_object,
                                    &num_blob_loads,
-                                   &suppress_warnings,
                                    &enable_asserts,
                                    &experimental_flags_object};
     message.value.as_array.values = message_arr;
@@ -713,7 +704,8 @@
       const char* multiroot_filepaths,
       const char* multiroot_scheme,
       const MallocGrowableArray<char*>* experimental_flags,
-      const char* original_working_directory) {
+      const char* original_working_directory,
+      Dart_KernelCompilationVerbosityLevel verbosity) {
     // Build the message for the Kernel isolate.
     // tag is used to specify which operation the frontend should perform.
     Dart_CObject tag;
@@ -780,10 +772,6 @@
 
     Dart_CObject files = BuildFilesPairs(source_files_count, source_files);
 
-    Dart_CObject suppress_warnings;
-    suppress_warnings.type = Dart_CObject_kBool;
-    suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
-
     Dart_CObject enable_asserts;
     enable_asserts.type = Dart_CObject_kBool;
     enable_asserts.value.as_bool = isolate_group != nullptr
@@ -857,6 +845,11 @@
       }
     }
 
+    Dart_CObject verbosity_str;
+    verbosity_str.type = Dart_CObject_kString;
+    verbosity_str.value.as_string =
+        const_cast<char*>(KernelCompilationVerbosityLevelToString(verbosity));
+
     Dart_CObject* message_arr[] = {&tag,
                                    &send_port,
                                    &uri,
@@ -866,13 +859,13 @@
                                    &null_safety,
                                    &isolate_id,
                                    &files,
-                                   &suppress_warnings,
                                    &enable_asserts,
                                    &experimental_flags_object,
                                    &package_config_uri,
                                    &multiroot_filepaths_object,
                                    &multiroot_scheme_object,
-                                   &original_working_directory_object};
+                                   &original_working_directory_object,
+                                   &verbosity_str};
     message.value.as_array.values = message_arr;
     message.value.as_array.length = ARRAY_SIZE(message_arr);
     // Send the message.
@@ -987,6 +980,22 @@
     return NULL;
   }
 
+  static const char* KernelCompilationVerbosityLevelToString(
+      Dart_KernelCompilationVerbosityLevel verbosity) {
+    switch (verbosity) {
+      case Dart_KernelCompilationVerbosityLevel_Error:
+        return "error";
+      case Dart_KernelCompilationVerbosityLevel_Warning:
+        return "warning";
+      case Dart_KernelCompilationVerbosityLevel_Info:
+        return "info";
+      case Dart_KernelCompilationVerbosityLevel_All:
+        return "all";
+      default:
+        UNREACHABLE();
+    }
+  }
+
   // This monitor must be held whenever linked list of requests is accessed.
   static Monitor* requests_monitor_;
 
@@ -1017,7 +1026,8 @@
     bool snapshot_compile,
     const char* package_config,
     const char* multiroot_filepaths,
-    const char* multiroot_scheme) {
+    const char* multiroot_scheme,
+    Dart_KernelCompilationVerbosityLevel verbosity) {
   // Start the kernel Isolate if it is not already running.
   if (!Start()) {
     Dart_KernelCompilationResult result = {};
@@ -1041,7 +1051,8 @@
       kCompileTag, kernel_port, script_uri, platform_kernel,
       platform_kernel_size, source_file_count, source_files,
       incremental_compile, snapshot_compile, package_config,
-      multiroot_filepaths, multiroot_scheme, experimental_flags_, NULL);
+      multiroot_filepaths, multiroot_scheme, experimental_flags_, NULL,
+      verbosity);
 }
 
 bool KernelIsolate::DetectNullSafety(const char* script_uri,
@@ -1060,7 +1071,7 @@
   Dart_KernelCompilationResult result = request.SendAndWaitForResponse(
       kDetectNullabilityTag, kernel_port, script_uri, nullptr, -1, 0, nullptr,
       false, false, package_config, nullptr, nullptr, experimental_flags_,
-      original_working_directory);
+      original_working_directory, Dart_KernelCompilationVerbosityLevel_Error);
   return result.null_safety;
 }
 
@@ -1074,9 +1085,10 @@
   }
 
   KernelCompilationRequest request;
-  return request.SendAndWaitForResponse(kListDependenciesTag, kernel_port, NULL,
-                                        NULL, 0, 0, NULL, false, false, NULL,
-                                        NULL, NULL, experimental_flags_, NULL);
+  return request.SendAndWaitForResponse(
+      kListDependenciesTag, kernel_port, NULL, NULL, 0, 0, NULL, false, false,
+      NULL, NULL, NULL, experimental_flags_, NULL,
+      Dart_KernelCompilationVerbosityLevel_Error);
 }
 
 Dart_KernelCompilationResult KernelIsolate::AcceptCompilation() {
@@ -1091,9 +1103,10 @@
   }
 
   KernelCompilationRequest request;
-  return request.SendAndWaitForResponse(kAcceptTag, kernel_port, NULL, NULL, 0,
-                                        0, NULL, true, false, NULL, NULL, NULL,
-                                        experimental_flags_, NULL);
+  return request.SendAndWaitForResponse(
+      kAcceptTag, kernel_port, NULL, NULL, 0, 0, NULL, true, false, NULL, NULL,
+      NULL, experimental_flags_, NULL,
+      Dart_KernelCompilationVerbosityLevel_Error);
 }
 
 Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
@@ -1138,7 +1151,8 @@
   KernelCompilationRequest request;
   return request.SendAndWaitForResponse(
       kUpdateSourcesTag, kernel_port, NULL, NULL, 0, source_files_count,
-      source_files, true, false, NULL, NULL, NULL, experimental_flags_, NULL);
+      source_files, true, false, NULL, NULL, NULL, experimental_flags_, NULL,
+      Dart_KernelCompilationVerbosityLevel_Error);
 }
 
 void KernelIsolate::NotifyAboutIsolateShutdown(const Isolate* isolate) {
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index f312aee..438e883 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -54,7 +54,9 @@
       bool snapshot_compile = false,
       const char* package_config = NULL,
       const char* multiroot_filepaths = NULL,
-      const char* multiroot_scheme = NULL);
+      const char* multiroot_scheme = NULL,
+      Dart_KernelCompilationVerbosityLevel verbosity =
+          Dart_KernelCompilationVerbosityLevel_All);
 
   static bool DetectNullSafety(const char* script_uri,
                                const char* package_config,
diff --git a/tools/VERSION b/tools/VERSION
index 881e000..d2409964 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 258
+PRERELEASE 259
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 2bf93261..f3980bc 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -2205,6 +2205,13 @@
           ]
         },
         {
+          "name": "js_runtime unit tests",
+          "arguments": [
+            "-nunittest-asserts-no-sdk-linux",
+            "pkg//js_runtime/"
+          ]
+        },
+        {
           "name": "dart2js unit tests",
           "arguments": [
             "-nunittest-asserts-no-sdk-linux",
@@ -3218,7 +3225,7 @@
           "name": "package unit tests",
           "arguments": [
             "-nunittest-asserts-${mode}-${system}",
-            "pkg/pkg/(?!(analyzer*|analysis_server|compiler|front_end|kernel|nnbd_migration)/)"
+            "pkg/pkg/(?!(analyzer*|analysis_server|compiler|js_runtime|front_end|kernel|nnbd_migration)/)"
           ]
         },
         {
@@ -3256,7 +3263,7 @@
           "name": "package unit tests",
           "arguments": [
             "-nunittest-asserts-${mode}-${system}",
-            "pkg/pkg/(?!(analyzer*|analysis_server|compiler|front_end|kernel|nnbd_migration)/)"
+            "pkg/pkg/(?!(analyzer*|analysis_server|compiler|js_runtime|front_end|kernel|nnbd_migration)/)"
           ]
         },
         {