Version 2.14.0-189.0.dev

Merge commit '2c11a48c5ee269e612e3afb16ae7ac8844eaabf9' into 'dev'
diff --git a/DEPS b/DEPS
index cff4d03..1c57415 100644
--- a/DEPS
+++ b/DEPS
@@ -106,7 +106,7 @@
   "dart_style_rev": "f17c23e0eea9a870601c19d904e2a9c1a7c81470",
 
   "chromedriver_tag": "83.0.4103.39",
-  "dartdoc_rev" : "305713608c25106d95f9114418d895e08d1a9e9c",
+  "dartdoc_rev" : "b733d4952dbd25374d55e28476a5f44bd60ed63f",
   "devtools_rev" : "b3bf672474a2bff82f33e1176aa803539baa0d60+1",
   "jsshell_tag": "version:88.0",
   "ffi_rev": "f3346299c55669cc0db48afae85b8110088bf8da",
@@ -497,14 +497,25 @@
   Var("dart_root") + "/third_party/pkg/yaml":
       Var("dart_git") + "yaml.git" + "@" + Var("yaml_rev"),
 
-  Var("dart_root") + "/buildtools/" + Var("host_os") + "-" + Var("host_cpu") + "/clang": {
+  Var("dart_root") + "/buildtools/" + Var("host_os") + "-x64/clang": {
       "packages": [
           {
-              "package": "fuchsia/third_party/clang/${{platform}}",
+              "package": "fuchsia/third_party/clang/" + Var("host_os") + "-amd64",
               "version": "git_revision:" + Var("clang_revision"),
           },
       ],
-      "condition": "(host_os == 'linux' or host_os == 'mac') and (host_cpu == 'x64' or host_cpu == 'arm64')",
+      # TODO(https://fxbug.dev/73385): Use arm64 toolchain on arm64 when it exists.
+      "condition": "host_cpu == x64 and (host_os == linux or host_os == mac) or host_cpu == arm64 and host_os == mac",
+      "dep_type": "cipd",
+  },
+  Var("dart_root") + "/buildtools/linux-arm64/clang": {
+      "packages": [
+          {
+              "package": "fuchsia/third_party/clang/linux-arm64",
+              "version": "git_revision:" + Var("clang_revision"),
+          },
+      ],
+      "condition": "host_os == 'linux' and host_cpu == 'arm64'",
       "dep_type": "cipd",
   },
 
diff --git a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
index 6c0624e..4b41e12 100644
--- a/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
+++ b/pkg/_js_interop_checks/lib/src/transformations/js_util_optimizer.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
 import 'package:kernel/kernel.dart';
 
 /// Replaces js_util methods with inline calls to foreign_helper JS which
@@ -26,20 +28,41 @@
   final Iterable<Procedure> _allowedInteropJsUtilTargets;
   final Procedure _allowInteropTarget;
 
-  JsUtilOptimizer(CoreTypes coreTypes)
+  final CoreTypes _coreTypes;
+  final StatefulStaticTypeContext _staticTypeContext;
+
+  JsUtilOptimizer(this._coreTypes, ClassHierarchy hierarchy)
       : _jsTarget =
-            coreTypes.index.getTopLevelMember('dart:_foreign_helper', 'JS'),
+            _coreTypes.index.getTopLevelMember('dart:_foreign_helper', 'JS'),
         _getPropertyTarget =
-            coreTypes.index.getTopLevelMember('dart:js_util', 'getProperty'),
+            _coreTypes.index.getTopLevelMember('dart:js_util', 'getProperty'),
         _setPropertyTarget =
-            coreTypes.index.getTopLevelMember('dart:js_util', 'setProperty'),
-        _setPropertyUncheckedTarget = coreTypes.index
+            _coreTypes.index.getTopLevelMember('dart:js_util', 'setProperty'),
+        _setPropertyUncheckedTarget = _coreTypes.index
             .getTopLevelMember('dart:js_util', '_setPropertyUnchecked'),
         _allowInteropTarget =
-            coreTypes.index.getTopLevelMember('dart:js', 'allowInterop'),
+            _coreTypes.index.getTopLevelMember('dart:js', 'allowInterop'),
         _allowedInteropJsUtilTargets = _allowedInteropJsUtilMembers.map(
             (member) =>
-                coreTypes.index.getTopLevelMember('dart:js_util', member)) {}
+                _coreTypes.index.getTopLevelMember('dart:js_util', member)),
+        _staticTypeContext = StatefulStaticTypeContext.stacked(
+            TypeEnvironment(_coreTypes, hierarchy)) {}
+
+  @override
+  visitLibrary(Library lib) {
+    _staticTypeContext.enterLibrary(lib);
+    lib.transformChildren(this);
+    _staticTypeContext.leaveLibrary(lib);
+    return lib;
+  }
+
+  @override
+  defaultMember(Member node) {
+    _staticTypeContext.enterMember(node);
+    node.transformChildren(this);
+    _staticTypeContext.leaveMember(node);
+    return node;
+  }
 
   /// Replaces js_util method calls with optimization when possible.
   ///
@@ -96,39 +119,32 @@
       ..fileOffset = node.fileOffset;
   }
 
-  /// Returns whether the given TreeNode is guaranteed to be allowed to interop
-  /// with JS.
+  /// Returns whether the given Expression is guaranteed to be allowed to
+  /// interop with JS.
   ///
   /// Returns true when the node is guaranteed to be not a function:
-  ///    - has a DartType that is NullType or an InterfaceType that is not
-  ///      Function or Object
+  ///    - has a static DartType that is NullType or an InterfaceType that is
+  ///      not Function or Object
   /// Also returns true for allowed method calls within the JavaScript domain:
   ///        - dart:_foreign_helper JS
   ///        - dart:js `allowInterop`
   ///        - dart:js_util and any of the `_allowedInteropJsUtilMembers`
-  bool _allowedInterop(TreeNode node) {
+  bool _allowedInterop(Expression node) {
     // TODO(rileyporter): Detect functions that have been wrapped at some point
     // with `allowInterop`
-    // TODO(rileyporter): Use staticTypeContext to generalize type checking and
-    // allow more non-function types. Currently, we skip all literal types.
-    var checkType;
-    if (node is VariableGet) {
-      checkType = node.variable.type;
-    }
-
     if (node is StaticInvocation) {
       if (node.target == _allowInteropTarget) return true;
       if (node.target == _jsTarget) return true;
       if (_allowedInteropJsUtilTargets.contains(node.target)) return true;
-      checkType = node.target.function.returnType;
     }
 
-    if (checkType is InterfaceType) {
-      return checkType.classNode.name != 'Function' &&
-          checkType.classNode.name != 'Object';
+    var type = node.getStaticType(_staticTypeContext);
+    if (type is InterfaceType) {
+      return type.classNode != _coreTypes.functionClass &&
+          type.classNode != _coreTypes.objectClass;
     } else {
       // Only other DartType guaranteed to not be a function.
-      return checkType is NullType;
+      return type is NullType;
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index 424cb0d..4e42510 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -21,7 +21,7 @@
     for (var element in unitElement.mixins) {
       await _computeForClassElement(element);
     }
-    for (var element in unitElement.types) {
+    for (var element in unitElement.classes) {
       await _computeForClassElement(element);
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
index 498197c..4457f2e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
@@ -105,7 +105,10 @@
     for (var element in compilationUnit.functions) {
       elementMap.cacheTopLevelElement(dartdocDirectiveInfo, element);
     }
-    for (var element in [...compilationUnit.mixins, ...compilationUnit.types]) {
+    for (var element in [
+      ...compilationUnit.mixins,
+      ...compilationUnit.classes
+    ]) {
       var parentKey =
           elementMap.cacheTopLevelElement(dartdocDirectiveInfo, element);
       if (parentKey != null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
index 743bc27..8934ed9 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/redirecting_contributor.dart
@@ -64,9 +64,10 @@
         }
         var typeSystem = libraryElement.typeSystem;
         for (var unit in libraryElement.units) {
-          for (var type in unit.types) {
-            if (typeSystem.isSubtypeOf(type.thisType, classElement.thisType)) {
-              for (var constructor in type.constructors) {
+          for (var class_ in unit.classes) {
+            if (typeSystem.isSubtypeOf(
+                class_.thisType, classElement.thisType)) {
+              for (var constructor in class_.constructors) {
                 if (constructor != constructorElement &&
                     constructor.isAccessibleIn(request.libraryElement)) {
                   builder.suggestConstructor(constructor);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
index 0ec47fc..0d0583d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_to.dart
@@ -82,7 +82,7 @@
       // Check elements of this library.
       if (prefixName == null) {
         for (var unit in resolvedResult.libraryElement.units) {
-          finder._updateList(unit.types);
+          finder._updateList(unit.classes);
         }
       }
       // Check elements from imports.
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 6853504..6a7ad79 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -3,6 +3,7 @@
   explicitly  that there are always (possibly empty) strings as the first
   and the last elements of an interpolation.
 * Deprecated `ImportElement.prefixOffset`, use `prefix.nameOffset` instead.
+* Deprecated `CompilationUnitElement.types`, use `classes` instead.
 
 ## 1.7.0
 * Require `meta: ^1.4.0`.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index eb07ad0..236df2f 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -386,6 +386,10 @@
   /// setters) contained in this compilation unit.
   List<PropertyAccessorElement> get accessors;
 
+  /// Return a list containing all of the classes contained in this compilation
+  /// unit.
+  List<ClassElement> get classes;
+
   @override
   LibraryElement get enclosingElement;
 
@@ -431,6 +435,7 @@
 
   /// Return a list containing all of the classes contained in this compilation
   /// unit.
+  @Deprecated('Use classes instead')
   List<ClassElement> get types;
 
   /// Return the enum defined in this compilation unit that has the given
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 7f8e2f0..d89aaf1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -33,6 +33,7 @@
 import 'package:analyzer/src/dart/analysis/testing_data.dart';
 import 'package:analyzer/src/diagnostic/diagnostic.dart';
 import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisEngine, AnalysisOptions, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart';
@@ -1993,6 +1994,12 @@
       // Ignore, continue with the exception that we are reporting now.
     }
 
+    if (exception is CaughtExceptionWithFiles) {
+      for (var nested in exception.fileContentMap.entries) {
+        fileContentMap['nested-${nested.key}'] = nested.value;
+      }
+    }
+
     _exceptionController.add(
       ExceptionResult(
         filePath: path,
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 99f4c26..40b742f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -399,7 +400,15 @@
   /// Return a new parsed unresolved [CompilationUnit].
   CompilationUnitImpl parse([AnalysisErrorListener? errorListener]) {
     errorListener ??= AnalysisErrorListener.NULL_LISTENER;
-    return _parse(errorListener);
+    try {
+      return _parse(errorListener);
+    } catch (exception, stackTrace) {
+      throw CaughtExceptionWithFiles(
+        exception,
+        stackTrace,
+        {path: content},
+      );
+    }
   }
 
   /// Read the file content and ensure that all of the file properties are
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index c460b9e..20df7ad 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -56,7 +56,7 @@
       if (searchedFiles.add(file, this)) {
         var unitResult = await _driver.getUnitElement2(file);
         if (unitResult is UnitElementResult) {
-          unitResult.element.types.forEach(addElements);
+          unitResult.element.classes.forEach(addElements);
           unitResult.element.mixins.forEach(addElements);
         }
       }
@@ -178,13 +178,13 @@
       if (unitResult is UnitElementResult) {
         CompilationUnitElement unitElement = unitResult.element;
         unitElement.accessors.forEach(addElement);
+        unitElement.classes.forEach(addElement);
         unitElement.enums.forEach(addElement);
         unitElement.extensions.forEach(addElement);
         unitElement.functions.forEach(addElement);
         unitElement.mixins.forEach(addElement);
         unitElement.topLevelVariables.forEach(addElement);
         unitElement.typeAliases.forEach(addElement);
-        unitElement.types.forEach(addElement);
       }
     }
     return elements;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 684e4a1..53393a1 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2038,7 +2038,12 @@
 
   @override
   LanguageVersionToken? get languageVersionToken {
-    Token? comment = beginToken.precedingComments;
+    Token? targetToken = beginToken;
+    if (targetToken.type == TokenType.SCRIPT_TAG) {
+      targetToken = targetToken.next;
+    }
+
+    Token? comment = targetToken?.precedingComments;
     while (comment != null) {
       if (comment is LanguageVersionToken) {
         return comment;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 8f4798d..2a32921 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -937,6 +937,9 @@
   /// contained in this compilation unit.
   List<PropertyAccessorElement> _accessors = const [];
 
+  /// A list containing all of the classes contained in this compilation unit.
+  List<ClassElement> _classes = const [];
+
   /// A list containing all of the enums contained in this compilation unit.
   List<ClassElement> _enums = const [];
 
@@ -961,9 +964,6 @@
   /// unit.
   List<TypeAliasElement> _typeAliases = const [];
 
-  /// A list containing all of the classes contained in this compilation unit.
-  List<ClassElement> _types = const [];
-
   /// A list containing all of the variables contained in this compilation unit.
   List<TopLevelVariableElement> _variables = const [];
 
@@ -988,6 +988,25 @@
   }
 
   @override
+  List<ClassElement> get classes {
+    return _classes;
+  }
+
+  /// Set the classes contained in this compilation unit to [classes].
+  set classes(List<ClassElement> classes) {
+    for (ClassElement class_ in classes) {
+      // Another implementation of ClassElement is _DeferredClassElement,
+      // which is used to resynthesize classes lazily. We cannot cast it
+      // to ClassElementImpl, and it already can provide correct values of the
+      // 'enclosingElement' property.
+      if (class_ is ClassElementImpl) {
+        class_.enclosingElement = this;
+      }
+    }
+    _classes = classes;
+  }
+
+  @override
   LibraryElement get enclosingElement =>
       super.enclosingElement as LibraryElement;
 
@@ -1120,23 +1139,10 @@
   @override
   TypeParameterizedElementMixin? get typeParameterContext => null;
 
+  @Deprecated('Use classes instead')
   @override
   List<ClassElement> get types {
-    return _types;
-  }
-
-  /// Set the types contained in this compilation unit to the given [types].
-  set types(List<ClassElement> types) {
-    for (ClassElement type in types) {
-      // Another implementation of ClassElement is _DeferredClassElement,
-      // which is used to resynthesize classes lazily. We cannot cast it
-      // to ClassElementImpl, and it already can provide correct values of the
-      // 'enclosingElement' property.
-      if (type is ClassElementImpl) {
-        type.enclosingElement = this;
-      }
-    }
-    _types = types;
+    return _classes;
   }
 
   @override
@@ -1164,9 +1170,9 @@
 
   @override
   ClassElement? getType(String className) {
-    for (ClassElement type in types) {
-      if (type.name == className) {
-        return type;
+    for (ClassElement class_ in classes) {
+      if (class_.name == className) {
+        return class_;
       }
     }
     return null;
@@ -1183,12 +1189,12 @@
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     safelyVisitChildren(accessors, visitor);
+    safelyVisitChildren(classes, visitor);
     safelyVisitChildren(enums, visitor);
     safelyVisitChildren(extensions, visitor);
     safelyVisitChildren(functions, visitor);
     safelyVisitChildren(mixins, visitor);
     safelyVisitChildren(typeAliases, visitor);
-    safelyVisitChildren(types, visitor);
     safelyVisitChildren(topLevelVariables, visitor);
   }
 }
@@ -3869,13 +3875,13 @@
   Iterable<Element> get topLevelElements sync* {
     for (var unit in units) {
       yield* unit.accessors;
+      yield* unit.classes;
       yield* unit.enums;
       yield* unit.extensions;
       yield* unit.functions;
       yield* unit.mixins;
       yield* unit.topLevelVariables;
       yield* unit.typeAliases;
-      yield* unit.types;
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/scope.dart b/pkg/analyzer/lib/src/dart/element/scope.dart
index e084086..5f6ff73 100644
--- a/pkg/analyzer/lib/src/dart/element/scope.dart
+++ b/pkg/analyzer/lib/src/dart/element/scope.dart
@@ -156,7 +156,7 @@
     compilationUnit.functions.forEach(_addGetter);
     compilationUnit.typeAliases.forEach(_addGetter);
     compilationUnit.mixins.forEach(_addGetter);
-    compilationUnit.types.forEach(_addGetter);
+    compilationUnit.classes.forEach(_addGetter);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 83348d9..95850f3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -229,6 +229,9 @@
     for (PropertyAccessorElement element in compilationUnit.accessors) {
       _addIfPublic(definedNames, element);
     }
+    for (ClassElement element in compilationUnit.classes) {
+      _addIfPublic(definedNames, element);
+    }
     for (ClassElement element in compilationUnit.enums) {
       _addIfPublic(definedNames, element);
     }
@@ -244,9 +247,6 @@
     for (TypeAliasElement element in compilationUnit.typeAliases) {
       _addIfPublic(definedNames, element);
     }
-    for (ClassElement element in compilationUnit.types) {
-      _addIfPublic(definedNames, element);
-    }
   }
 
   /// Apply the given [combinators] to all of the names in the given table of
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 2d222bd..bd18ac1 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -333,16 +333,17 @@
   //
   // Because map and set literals use the same delimiters (`{` and `}`), the
   // analyzer looks at the type arguments and the elements to determine which
-  // kind of literal you meant. When there are no type arguments and all of the
-  // elements are spread elements (which are allowed in both kinds of literals),
-  // then the analyzer uses the types of the expressions that are being spread.
-  // If all of the expressions have the type `Iterable`, then it's a set
-  // literal; if they all have the type `Map`, then it's a map literal.
+  // kind of literal you meant. When there are no type arguments, then the
+  // analyzer uses the types of the elements. If all of the elements are literal
+  // map entries and all of the spread operators are spreading a `Map` then it's
+  // a `Map`. If none of the elements are literal map entries and all of the
+  // spread operators are spreading an `Iterable`, then it's a `Set`. If neither
+  // of those is true then it's ambiguous.
   //
-  // The analyzer produces this diagnostic when some of the expressions being
-  // spread have the type `Iterable` and others have the type `Map`, making it
-  // impossible for the analyzer to determine whether you are writing a map
-  // literal or a set literal.
+  // The analyzer produces this diagnostic when at least one element is a
+  // literal map entry or a spread operator spreading a `Map`, and at least one
+  // element is neither of these, making it impossible for the analyzer to
+  // determine whether you are writing a map literal or a set literal.
   //
   // #### Examples
   //
@@ -379,9 +380,9 @@
   static const CompileTimeErrorCode AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH =
       CompileTimeErrorCode(
           'AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH',
-          "This literal contains both 'Map' and 'Iterable' spreads, "
-              "which makes it impossible to determine whether the literal is "
-              "a map or a set.",
+          "The literal can't be either a map or a set because it contains at "
+              "least one literal map entry or a spread operator spreading a "
+              "'Map', and at least one element which is neither of these.",
           correction:
               "Try removing or changing some of the elements so that all of "
               "the elements are consistent.",
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index f5e4f33..a762a29 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -196,6 +196,9 @@
         }
         definedGetters[name] = accessor;
       }
+      for (ClassElement class_ in element.classes) {
+        definedGetters[class_.name] = class_;
+      }
       for (ClassElement type in element.enums) {
         definedGetters[type.name] = type;
       }
@@ -211,9 +214,6 @@
       for (TypeAliasElement alias in element.typeAliases) {
         definedGetters[alias.name] = alias;
       }
-      for (ClassElement type in element.types) {
-        definedGetters[type.name] = type;
-      }
     }
 
     for (ImportElement importElement in _currentLibrary.imports) {
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 282bddd..a654bc8 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -51,7 +51,7 @@
   ElementWalker.forCompilationUnit(CompilationUnitElement element)
       : element = element,
         _accessors = element.accessors.where(_isNotSynthetic).toList(),
-        _classes = element.types,
+        _classes = element.classes,
         _enums = element.enums,
         _extensions = element.extensions,
         _functions = element.functions,
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index c0f4202..e7e2a81 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -547,7 +547,7 @@
     Reference unitReference,
   ) {
     var length = _reader.readUInt30();
-    unitElement.types = List.generate(length, (index) {
+    unitElement.classes = List.generate(length, (index) {
       return _readClassElement(unitElement, unitReference);
     });
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index c0ef2bd..e16d25e 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -440,7 +440,7 @@
     _sink._writeOptionalStringReference(unitElement.uri);
     _sink.writeBool(unitElement.isSynthetic);
     _resolutionSink._writeAnnotationList(unitElement.metadata);
-    _writeList(unitElement.types, _writeClassElement);
+    _writeList(unitElement.classes, _writeClassElement);
     _writeList(unitElement.enums, _writeEnumElement);
     _writeList(unitElement.extensions, _writeExtensionElement);
     _writeList(unitElement.functions, _writeFunctionElement);
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
index 587dc6c..48f2df7 100644
--- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -18,7 +18,7 @@
 
   void resolve() {
     for (var unitElement in _libraryElement.units) {
-      var classElements = [...unitElement.mixins, ...unitElement.types];
+      var classElements = [...unitElement.classes, ...unitElement.mixins];
       for (var classElement in classElements) {
         for (var constructorElement in classElement.constructors) {
           _constructor(
diff --git a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
index 79ad083..9675fd4 100644
--- a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
@@ -28,6 +28,10 @@
     for (var unit in _libraryElement.units) {
       _unitElement = unit as CompilationUnitElementImpl;
 
+      for (var classElement in unit.classes) {
+        _class(classElement);
+      }
+
       for (var extensionElement in unit.extensions) {
         _extension(extensionElement);
       }
@@ -36,10 +40,6 @@
         _class(classElement);
       }
 
-      for (var classElement in unit.types) {
-        _class(classElement);
-      }
-
       for (var element in unit.functions) {
         _function(element);
       }
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index c2b43c0..22ef219 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -52,6 +52,7 @@
   void buildDeclarationElements(CompilationUnit unit) {
     unit.declarations.accept(this);
     _unitElement.accessors = _enclosingContext.propertyAccessors;
+    _unitElement.classes = _enclosingContext.classes;
     _unitElement.enums = _enclosingContext.enums;
     _unitElement.extensions = _enclosingContext.extensions;
     _unitElement.functions = _enclosingContext.functions;
@@ -60,7 +61,6 @@
         .whereType<TopLevelVariableElementImpl>()
         .toList();
     _unitElement.typeAliases = _enclosingContext.typeAliases;
-    _unitElement.types = _enclosingContext.classes;
   }
 
   /// Build exports and imports, metadata into [_libraryElement].
diff --git a/pkg/analyzer/lib/src/summary2/informative_data.dart b/pkg/analyzer/lib/src/summary2/informative_data.dart
index ec885ce..b6b880d 100644
--- a/pkg/analyzer/lib/src/summary2/informative_data.dart
+++ b/pkg/analyzer/lib/src/summary2/informative_data.dart
@@ -87,7 +87,7 @@
         _applyToAccessors(unitElement.accessors, unitInfo.accessors);
 
         forCorrespondingPairs(
-          unitElement.types
+          unitElement.classes
               .where((element) => !element.isMixinApplication)
               .toList(),
           unitInfo.classDeclarations,
@@ -95,7 +95,7 @@
         );
 
         forCorrespondingPairs(
-          unitElement.types
+          unitElement.classes
               .where((element) => element.isMixinApplication)
               .toList(),
           unitInfo.classTypeAliases,
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 538f5d7..f279f1b 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -17,7 +17,7 @@
   var nodes = <SimplyBoundedNode>[];
   for (var libraryBuilder in linker.builders.values) {
     for (var unit in libraryBuilder.element.units) {
-      for (var element in unit.typeAliases) {
+      for (var element in unit.classes) {
         var node = walker.getNode(element);
         nodes.add(node);
       }
@@ -25,7 +25,7 @@
         var node = walker.getNode(element);
         nodes.add(node);
       }
-      for (var element in unit.types) {
+      for (var element in unit.typeAliases) {
         var node = walker.getNode(element);
         nodes.add(node);
       }
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 2dd428d..8c0f4f3 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -41,9 +41,9 @@
       _library = builder.element;
       for (var unit in _library.units) {
         _unitElement = unit as CompilationUnitElementImpl;
+        unit.classes.forEach(_resolveClassFields);
         unit.extensions.forEach(_resolveExtensionFields);
         unit.mixins.forEach(_resolveClassFields);
-        unit.types.forEach(_resolveClassFields);
 
         _scope = builder.scope;
         unit.topLevelVariables.forEach(_resolveVariable);
@@ -319,10 +319,10 @@
     for (var builder in _linker.builders.values) {
       for (var unit in builder.element.units) {
         _unitElement = unit as CompilationUnitElementImpl;
+        unit.classes.forEach(_addClassConstructorFieldFormals);
+        unit.classes.forEach(_addClassElementFields);
         unit.extensions.forEach(_addExtensionElementFields);
         unit.mixins.forEach(_addClassElementFields);
-        unit.types.forEach(_addClassConstructorFieldFormals);
-        unit.types.forEach(_addClassElementFields);
 
         _scope = builder.scope;
         for (var element in unit.topLevelVariables) {
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index ea2b598..bd67df2 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -34,8 +34,8 @@
   void inferCompilationUnit(CompilationUnitElement unit) {
     typeSystem = unit.library.typeSystem as TypeSystemImpl;
     isNonNullableByDefault = typeSystem.isNonNullableByDefault;
+    _inferClasses(unit.classes);
     _inferClasses(unit.mixins);
-    _inferClasses(unit.types);
   }
 
   /// Return `true` if the elements corresponding to the [elements] have the
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
index 75e989e..9cd9532e 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_element.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -191,7 +191,7 @@
       findInExecutables(mixin.methods);
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       findInExecutables(class_.accessors);
       findInExecutables(class_.constructors);
       findInExecutables(class_.methods);
@@ -279,7 +279,7 @@
       }
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       findInClass(class_);
     }
 
@@ -321,7 +321,7 @@
   CompilationUnitElement get unitElement;
 
   ClassElement class_(String name) {
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (class_.name == name) {
         return class_;
       }
@@ -330,7 +330,7 @@
   }
 
   ClassElement classOrMixin(String name) {
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (class_.name == name) {
         return class_;
       }
@@ -346,7 +346,7 @@
   ConstructorElement constructor(String name, {String? of}) {
     assert(name != '');
     ConstructorElement? result;
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (of == null || class_.name == of) {
         for (var constructor in class_.constructors) {
           if (constructor.name == name) {
@@ -403,7 +403,7 @@
       findIn(enum_.fields);
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (of != null && class_.name != of) {
         continue;
       }
@@ -458,7 +458,7 @@
       findIn(extension_.accessors);
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (of != null && class_.name != of) {
         continue;
       }
@@ -499,7 +499,7 @@
       findIn(extension_.methods);
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (of != null && class_.name != of) {
         continue;
       }
@@ -531,7 +531,7 @@
   ParameterElement parameter(String name) {
     ParameterElement? result;
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       for (var constructor in class_.constructors) {
         for (var parameter in constructor.parameters) {
           if (parameter.name == name) {
@@ -571,7 +571,7 @@
       findIn(extension_.accessors);
     }
 
-    for (var class_ in unitElement.types) {
+    for (var class_ in unitElement.classes) {
       if (of != null && class_.name != of) {
         continue;
       }
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
index 2761da8..cb56f4d 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk_elements.dart
@@ -874,7 +874,7 @@
     asyncUnit.librarySource = asyncUnit.source = asyncSource;
     asyncLibrary.definingCompilationUnit = asyncUnit;
 
-    asyncUnit.types = <ClassElement>[
+    asyncUnit.classes = <ClassElement>[
       completerElement,
       futureElement,
       futureOrElement,
@@ -891,7 +891,7 @@
     var coreSource = analysisContext.sourceFactory.forUri('dart:core')!;
     coreUnit.librarySource = coreUnit.source = coreSource;
 
-    coreUnit.types = <ClassElement>[
+    coreUnit.classes = <ClassElement>[
       boolElement,
       comparableElement,
       deprecatedElement,
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 6a9890f..5d2ee1e 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -145,8 +145,9 @@
   /// package:build does it.
   static const String _pubspecName = 'pubspec.yaml';
 
-  /// The associated pubspec file.
-  final File _pubspecFile;
+  /// The content of the `pubspec.yaml` file.
+  /// We read it once, so that all usages return consistent results.
+  final String? _pubspecContent;
 
   /// The map from a package name to the list of its `lib/` folders.
   @override
@@ -183,8 +184,8 @@
     this.projectPackageName,
     this.generatedRootPath,
     this.generatedThisPath,
-    this._pubspecFile,
-  ) {
+    File pubspecFile,
+  ) : _pubspecContent = _fileContentOrNull(pubspecFile) {
     _theOnlyPackage = PackageBuildWorkspacePackage(root, this);
   }
 
@@ -192,13 +193,6 @@
   UriResolver get packageUriResolver => PackageBuildPackageUriResolver(
       this, PackageMapUriResolver(provider, packageMap));
 
-  /// Return the content of the pubspec file, `null` if cannot be read.
-  String? get _pubspecContent {
-    try {
-      return _pubspecFile.readAsStringSync();
-    } catch (_) {}
-  }
-
   /// For some package file, which may or may not be a package source (it could
   /// be in `bin/`, `web/`, etc), find where its built counterpart will exist if
   /// its a generated source.
@@ -331,6 +325,13 @@
       }
     }
   }
+
+  /// Return the content of the [file], `null` if cannot be read.
+  static String? _fileContentOrNull(File file) {
+    try {
+      return file.readAsStringSync();
+    } catch (_) {}
+  }
 }
 
 /// Information about a package defined in a PackageBuildWorkspace.
diff --git a/pkg/analyzer/lib/src/workspace/pub.dart b/pkg/analyzer/lib/src/workspace/pub.dart
index a477bec..ef69e23 100644
--- a/pkg/analyzer/lib/src/workspace/pub.dart
+++ b/pkg/analyzer/lib/src/workspace/pub.dart
@@ -21,25 +21,20 @@
   /// Each Pub workspace is itself one package.
   late final PubWorkspacePackage _theOnlyPackage;
 
-  /// The associated pubspec file.
-  final File _pubspecFile;
+  /// The content of the `pubspec.yaml` file.
+  /// We read it once, so that all usages return consistent results.
+  final String? _pubspecContent;
 
   PubWorkspace._(
     ResourceProvider provider,
     Map<String, List<Folder>> packageMap,
     String root,
-    this._pubspecFile,
-  ) : super(provider, packageMap, root) {
+    File pubspecFile,
+  )   : _pubspecContent = _fileContentOrNull(pubspecFile),
+        super(provider, packageMap, root) {
     _theOnlyPackage = PubWorkspacePackage(root, this);
   }
 
-  /// Return the content of the pubspec file, `null` if cannot be read.
-  String? get _pubspecContent {
-    try {
-      return _pubspecFile.readAsStringSync();
-    } catch (_) {}
-  }
-
   @internal
   @override
   void contributeToResolutionSalt(ApiSignature buffer) {
@@ -71,6 +66,13 @@
       }
     }
   }
+
+  /// Return the content of the [file], `null` if cannot be read.
+  static String? _fileContentOrNull(File file) {
+    try {
+      return file.readAsStringSync();
+    } catch (_) {}
+  }
 }
 
 /// Information about a package defined in a [PubWorkspace].
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index c319cc9..b617776 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -6268,7 +6268,7 @@
 
     var myLibrary = myImport.importedLibrary!;
     var myUnit = myLibrary.definingCompilationUnit;
-    var myClass = myUnit.types.single;
+    var myClass = myUnit.classes.single;
     var myTypeAlias = myUnit.typeAliases.single;
     var myTopVariable = myUnit.topLevelVariables[0];
     var myTopFunction = myUnit.functions.single;
@@ -7377,7 +7377,7 @@
     var cNode = unit.declarations[0] as ClassDeclaration;
     ClassElement cElement = cNode.declaredElement!;
     TypeParameterElement tElement = cElement.typeParameters[0];
-    expect(cElement, same(unitElement.types[0]));
+    expect(cElement, same(unitElement.classes[0]));
 
     {
       FieldElement aElement = cElement.getField('a')!;
@@ -7661,11 +7661,11 @@
 
     var aNode = unit.declarations[0] as ClassDeclaration;
     ClassElement aElement = aNode.declaredElement!;
-    expect(aElement, same(unitElement.types[0]));
+    expect(aElement, same(unitElement.classes[0]));
 
     var cNode = unit.declarations[1] as ClassDeclaration;
     ClassElement cElement = cNode.declaredElement!;
-    expect(cElement, same(unitElement.types[1]));
+    expect(cElement, same(unitElement.classes[1]));
 
     {
       TypeParameter tNode = cNode.typeParameters!.typeParameters[0];
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index c8925ec..b725881 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -2032,7 +2032,7 @@
 
     ResolvedUnitResult result = await driver.getResultValid(path);
     expect(result, isNotNull);
-    expect(result.unit!.declaredElement!.types.map((e) => e.name), ['A']);
+    expect(result.unit!.declaredElement!.classes.map((e) => e.name), ['A']);
   }
 
   test_getResult_recursiveFlatten() async {
@@ -2292,7 +2292,7 @@
     newFile(path, content: 'class A {}');
     var unitResult = await driver.getUnitElement2(path);
     unitResult as UnitElementResult;
-    expect(unitResult.element.types.map((e) => e.name), ['A']);
+    expect(unitResult.element.classes.map((e) => e.name), ['A']);
   }
 
   @deprecated
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 9d9e9a9..26d4849 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -182,7 +182,7 @@
     var result = await session.getUnitElementValid(file.path);
     expect(result.state, ResultState.VALID);
     expect(result.path, file.path);
-    expect(result.element.types, hasLength(1));
+    expect(result.element.classes, hasLength(1));
     expect(result.uri.toString(), 'package:dart.my/a.dart');
   }
 
@@ -1008,7 +1008,7 @@
     expect(unitResult.session, session);
     expect(unitResult.path, testPath);
     expect(unitResult.uri, Uri.parse('package:test/test.dart'));
-    expect(unitResult.element.types, hasLength(2));
+    expect(unitResult.element.classes, hasLength(2));
   }
 
   test_resourceProvider() async {
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index 36a1ab1..84635ce 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -29,6 +29,31 @@
     testUnit = parseCompilationUnit(source) as CompilationUnitImpl;
   }
 
+  test_languageVersionComment_afterScriptTag() {
+    parse('''
+#!/bin/false
+// @dart=2.9
+void main() {}
+''');
+    var token = testUnit.languageVersionToken!;
+    expect(token.major, 2);
+    expect(token.minor, 9);
+    expect(token.offset, 13);
+  }
+
+  test_languageVersionComment_afterScriptTag_andComment() {
+    parse('''
+#!/bin/false
+// A normal comment.
+// @dart=2.9
+void main() {}
+''');
+    var token = testUnit.languageVersionToken!;
+    expect(token.major, 2);
+    expect(token.minor, 9);
+    expect(token.offset, 34);
+  }
+
   test_languageVersionComment_firstComment() {
     parse('''
 // @dart=2.6
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 0f8202f..a39f082 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -204,7 +204,7 @@
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpConcreteMethod(methodName, library), same(method));
   }
@@ -220,7 +220,7 @@
         ElementFactory.methodElement(methodName, intNone);
     method.isAbstract = true;
     classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpConcreteMethod(methodName, library), isNull);
   }
@@ -244,7 +244,7 @@
         ElementFactory.methodElement(methodName, intNone);
     method.isAbstract = true;
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -267,7 +267,7 @@
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpConcreteMethod(methodName, library), same(method));
   }
@@ -291,7 +291,7 @@
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpConcreteMethod(methodName, library), same(method));
   }
@@ -310,7 +310,7 @@
     classA.methods = <MethodElement>[inheritedMethod];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -321,7 +321,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpConcreteMethod("m", library), isNull);
   }
@@ -336,7 +336,7 @@
     PropertyAccessorElement getter =
         ElementFactory.getterElement(getterName, false, intNone);
     classA.accessors = <PropertyAccessorElement>[getter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpGetter(getterName, library), same(getter));
   }
@@ -355,7 +355,7 @@
     classA.accessors = <PropertyAccessorElement>[getter];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpGetter(getterName, library), same(getter));
   }
@@ -365,7 +365,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpGetter("g", library), isNull);
   }
@@ -380,7 +380,7 @@
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     classA.supertype = interfaceTypeStar(classB);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classA.lookUpGetter("g", library), isNull);
   }
@@ -395,7 +395,7 @@
     PropertyAccessorElement getter =
         ElementFactory.getterElement(getterName, false, intNone);
     classA.accessors = <PropertyAccessorElement>[getter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteGetter(getterName, library), isNull);
   }
@@ -414,7 +414,7 @@
     classA.accessors = <PropertyAccessorElement>[inheritedGetter];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteGetter(getterName, library),
         same(inheritedGetter));
@@ -425,7 +425,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
   }
@@ -440,7 +440,7 @@
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     classA.supertype = interfaceTypeStar(classB);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classA.lookUpInheritedConcreteGetter("g", library), isNull);
   }
@@ -454,7 +454,7 @@
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteMethod(methodName, library), isNull);
   }
@@ -478,7 +478,7 @@
         ElementFactory.methodElement(methodName, intNone);
     method.isAbstract = true;
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -501,7 +501,7 @@
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -526,7 +526,7 @@
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull);
   }
@@ -559,7 +559,7 @@
     MethodElementImpl method =
         ElementFactory.methodElement(methodName, intNone);
     classC.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB, classC];
     expect(classC.lookUpInheritedConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -579,7 +579,7 @@
     classA.methods = <MethodElement>[inheritedMethod];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteMethod(methodName, library),
         same(inheritedMethod));
@@ -590,7 +590,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteMethod("m", library), isNull);
   }
@@ -605,7 +605,7 @@
     PropertyAccessorElement setter =
         ElementFactory.setterElement(setterName, false, intNone);
     classA.accessors = <PropertyAccessorElement>[setter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteSetter(setterName, library), isNull);
   }
@@ -624,7 +624,7 @@
     classA.accessors = <PropertyAccessorElement>[setter];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedConcreteSetter(setterName, library),
         same(setter));
@@ -635,7 +635,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
   }
@@ -650,7 +650,7 @@
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     classA.supertype = interfaceTypeStar(classB);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classA.lookUpInheritedConcreteSetter("s", library), isNull);
   }
@@ -664,7 +664,7 @@
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedMethod(methodName, library), isNull);
   }
@@ -686,7 +686,7 @@
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classB.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedMethod(methodName, library),
         same(inheritedMethod));
@@ -706,7 +706,7 @@
     classA.methods = <MethodElement>[inheritedMethod];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpInheritedMethod(methodName, library),
         same(inheritedMethod));
@@ -717,7 +717,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpInheritedMethod("m", library), isNull);
   }
@@ -728,7 +728,7 @@
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, intNone);
     classA.methods = <MethodElement>[method];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpMethod(methodName, library), same(method));
   }
@@ -741,7 +741,7 @@
     classA.methods = <MethodElement>[method];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpMethod(methodName, library), same(method));
   }
@@ -749,7 +749,7 @@
   void test_lookUpMethod_undeclared() {
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpMethod("m", library), isNull);
   }
@@ -760,7 +760,7 @@
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     classA.supertype = interfaceTypeStar(classB);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classA.lookUpMethod("m", library), isNull);
   }
@@ -775,7 +775,7 @@
     PropertyAccessorElement setter =
         ElementFactory.setterElement(setterName, false, intNone);
     classA.accessors = <PropertyAccessorElement>[setter];
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpSetter(setterName, library), same(setter));
   }
@@ -794,7 +794,7 @@
     classA.accessors = <PropertyAccessorElement>[setter];
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classB.lookUpSetter(setterName, library), same(setter));
   }
@@ -804,7 +804,7 @@
     // }
     LibraryElementImpl library = _newLibrary();
     var classA = class_(name: 'A');
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA];
     expect(classA.lookUpSetter("s", library), isNull);
   }
@@ -819,7 +819,7 @@
     ClassElementImpl classB =
         ElementFactory.classElement("B", interfaceTypeStar(classA));
     classA.supertype = interfaceTypeStar(classB);
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classA, classB];
     expect(classA.lookUpSetter("s", library), isNull);
   }
@@ -835,7 +835,7 @@
         ElementFactory.compilationUnit("/lib.dart");
     String className = "C";
     ClassElement classElement = ElementFactory.classElement2(className);
-    unit.types = <ClassElement>[classElement];
+    unit.classes = <ClassElement>[classElement];
     expect(unit.getType(className), same(classElement));
   }
 
@@ -844,7 +844,7 @@
         ElementFactory.compilationUnit("/lib.dart");
     String className = "C";
     ClassElement classElement = ElementFactory.classElement2(className);
-    unit.types = <ClassElement>[classElement];
+    unit.classes = <ClassElement>[classElement];
     expect(unit.getType("${className}x"), isNull);
   }
 }
@@ -881,7 +881,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     ClassElementImpl classElement = ElementFactory.classElement2("C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classElement];
     FieldElement field = ElementFactory.fieldElement(
       "next",
@@ -906,7 +906,7 @@
     LibraryElementImpl library1 =
         ElementFactory.library(_analysisContext, "lib1");
     ClassElement classElement = ElementFactory.classElement2("_C");
-    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library1.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classElement];
     LibraryElementImpl library2 =
         ElementFactory.library(_analysisContext, "lib2");
@@ -917,7 +917,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     ClassElement classElement = ElementFactory.classElement2("_C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classElement];
     expect(classElement.isAccessibleIn(library), isTrue);
   }
@@ -926,7 +926,7 @@
     LibraryElementImpl library1 =
         ElementFactory.library(_analysisContext, "lib1");
     ClassElement classElement = ElementFactory.classElement2("C");
-    (library1.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library1.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classElement];
     LibraryElementImpl library2 =
         ElementFactory.library(_analysisContext, "lib2");
@@ -937,7 +937,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     ClassElement classElement = ElementFactory.classElement2("C");
-    (library.definingCompilationUnit as CompilationUnitElementImpl).types =
+    (library.definingCompilationUnit as CompilationUnitElementImpl).classes =
         <ClassElement>[classElement];
     expect(classElement.isAccessibleIn(library), isTrue);
   }
@@ -1650,7 +1650,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpGetter(getterName, library), same(getterG));
   }
 
@@ -1671,7 +1671,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeB.lookUpGetter(getterName, library), same(getterG));
   }
 
@@ -1703,7 +1706,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    unit.classes = <ClassElement>[classB, classM1, classM2, classC];
     expect(
         interfaceTypeStar(classC).lookUpGetter(getterName, library), getterM2g);
   }
@@ -1721,7 +1724,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeA.lookUpGetter("g", library), isNull);
   }
 
@@ -1735,7 +1741,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpGetter("g", library), isNull);
   }
 
@@ -1753,7 +1759,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpMethod(methodName, library), same(methodM));
   }
 
@@ -1774,7 +1780,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeB.lookUpMethod(methodName, library), same(methodM));
   }
 
@@ -1805,7 +1814,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    unit.classes = <ClassElement>[classB, classM1, classM2, classC];
     expect(
         interfaceTypeStar(classC).lookUpMethod(methodName, library), methodM2m);
   }
@@ -1836,7 +1845,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[A];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[A];
     //
     // B<I>
     //
@@ -1864,7 +1873,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeA.lookUpMethod("m", library), isNull);
   }
 
@@ -1878,7 +1890,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpMethod("m", library), isNull);
   }
 
@@ -1896,7 +1908,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpSetter(setterName, library), same(setterS));
   }
 
@@ -1917,7 +1929,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeB.lookUpSetter(setterName, library), same(setterS));
   }
 
@@ -1949,7 +1964,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     var unit = library.definingCompilationUnit as CompilationUnitElementImpl;
-    unit.types = <ClassElement>[classB, classM1, classM2, classC];
+    unit.classes = <ClassElement>[classB, classM1, classM2, classC];
     expect(
         interfaceTypeStar(classC).lookUpGetter(setterName, library), setterM2g);
   }
@@ -1967,7 +1982,10 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA, classB];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[
+      classA,
+      classB
+    ];
     expect(typeA.lookUpSetter("s", library), isNull);
   }
 
@@ -1981,7 +1999,7 @@
     LibraryElementImpl library =
         ElementFactory.library(_analysisContext, "lib");
     CompilationUnitElement unit = library.definingCompilationUnit;
-    (unit as CompilationUnitElementImpl).types = <ClassElement>[classA];
+    (unit as CompilationUnitElementImpl).classes = <ClassElement>[classA];
     expect(typeA.lookUpSetter("s", library), isNull);
   }
 
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 6f2cd6e..d3743df 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -729,14 +729,14 @@
     var element = fileResolver.getLibraryByUri(
       uriStr: 'package:dart.my/a.dart',
     );
-    expect(element.definingCompilationUnit.types, hasLength(1));
+    expect(element.definingCompilationUnit.classes, hasLength(1));
   }
 
   test_getLibraryByUri_notExistingFile() {
     var element = fileResolver.getLibraryByUri(
       uriStr: 'package:dart.my/a.dart',
     );
-    expect(element.definingCompilationUnit.types, isEmpty);
+    expect(element.definingCompilationUnit.classes, isEmpty);
   }
 
   test_getLibraryByUri_partOf() {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 108b829..0f1dc1b 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -1184,7 +1184,7 @@
     }
     e.typeAliases.forEach(writeTypeAliasElement);
     e.enums.forEach(writeClassElement);
-    e.types.forEach(writeClassElement);
+    e.classes.forEach(writeClassElement);
     e.mixins.forEach(writeClassElement);
     e.extensions.forEach(writeExtensionElement);
     e.topLevelVariables.forEach(writePropertyInducingElement);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 7260d56..c7addb5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9375,7 +9375,7 @@
   dynamic m(Stream<dynamic> p) {}
 }
 ''');
-    ClassElement b = library.definingCompilationUnit.types[0];
+    ClassElement b = library.definingCompilationUnit.classes[0];
     ParameterElement p = b.methods[0].parameters[0];
     // This test should verify that we correctly record inferred types,
     // when the type is defined in a part of an SDK library. So, test that
@@ -12835,7 +12835,7 @@
   int m() => 0;
 }
 ''');
-    var c = library.definingCompilationUnit.types.single;
+    var c = library.definingCompilationUnit.classes.single;
     var m = c.methods.single;
     expect(m.hasImplicitReturnType, isFalse);
   }
@@ -12846,7 +12846,7 @@
   m() => 0;
 }
 ''');
-    var c = library.definingCompilationUnit.types.single;
+    var c = library.definingCompilationUnit.classes.single;
     var m = c.methods.single;
     expect(m.hasImplicitReturnType, isTrue);
   }
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 0acae0a..21fa9c9 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1660,7 +1660,7 @@
   static int get _x => null;
 }
 ''');
-    var x = _resultUnitElement.types[0].fields[0];
+    var x = _resultUnitElement.classes[0].fields[0];
     _assertTypeStr(x.type, 'int');
   }
 
@@ -1671,7 +1671,7 @@
 }
 int get y => null;
 ''');
-    var x = _resultUnitElement.types[0].fields[0];
+    var x = _resultUnitElement.classes[0].fields[0];
     _assertTypeStr(x.type, 'int');
   }
 
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 5ae038a..2579b39 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -523,23 +523,22 @@
 
 ### ambiguous_set_or_map_literal_both
 
-_This literal contains both 'Map' and 'Iterable' spreads, which makes it
+_This literal contains both 'Map' and 'Iterable' elements, which makes it
 impossible to determine whether the literal is a map or a set._
 
 #### Description
 
 Because map and set literals use the same delimiters (`{` and `}`), the
 analyzer looks at the type arguments and the elements to determine which
-kind of literal you meant. When there are no type arguments and all of the
-elements are spread elements (which are allowed in both kinds of literals),
-then the analyzer uses the types of the expressions that are being spread.
-If all of the expressions have the type `Iterable`, then it's a set
-literal; if they all have the type `Map`, then it's a map literal.
+kind of literal you meant. When there are no type arguments, then the
+analyzer uses the types of the elements. If all of the expressions have the
+type `Iterable`, then it's a set literal; if they all have the type `Map`,
+then it's a map literal.
 
-The analyzer produces this diagnostic when some of the expressions being
-spread have the type `Iterable` and others have the type `Map`, making it
-impossible for the analyzer to determine whether you are writing a map
-literal or a set literal.
+The analyzer produces this diagnostic when some of the elements have the
+type `Iterable` and others have the type `Map`, making it impossible for
+the analyzer to determine whether you are writing a map literal or a set
+literal.
 
 #### Examples
 
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index c1f201f..7d3e886 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -2898,7 +2898,7 @@
         targetElement = unitResult!.declaredElement!.mixins
             .firstWhere((e) => e.name == targetMixinName);
       } else {
-        targetElement = unitResult!.declaredElement!.types
+        targetElement = unitResult!.declaredElement!.classes
             .firstWhere((e) => e.name == targetClassName);
       }
     }
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index ee3f962..f939fe1 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -154,7 +154,7 @@
       {void logger(String msg),
       ChangedStructureNotifier changedStructureNotifier}) {
     _nativeClasses ??= JsInteropChecks.getNativeClasses(component);
-    var jsUtilOptimizer = JsUtilOptimizer(coreTypes);
+    var jsUtilOptimizer = JsUtilOptimizer(coreTypes, hierarchy);
     for (var library in libraries) {
       // TODO (rileyporter): Merge js_util optimizations with other lowerings
       // in the single pass in `transformations/lowering.dart`.
diff --git a/pkg/dartdev/analysis_options.yaml b/pkg/dartdev/analysis_options.yaml
index b5b7736..3faacee 100644
--- a/pkg/dartdev/analysis_options.yaml
+++ b/pkg/dartdev/analysis_options.yaml
@@ -1,23 +1,11 @@
-include: package:pedantic/analysis_options.1.9.0.yaml
-
-analyzer:
-  errors:
-    # Increase the severity of several hints.
-    prefer_single_quotes: warning
-    unused_import: warning
-    unnecessary_brace_in_string_interps: warning
-
-    # Ignore one pedantic lint
-    omit_local_variable_types: ignore
+include: package:lints/recommended.yaml
 
 linter:
   rules:
-    - always_declare_return_types
-    - depend_on_referenced_packages
-    - directives_ordering
-    - overridden_fields
-    - prefer_single_quotes
-    - sort_pub_dependencies
-    - unnecessary_brace_in_string_interps
-    - unnecessary_overrides
-    - unnecessary_parenthesis
+    # Disable implementation_imports.
+    implementation_imports: false
+
+    # Enable additional rules.
+    depend_on_referenced_packages: true
+    directives_ordering: true
+    sort_pub_dependencies: true
diff --git a/pkg/dartdev/benchmark/bench.dart b/pkg/dartdev/benchmark/bench.dart
index fc62a89..abfeaff 100644
--- a/pkg/dartdev/benchmark/bench.dart
+++ b/pkg/dartdev/benchmark/bench.dart
@@ -34,14 +34,14 @@
   }
 
   if (!argResults.wasParsed('dart-sdk')) {
-    print('No value passed for \`dart-sdk\`.');
+    print('No value passed for `dart-sdk`.');
     print('');
     printUsage(argParser);
     io.exit(1);
   }
 
   if (!argResults.wasParsed('run')) {
-    print('No value passed for \`run\`.');
+    print('No value passed for `run`.');
     print('');
     printUsage(argParser);
     io.exit(1);
@@ -143,7 +143,7 @@
       : super(
           'run-script-startup',
           'Benchmark the startup time of a minimal Dart script, executed with '
-              '\`dart run\` (μs).',
+              '`dart run` (μs).',
         );
 
   @override
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index cbe7945..83ba6bd 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -231,6 +231,7 @@
       exitCode = 1;
     } finally {
       stopwatch.stop();
+
       if (analytics.enabled) {
         unawaited(
           analytics.sendTiming(
@@ -240,6 +241,7 @@
           ),
         );
       }
+
       // Set the exitCode, if it wasn't set in the catch block above.
       exitCode ??= 0;
 
@@ -265,7 +267,8 @@
         analytics.enabled = true;
       }
       analytics.close();
-      return exitCode;
     }
+
+    return exitCode;
   }
 }
diff --git a/pkg/dartdev/lib/src/commands/analyze.dart b/pkg/dartdev/lib/src/commands/analyze.dart
index 254a780..a4c02be 100644
--- a/pkg/dartdev/lib/src/commands/analyze.dart
+++ b/pkg/dartdev/lib/src/commands/analyze.dart
@@ -207,7 +207,7 @@
       }
 
       // Emit "file:line:col * Error message. Correction (code)."
-      var message = ansi.emphasized('${error.message}');
+      var message = ansi.emphasized(error.message);
       if (error.correction != null) {
         message += ' ${error.correction}';
       }
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index c053a29..60d2e46 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -128,12 +128,12 @@
       var fileCount = 0;
       var fixCount = 0;
 
-      details.forEach((d) {
+      for (var d in details) {
         ++fileCount;
-        d.fixes.forEach((f) {
+        for (var f in d.fixes) {
           fixCount += f.occurrences;
-        });
-      });
+        }
+      }
 
       if (dryRun) {
         log.stdout('');
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index c4bd9f1..22e9e1a 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -110,10 +110,9 @@
       );
 
     if (verbose) {
-      argParser
-        ..addSeparator(
-          'Advanced options:',
-        );
+      argParser.addSeparator(
+        'Advanced options:',
+      );
     }
     argParser
       ..addMultiOption(
diff --git a/pkg/dartdev/lib/src/events.dart b/pkg/dartdev/lib/src/events.dart
index 26e47df..eb30e78 100644
--- a/pkg/dartdev/lib/src/events.dart
+++ b/pkg/dartdev/lib/src/events.dart
@@ -64,7 +64,7 @@
   specifiedExperiments = specifiedExperiments?.toList() ?? [];
 
   // Sort the flag lists to slightly reduce the explosion of possibilities.
-  commandFlags..sort();
+  commandFlags.sort();
   specifiedExperiments.sort();
 
   // Insert a seperator before and after the flags list to make it easier to filter
diff --git a/pkg/dartdev/lib/src/templates/console_full.dart b/pkg/dartdev/lib/src/templates/console_full.dart
index f2e8b7a..5797c9a 100644
--- a/pkg/dartdev/lib/src/templates/console_full.dart
+++ b/pkg/dartdev/lib/src/templates/console_full.dart
@@ -26,7 +26,7 @@
   @override
   String getInstallInstructions(
     String directory,
-    String scriptName,
+    String scriptPath,
   ) =>
       super.getInstallInstructions(directory, null);
 }
diff --git a/pkg/dartdev/lib/src/templates/console_simple.dart b/pkg/dartdev/lib/src/templates/console_simple.dart
index a90c2ef6..376249b 100644
--- a/pkg/dartdev/lib/src/templates/console_simple.dart
+++ b/pkg/dartdev/lib/src/templates/console_simple.dart
@@ -24,7 +24,7 @@
   @override
   String getInstallInstructions(
     String directory,
-    String scriptName,
+    String scriptPath,
   ) =>
       super.getInstallInstructions(directory, null);
 }
diff --git a/pkg/dartdev/lib/src/templates/package_simple.dart b/pkg/dartdev/lib/src/templates/package_simple.dart
index 9d9eb59..651e5e4 100644
--- a/pkg/dartdev/lib/src/templates/package_simple.dart
+++ b/pkg/dartdev/lib/src/templates/package_simple.dart
@@ -27,11 +27,11 @@
   @override
   String getInstallInstructions(
     String directory,
-    String projectName,
+    String scriptPath,
   ) =>
       super.getInstallInstructions(
         directory,
-        'example/${projectName}_example',
+        'example/${scriptPath}_example',
       );
 }
 
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index 97794bb..45873bc 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -27,7 +27,7 @@
   @override
   String getInstallInstructions(
     String directory,
-    String scriptName,
+    String scriptPath,
   ) =>
       super.getInstallInstructions(
         directory,
diff --git a/pkg/dartdev/lib/src/templates/web_simple.dart b/pkg/dartdev/lib/src/templates/web_simple.dart
index 73ae51a..4bceae1 100644
--- a/pkg/dartdev/lib/src/templates/web_simple.dart
+++ b/pkg/dartdev/lib/src/templates/web_simple.dart
@@ -28,7 +28,7 @@
   @override
   String getInstallInstructions(
     String directory,
-    String scriptName,
+    String scriptPath,
   ) =>
       '  cd ${p.relative(directory)}\n'
       '  dart pub global activate webdev\n'
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index 20071f4..3887bdf 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -32,6 +32,7 @@
   usage: ^3.4.0
 
 dev_dependencies:
+  lints: any
   pub_semver: any
   test: ^1.0.0
   yaml: any
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 0982a0c..5af3323 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -141,7 +141,7 @@
 
   // Create tests for each template.
   for (String templateId in CreateCommand.legalTemplateIds) {
-    test('$templateId', () {
+    test(templateId, () {
       p = project();
       const projectName = 'template_project';
       ProcessResult result = p.runSync([
diff --git a/pkg/dds/test/dap/integration/debug_logging_test.dart b/pkg/dds/test/dap/integration/debug_logging_test.dart
index 1fc81bc1..1df090c 100644
--- a/pkg/dds/test/dap/integration/debug_logging_test.dart
+++ b/pkg/dds/test/dap/integration/debug_logging_test.dart
@@ -31,6 +31,7 @@
           'Exited.',
         ]);
       });
-    });
+      // These tests can be slow due to starting up the external server process.
+    }, timeout: Timeout.none);
   });
 }
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index a934e42..f205ed5 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -42,6 +42,7 @@
           'Exited.',
         ]);
       });
-    });
+      // These tests can be slow due to starting up the external server process.
+    }, timeout: Timeout.none);
   });
 }
diff --git a/pkg/dds/test/dap/integration/no_debug_test.dart b/pkg/dds/test/dap/integration/no_debug_test.dart
index 72509b0..e9f5dd2 100644
--- a/pkg/dds/test/dap/integration/no_debug_test.dart
+++ b/pkg/dds/test/dap/integration/no_debug_test.dart
@@ -35,6 +35,7 @@
           'Exited.',
         ]);
       });
-    });
+      // These tests can be slow due to starting up the external server process.
+    }, timeout: Timeout.none);
   });
 }
diff --git a/pkg/dds/test/dap/integration/test_server.dart b/pkg/dds/test/dap/integration/test_server.dart
index 7e4c526..003e83c 100644
--- a/pkg/dds/test/dap/integration/test_server.dart
+++ b/pkg/dds/test/dap/integration/test_server.dart
@@ -15,6 +15,7 @@
   String get host;
   int get port;
   FutureOr<void> stop();
+  List<String> get errorLogs;
 }
 
 /// An instance of a DAP server running in-process (to aid debugging).
@@ -29,6 +30,7 @@
 
   String get host => _server.host;
   int get port => _server.port;
+  List<String> get errorLogs => const []; // In-proc errors just throw in-line.
 
   @override
   FutureOr<void> stop() async {
@@ -56,16 +58,24 @@
   final Process _process;
   final int port;
   final String host;
+  final List<String> _errors = [];
+
+  List<String> get errorLogs => _errors;
 
   OutOfProcessDapTestServer._(this._process, this.host, this.port) {
     // The DAP server should generally not write to stdout/stderr (unless -v is
     // passed), but it may do if it fails to start or crashes. If this happens,
     // ensure these are included in the test output.
     _process.stdout.transform(utf8.decoder).listen(print);
-    _process.stderr.transform(utf8.decoder).listen((s) => throw s);
+    _process.stderr.transform(utf8.decoder).listen((s) {
+      _errors.add(s);
+      throw s;
+    });
     unawaited(_process.exitCode.then((code) {
+      final message = 'Out-of-process DAP server terminated with code $code';
+      _errors.add(message);
       if (!_isShuttingDown && code != 0) {
-        throw 'Out-of-process DAP server terminated with code $code';
+        throw message;
       }
     }));
   }
diff --git a/pkg/dds/test/dap/integration/test_support.dart b/pkg/dds/test/dap/integration/test_support.dart
index 7c66534..71190fe 100644
--- a/pkg/dds/test/dap/integration/test_support.dart
+++ b/pkg/dds/test/dap/integration/test_support.dart
@@ -80,8 +80,10 @@
   FutureOr<DapTestClient> _startClient(DapTestServer server) async {
     // Since we don't get a signal from the DAP server when it's ready and we
     // just started it, add a short retry to connections.
+    // Since the bots can be quite slow, it may take 6-7 seconds for the server
+    // to initially start up (including compilation).
     var attempt = 1;
-    while (attempt++ <= 20) {
+    while (attempt++ <= 100) {
       try {
         return await DapTestClient.connect(server.port);
       } catch (e) {
@@ -89,8 +91,19 @@
       }
     }
 
-    throw 'Failed to connect to DAP server on port ${server.port}'
-        ' after $attempt attempts. Did the server start correctly?';
+    final errorMessage = StringBuffer();
+    errorMessage.writeln(
+      'Failed to connect to DAP server on port ${server.port}'
+      ' after $attempt attempts. Did the server start correctly?',
+    );
+
+    final serverErrorLogs = server.errorLogs;
+    if (serverErrorLogs.isNotEmpty) {
+      errorMessage.writeln('Server errors:');
+      errorMessage.writeAll(serverErrorLogs);
+    }
+
+    throw Exception(errorMessage.toString());
   }
 
   /// Starts a DAP server that can be shared across tests.
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index c7c4e10..627f50a 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -159,7 +159,7 @@
       {void Function(String msg) logger,
       ChangedStructureNotifier changedStructureNotifier}) {
     _nativeClasses ??= JsInteropChecks.getNativeClasses(component);
-    var jsUtilOptimizer = JsUtilOptimizer(coreTypes);
+    var jsUtilOptimizer = JsUtilOptimizer(coreTypes, hierarchy);
     for (var library in libraries) {
       _CovarianceTransformer(library).transform();
       jsUtilOptimizer.visitLibrary(library);
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 4b3a9b0..5881625 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -38,8 +38,6 @@
 import 'src/javascript_bundle.dart';
 import 'src/strong_components.dart';
 
-export 'src/to_string_transformer.dart';
-
 ArgParser argParser = ArgParser(allowTrailingOptions: true)
   ..addFlag('train',
       help: 'Run through sample command line to produce snapshot',
diff --git a/pkg/frontend_server/lib/src/to_string_transformer.dart b/pkg/frontend_server/lib/src/to_string_transformer.dart
deleted file mode 100644
index c8c2ae2..0000000
--- a/pkg/frontend_server/lib/src/to_string_transformer.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// 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.
-
-import 'package:kernel/ast.dart';
-import '../frontend_server.dart';
-
-// Transformer/visitor for toString
-// If we add any more of these, they really should go into a separate library.
-
-/// A [RecursiveVisitor] that replaces [Object.toString] overrides with
-/// `super.toString()`.
-class ToStringVisitor extends RecursiveVisitor {
-  /// The [packageUris] must not be null.
-  ToStringVisitor(this._packageUris) : assert(_packageUris != null);
-
-  /// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
-  /// 'package:flutter/foundation.dart'.
-  final Set<String> _packageUris;
-
-  /// Turn 'dart:ui' into 'dart:ui', or
-  /// 'package:flutter/src/semantics_event.dart' into 'package:flutter'.
-  String _importUriToPackage(Uri importUri) =>
-      '${importUri.scheme}:${importUri.pathSegments.first}';
-
-  bool _isInTargetPackage(Procedure node) {
-    return _packageUris
-        .contains(_importUriToPackage(node.enclosingLibrary.importUri));
-  }
-
-  bool _hasKeepAnnotation(Procedure node) {
-    for (ConstantExpression expression
-        in node.annotations.whereType<ConstantExpression>()) {
-      if (expression.constant is! InstanceConstant) {
-        continue;
-      }
-      final InstanceConstant constant = expression.constant as InstanceConstant;
-      if (constant.classNode.name == '_KeepToString' &&
-          constant.classNode.enclosingLibrary.importUri.toString() ==
-              'dart:ui') {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  void visitProcedure(Procedure node) {
-    if (node.name.text == 'toString' &&
-        node.enclosingClass != null &&
-        node.enclosingLibrary != null &&
-        !node.isStatic &&
-        !node.isAbstract &&
-        !node.enclosingClass.isEnum &&
-        _isInTargetPackage(node) &&
-        !_hasKeepAnnotation(node)) {
-      node.function.body.replaceWith(
-        ReturnStatement(
-          SuperMethodInvocation(
-            node.name,
-            Arguments(<Expression>[]),
-          ),
-        ),
-      );
-    }
-  }
-
-  @override
-  void defaultMember(Member node) {}
-}
-
-/// Replaces [Object.toString] overrides with calls to super for the specified
-/// [packageUris].
-class ToStringTransformer extends ProgramTransformer {
-  /// The [packageUris] parameter must not be null, but may be empty.
-  ToStringTransformer(this._child, this._packageUris)
-      : assert(_packageUris != null);
-
-  final ProgramTransformer _child;
-
-  /// A set of package URIs to apply this transformer to, e.g. 'dart:ui' and
-  /// 'package:flutter/foundation.dart'.
-  final Set<String> _packageUris;
-
-  @override
-  void transform(Component component) {
-    assert(_child is! ToStringTransformer);
-    if (_packageUris.isNotEmpty) {
-      component.visitChildren(ToStringVisitor(_packageUris));
-    }
-    _child?.transform(component);
-  }
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 8a80c28..fa9952ce5 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -129,6 +129,7 @@
 analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test: Slow, Pass
 analyzer_plugin/test/src/utilities/completion/optype_test: Slow, Pass
 dartdev/test/*: Slow, Pass
+dds/test/dap/integration/*: Slow, Pass
 
 [ $runtime != vm ]
 dds/test/*: SkipByDesign # Only meant to run on vm
diff --git a/pkg/vm/lib/transformations/to_string_transformer.dart b/pkg/vm/lib/transformations/to_string_transformer.dart
index 2931251..10e7575 100644
--- a/pkg/vm/lib/transformations/to_string_transformer.dart
+++ b/pkg/vm/lib/transformations/to_string_transformer.dart
@@ -39,9 +39,6 @@
       final className = constant.classNode.name;
       final libraryUri =
           constant.classNode.enclosingLibrary.importUri.toString();
-      if (className == '_KeepToString' && libraryUri == 'dart:ui') {
-        return true;
-      }
       if (className == 'pragma' && libraryUri == 'dart:core') {
         for (var fieldRef in constant.fieldValues.keys) {
           if (fieldRef.asField.name.text == 'name') {
diff --git a/runtime/bin/crypto_win.cc b/runtime/bin/crypto_win.cc
index 23d52ef..4233e98 100644
--- a/runtime/bin/crypto_win.cc
+++ b/runtime/bin/crypto_win.cc
@@ -11,9 +11,18 @@
 namespace dart {
 namespace bin {
 
+// see https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
+#ifndef NT_SUCCESS
+#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
+#endif
+
 bool Crypto::GetRandomBytes(intptr_t count, uint8_t* buffer) {
-  return SUCCEEDED(BCryptGenRandom(NULL, buffer, (ULONG)count,
-                                   BCRYPT_USE_SYSTEM_PREFERRED_RNG));
+  if (count <= 0) {
+    return true;
+  }
+  return NT_SUCCESS(BCryptGenRandom(/*hAlgorithm=*/nullptr, buffer,
+                                    (ULONG)count,
+                                    BCRYPT_USE_SYSTEM_PREFERRED_RNG));
 }
 
 }  // namespace bin
diff --git a/runtime/tests/vm/dart/regress_46141_test.dart b/runtime/tests/vm/dart/regress_46141_test.dart
new file mode 100644
index 0000000..5ffc588
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_46141_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/46141.
+// Verifies that unboxing of phi corresponding to a late variable doesn't
+// happen.
+
+// VMOptions=--deterministic
+
+import 'package:expect/expect.dart';
+
+final values = List.filled(100, 0.0);
+
+double? fn(double day) {
+  double? last;
+  late int lastDay;
+
+  int i = 0;
+  while (i < values.length) {
+    final t = values[i];
+    if (day > 95) {
+      print(lastDay);
+      break;
+    }
+    last = t;
+    lastDay = i;
+    i++;
+  }
+  return last;
+}
+
+void main() {
+  for (int i = 0; i < values.length; i++) {
+    bool wasError = false;
+    try {
+      fn(i.toDouble());
+    } on Error {
+      wasError = true;
+    }
+    Expect.isTrue(wasError == (i > 95));
+  }
+}
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 5e2b4c7..bfa05f5 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -217,6 +217,8 @@
   kNumPredefinedCids,
 };
 
+constexpr ClassId kSentinelCid = kNeverCid;
+
 // Keep these in sync with the cid numbering above.
 const int kTypedDataCidRemainderInternal = 0;
 const int kTypedDataCidRemainderView = 1;
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 9d81af6..4b6bffd 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -27,6 +27,8 @@
 // It captures the following properties:
 //    - whether the value can potentially be null or if it is definitely not
 //      null;
+//    - whether the value can potentially be sentinel or if it is definitely
+//      not sentinel;
 //    - concrete class id of the value or kDynamicCid if unknown statically;
 //    - abstract super type of the value, where the concrete type of the value
 //      in runtime is guaranteed to be sub type of this type.
@@ -36,27 +38,42 @@
 // operation for the lattice.
 class CompileType : public ZoneAllocated {
  public:
-  static const bool kNullable = true;
-  static const bool kNonNullable = false;
+  static constexpr bool kCanBeNull = true;
+  static constexpr bool kCannotBeNull = false;
 
-  CompileType(bool is_nullable, intptr_t cid, const AbstractType* type)
-      : is_nullable_(is_nullable), cid_(cid), type_(type) {}
+  static constexpr bool kCanBeSentinel = true;
+  static constexpr bool kCannotBeSentinel = false;
+
+  CompileType(bool can_be_null,
+              bool can_be_sentinel,
+              intptr_t cid,
+              const AbstractType* type)
+      : can_be_null_(can_be_null),
+        can_be_sentinel_(can_be_sentinel),
+        cid_(cid),
+        type_(type) {}
 
   CompileType(const CompileType& other)
       : ZoneAllocated(),
-        is_nullable_(other.is_nullable_),
+        can_be_null_(other.can_be_null_),
+        can_be_sentinel_(other.can_be_sentinel_),
         cid_(other.cid_),
         type_(other.type_) {}
 
   CompileType& operator=(const CompileType& other) {
     // This intentionally does not change the owner of this type.
-    is_nullable_ = other.is_nullable_;
+    can_be_null_ = other.can_be_null_;
+    can_be_sentinel_ = other.can_be_sentinel_;
     cid_ = other.cid_;
     type_ = other.type_;
     return *this;
   }
 
-  bool is_nullable() const { return is_nullable_; }
+  bool is_nullable() const { return can_be_null_; }
+
+  // Return true if value of this type can be Object::sentinel().
+  // Such values cannot be unboxed.
+  bool can_be_sentinel() const { return can_be_sentinel_; }
 
   // Return type such that concrete value's type in runtime is guaranteed to
   // be subtype of it.
@@ -88,10 +105,6 @@
   // against given type.
   bool IsInstanceOf(const AbstractType& other);
 
-  // Create a new CompileType representing given combination of class id and
-  // abstract type. The pair is assumed to be coherent.
-  static CompileType Create(intptr_t cid, const AbstractType& type);
-
   // Return the non-nullable version of this type.
   CompileType CopyNonNullable() {
     if (IsNull()) {
@@ -100,28 +113,32 @@
       return None();
     }
 
-    return CompileType(kNonNullable, cid_, type_);
+    return CompileType(kCannotBeNull, can_be_sentinel_, cid_, type_);
   }
 
-  static CompileType CreateNullable(bool is_nullable, intptr_t cid) {
-    return CompileType(is_nullable, cid, nullptr);
+  // Return the non-sentinel version of this type.
+  CompileType CopyNonSentinel() {
+    return CompileType(can_be_null_, kCannotBeSentinel, cid_, type_);
   }
 
   // Create a new CompileType representing given abstract type.
   // By default nullability of values is determined by type.
   // CompileType can be further constrained to non-nullable values by
-  // passing kNonNullable as an optional parameter.
+  // passing kCannotBeNull as |can_be_null| parameter.
   static CompileType FromAbstractType(const AbstractType& type,
-                                      bool is_nullable = kNullable);
+                                      bool can_be_null,
+                                      bool can_be_sentinel);
 
   // Create a new CompileType representing a value with the given class id.
-  // Resulting CompileType is nullable only if cid is kDynamicCid or kNullCid.
+  // Resulting CompileType can be null only if cid is kDynamicCid or kNullCid.
+  // Resulting CompileType can be sentinel only if cid is kDynamicCid or
+  // kSentinelCid.
   static CompileType FromCid(intptr_t cid);
 
   // Create None CompileType. It is the bottom of the lattice and is used to
   // represent type of the phi that was not yet inferred.
   static CompileType None() {
-    return CompileType(kNullable, kIllegalCid, nullptr);
+    return CompileType(kCanBeNull, kCanBeSentinel, kIllegalCid, nullptr);
   }
 
   // Create Dynamic CompileType. It is the top of the lattice and is used to
@@ -147,12 +164,12 @@
 
   // Create nullable Smi type.
   static CompileType NullableSmi() {
-    return CreateNullable(kNullable, kSmiCid);
+    return CompileType(kCanBeNull, kCannotBeSentinel, kSmiCid, nullptr);
   }
 
   // Create nullable Mint type.
   static CompileType NullableMint() {
-    return CreateNullable(kNullable, kMintCid);
+    return CompileType(kCanBeNull, kCannotBeSentinel, kMintCid, nullptr);
   }
 
   // Create non-nullable Double type.
@@ -175,7 +192,8 @@
 
   // Return true if this and other types are the same.
   bool IsEqualTo(CompileType* other) {
-    return (is_nullable_ == other->is_nullable_) &&
+    return (can_be_null_ == other->can_be_null_) &&
+           (can_be_sentinel_ == other->can_be_sentinel_) &&
            (ToNullableCid() == other->ToNullableCid()) &&
            (compiler::IsEqualType(*ToAbstractType(), *other->ToAbstractType()));
   }
@@ -258,7 +276,8 @@
   Definition* owner() const { return owner_; }
 
  private:
-  bool is_nullable_;
+  bool can_be_null_;
+  bool can_be_sentinel_;
   classid_t cid_;
   const AbstractType* type_;
   Definition* owner_ = nullptr;
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 52c25a2..0ccabb1 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1479,8 +1479,9 @@
             // Check if phi corresponds to the same slot.
             auto* phis = phi->block()->phis();
             if ((index < phis->length()) && (*phis)[index] == phi) {
-              phi->UpdateType(
-                  CompileType::FromAbstractType(load->local().type()));
+              phi->UpdateType(CompileType::FromAbstractType(
+                  load->local().type(), CompileType::kCanBeNull,
+                  /*can_be_sentinel=*/load->local().is_late()));
             } else {
               ASSERT(IsCompiledForOsr() && (phi->block()->stack_depth() > 0));
             }
@@ -2006,7 +2007,8 @@
     }
   }
 
-  if ((unboxed == kTagged) && phi->Type()->IsInt()) {
+  if ((unboxed == kTagged) && phi->Type()->IsInt() &&
+      !phi->Type()->can_be_sentinel()) {
     // Conservatively unbox phis that:
     //   - are proven to be of type Int;
     //   - fit into 64bits range;
@@ -2059,6 +2061,7 @@
   // to how we treat doubles and other boxed numeric types).
   // In JIT mode only unbox phis which are not fully known to be Smi.
   if ((unboxed == kTagged) && phi->Type()->IsInt() &&
+      !phi->Type()->can_be_sentinel() &&
       (is_aot || phi->Type()->ToCid() != kSmiCid)) {
     unboxed = kUnboxedInt64;
   }
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
index 00baa85..8f82bb1 100644
--- a/runtime/vm/compiler/backend/flow_graph_test.cc
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -81,4 +81,69 @@
 }
 #endif  // defined(TARGET_ARCH_IS_64_BIT)
 
+ISOLATE_UNIT_TEST_CASE(FlowGraph_LateVariablePhiUnboxing) {
+  using compiler::BlockBuilder;
+
+  CompilerState S(thread, /*is_aot=*/true, /*is_optimizing=*/true);
+  FlowGraphBuilderHelper H;
+
+  auto normal_entry = H.flow_graph()->graph_entry()->normal_entry();
+  auto loop_header = H.JoinEntry();
+  auto loop_body = H.TargetEntry();
+  auto loop_exit = H.TargetEntry();
+
+  ConstantInstr* sentinel = H.flow_graph()->GetConstant(Object::sentinel());
+
+  PhiInstr* loop_var;
+  PhiInstr* late_var;
+  Definition* add1;
+
+  {
+    BlockBuilder builder(H.flow_graph(), normal_entry);
+    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_header);
+    loop_var = H.Phi(loop_header,
+                     {{normal_entry, H.IntConstant(0)}, {loop_body, &add1}});
+    builder.AddPhi(loop_var);
+    loop_var->UpdateType(CompileType::Int());
+    loop_var->UpdateType(CompileType::FromAbstractType(
+        Type::ZoneHandle(Type::IntType()), CompileType::kCannotBeNull,
+        CompileType::kCanBeSentinel));
+    late_var =
+        H.Phi(loop_header, {{normal_entry, sentinel}, {loop_body, &add1}});
+    builder.AddPhi(late_var);
+    builder.AddBranch(new RelationalOpInstr(
+                          InstructionSource(), Token::kLT, new Value(loop_var),
+                          new Value(H.IntConstant(10)), kMintCid,
+                          S.GetNextDeoptId(), Instruction::kNotSpeculative),
+                      loop_body, loop_exit);
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_body);
+    add1 = builder.AddDefinition(new BinaryInt64OpInstr(
+        Token::kADD, new Value(loop_var), new Value(H.IntConstant(1)),
+        S.GetNextDeoptId(), Instruction::kNotSpeculative));
+    builder.AddInstruction(new GotoInstr(loop_header, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(H.flow_graph(), loop_exit);
+    builder.AddReturn(new Value(late_var));
+  }
+
+  H.FinishGraph();
+
+  FlowGraphTypePropagator::Propagate(H.flow_graph());
+  H.flow_graph()->SelectRepresentations();
+
+#if defined(TARGET_ARCH_IS_64_BIT)
+  EXPECT_PROPERTY(loop_var, it.representation() == kUnboxedInt64);
+#endif
+  EXPECT_PROPERTY(late_var, it.representation() == kTagged);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index aefb2d4..ece5752 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -299,7 +299,8 @@
       Slot(Kind::kCapturedVariable,
            IsImmutableBit::encode(variable.is_final() && !variable.is_late()) |
                IsNullableBit::encode(true) |
-               IsCompressedBit::encode(Context::ContainsCompressedPointers()),
+               IsCompressedBit::encode(Context::ContainsCompressedPointers()) |
+               IsSentinelVisibleBit::encode(variable.is_late()),
            kDynamicCid,
            compiler::target::Context::variable_offset(variable.index().value()),
            &variable.name(), &variable.type(), kTagged));
@@ -382,16 +383,18 @@
   }
 
   Class& owner = Class::Handle(zone, field.Owner());
-  const Slot& slot = SlotCache::Instance(thread).Canonicalize(
-      Slot(Kind::kDartField,
-           IsImmutableBit::encode((field.is_final() && !field.is_late()) ||
-                                  field.is_const()) |
-               IsNullableBit::encode(is_nullable) |
-               IsGuardedBit::encode(used_guarded_state) |
-               IsCompressedBit::encode(
-                   compiler::target::Class::HasCompressedPointers(owner)),
-           nullable_cid, compiler::target::Field::OffsetOf(field), &field,
-           &type, rep));
+  const Slot& slot = SlotCache::Instance(thread).Canonicalize(Slot(
+      Kind::kDartField,
+      IsImmutableBit::encode((field.is_final() && !field.is_late()) ||
+                             field.is_const()) |
+          IsNullableBit::encode(is_nullable) |
+          IsGuardedBit::encode(used_guarded_state) |
+          IsCompressedBit::encode(
+              compiler::target::Class::HasCompressedPointers(owner)) |
+          IsSentinelVisibleBit::encode(field.is_late() && field.is_final() &&
+                                       !field.has_initializer()),
+      nullable_cid, compiler::target::Field::OffsetOf(field), &field, &type,
+      rep));
 
   // If properties of this slot were based on the guarded state make sure
   // to add the field to the list of guarded fields. Note that during background
@@ -452,7 +455,7 @@
       break;
   }
 
-  return CompileType(is_nullable(), nullable_cid(),
+  return CompileType(is_nullable(), is_sentinel_visible(), nullable_cid(),
                      nullable_cid() == kDynamicCid ? static_type_ : nullptr);
 }
 
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 221e371..43a27cc 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -261,6 +261,11 @@
 
   bool is_compressed() const { return IsCompressedBit::decode(flags_); }
 
+  // Returns true if load from this slot can return sentinel value.
+  bool is_sentinel_visible() const {
+    return IsSentinelVisibleBit::decode(flags_);
+  }
+
   // Static type of the slots if any.
   //
   // A value that is read from the slot is guaranteed to be assignable to its
@@ -316,6 +321,8 @@
   using IsNullableBit = BitField<int8_t, bool, IsImmutableBit::kNextBit, 1>;
   using IsGuardedBit = BitField<int8_t, bool, IsNullableBit::kNextBit, 1>;
   using IsCompressedBit = BitField<int8_t, bool, IsGuardedBit::kNextBit, 1>;
+  using IsSentinelVisibleBit =
+      BitField<int8_t, bool, IsCompressedBit::kNextBit, 1>;
 
   template <typename T>
   const T* DataAs() const {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 554ea11..8ff2339 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -361,7 +361,9 @@
       (current->is_nullable() && !guard->field().is_nullable())) {
     const bool is_nullable =
         guard->field().is_nullable() && current->is_nullable();
-    SetTypeOf(def, new (zone()) CompileType(is_nullable, cid, NULL));
+    SetTypeOf(def,
+              new (zone()) CompileType(
+                  is_nullable, CompileType::kCannotBeSentinel, cid, nullptr));
   }
 }
 
@@ -422,11 +424,12 @@
     if (!type->IsTopTypeForInstanceOf()) {
       const bool is_nullable = (type->IsNullable() || type->IsTypeParameter() ||
                                 (type->IsNeverType() && type->IsLegacy()))
-                                   ? CompileType::kNullable
-                                   : CompileType::kNonNullable;
+                                   ? CompileType::kCanBeNull
+                                   : CompileType::kCannotBeNull;
       EnsureMoreAccurateRedefinition(
           true_successor, left,
-          CompileType::FromAbstractType(*type, is_nullable));
+          CompileType::FromAbstractType(*type, is_nullable,
+                                        CompileType::kCannotBeSentinel));
     }
   } else if (comparison->InputAt(0)->BindsToConstant() &&
              comparison->InputAt(0)->BoundConstant().IsNull()) {
@@ -445,6 +448,25 @@
     EnsureMoreAccurateRedefinition(
         true_successor, comparison->InputAt(0)->definition(),
         comparison->InputAt(0)->Type()->CopyNonNullable());
+  } else if (comparison->InputAt(0)->BindsToConstant() &&
+             comparison->InputAt(0)->BoundConstant().ptr() ==
+                 Object::sentinel().ptr()) {
+    // Handle for expr != sentinel.
+    BlockEntryInstr* true_successor =
+        negated ? instr->true_successor() : instr->false_successor();
+    EnsureMoreAccurateRedefinition(
+        true_successor, comparison->InputAt(1)->definition(),
+        comparison->InputAt(1)->Type()->CopyNonSentinel());
+
+  } else if (comparison->InputAt(1)->BindsToConstant() &&
+             comparison->InputAt(1)->BoundConstant().ptr() ==
+                 Object::sentinel().ptr()) {
+    // Handle for sentinel != expr.
+    BlockEntryInstr* true_successor =
+        negated ? instr->true_successor() : instr->false_successor();
+    EnsureMoreAccurateRedefinition(
+        true_successor, comparison->InputAt(0)->definition(),
+        comparison->InputAt(0)->Type()->CopyNonSentinel());
   }
   // TODO(fschneider): Add propagation for generic is-tests.
 }
@@ -543,21 +565,23 @@
     return;
   }
 
-  is_nullable_ = is_nullable_ || other->is_nullable_;
+  can_be_null_ = can_be_null_ || other->can_be_null_;
+  can_be_sentinel_ = can_be_sentinel_ || other->can_be_sentinel_;
 
-  if (ToNullableCid() == kNullCid) {
+  ToNullableCid();  // Ensure cid_ is set.
+  if ((cid_ == kNullCid) || (cid_ == kSentinelCid)) {
     cid_ = other->cid_;
     type_ = other->type_;
     return;
   }
 
-  if (other->ToNullableCid() == kNullCid) {
+  other->ToNullableCid();  // Ensure other->cid_ is set.
+  if ((other->cid_ == kNullCid) || (other->cid_ == kSentinelCid)) {
     return;
   }
 
   const AbstractType* abstract_type = ToAbstractType();
-  if (ToNullableCid() != other->ToNullableCid()) {
-    ASSERT(cid_ != kNullCid);
+  if (cid_ != other->cid_) {
     cid_ = kDynamicCid;
   }
 
@@ -625,50 +649,53 @@
     preferred_type = new_type;
   }
 
-  // Refine non-nullability.
-  bool is_nullable = old_type->is_nullable() && new_type->is_nullable();
+  // Refine non-nullability and whether it can be sentinel.
+  const bool can_be_null = old_type->is_nullable() && new_type->is_nullable();
+  const bool can_be_sentinel =
+      old_type->can_be_sentinel() && new_type->can_be_sentinel();
 
-  if (preferred_type->is_nullable() && !is_nullable) {
-    return new CompileType(preferred_type->CopyNonNullable());
+  if ((preferred_type->is_nullable() && !can_be_null) ||
+      (preferred_type->can_be_sentinel() && !can_be_sentinel)) {
+    return new CompileType(can_be_null, can_be_sentinel, preferred_type->cid_,
+                           preferred_type->type_);
   } else {
-    ASSERT(preferred_type->is_nullable() == is_nullable);
+    ASSERT(preferred_type->is_nullable() == can_be_null);
+    ASSERT(preferred_type->can_be_sentinel() == can_be_sentinel);
     return preferred_type;
   }
 }
 
-static bool IsNullableCid(intptr_t cid) {
-  ASSERT(cid != kIllegalCid);
-  return cid == kNullCid || cid == kDynamicCid;
-}
-
-CompileType CompileType::Create(intptr_t cid, const AbstractType& type) {
-  return CompileType(IsNullableCid(cid), cid, &type);
-}
-
 CompileType CompileType::FromAbstractType(const AbstractType& type,
-                                          bool is_nullable) {
-  return CompileType(is_nullable && !type.IsStrictlyNonNullable(), kIllegalCid,
-                     &type);
+                                          bool can_be_null,
+                                          bool can_be_sentinel) {
+  return CompileType(can_be_null && !type.IsStrictlyNonNullable(),
+                     can_be_sentinel, kIllegalCid, &type);
 }
 
 CompileType CompileType::FromCid(intptr_t cid) {
-  return CompileType(IsNullableCid(cid), cid, NULL);
+  ASSERT(cid != kIllegalCid);
+  ASSERT(cid != kDynamicCid);
+  return CompileType(cid == kNullCid, cid == kSentinelCid, cid, nullptr);
 }
 
 CompileType CompileType::Dynamic() {
-  return Create(kDynamicCid, Object::dynamic_type());
+  return CompileType(kCanBeNull, kCannotBeSentinel, kDynamicCid,
+                     &Object::dynamic_type());
 }
 
 CompileType CompileType::Null() {
-  return Create(kNullCid, Type::ZoneHandle(Type::NullType()));
+  return CompileType(kCanBeNull, kCannotBeSentinel, kNullCid,
+                     &Type::ZoneHandle(Type::NullType()));
 }
 
 CompileType CompileType::Bool() {
-  return Create(kBoolCid, Type::ZoneHandle(Type::BoolType()));
+  return CompileType(kCannotBeNull, kCannotBeSentinel, kBoolCid,
+                     &Type::ZoneHandle(Type::BoolType()));
 }
 
 CompileType CompileType::Int() {
-  return FromAbstractType(Type::ZoneHandle(Type::IntType()), kNonNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::IntType()), kCannotBeNull,
+                          kCannotBeSentinel);
 }
 
 CompileType CompileType::Int32() {
@@ -680,23 +707,28 @@
 }
 
 CompileType CompileType::NullableInt() {
-  return FromAbstractType(Type::ZoneHandle(Type::NullableIntType()), kNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::NullableIntType()), kCanBeNull,
+                          kCannotBeSentinel);
 }
 
 CompileType CompileType::Smi() {
-  return Create(kSmiCid, Type::ZoneHandle(Type::SmiType()));
+  return CompileType(kCannotBeNull, kCannotBeSentinel, kSmiCid,
+                     &Type::ZoneHandle(Type::SmiType()));
 }
 
 CompileType CompileType::Double() {
-  return Create(kDoubleCid, Type::ZoneHandle(Type::Double()));
+  return CompileType(kCannotBeNull, kCannotBeSentinel, kDoubleCid,
+                     &Type::ZoneHandle(Type::Double()));
 }
 
 CompileType CompileType::NullableDouble() {
-  return FromAbstractType(Type::ZoneHandle(Type::NullableDouble()), kNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::NullableDouble()), kCanBeNull,
+                          kCannotBeSentinel);
 }
 
 CompileType CompileType::String() {
-  return FromAbstractType(Type::ZoneHandle(Type::StringType()), kNonNullable);
+  return FromAbstractType(Type::ZoneHandle(Type::StringType()), kCannotBeNull,
+                          kCannotBeSentinel);
 }
 
 intptr_t CompileType::ToCid() {
@@ -706,13 +738,18 @@
     if ((type_ != NULL) && type_->IsNullType()) {
       cid_ = kNullCid;
     }
+    // Same for sentinel.
+    if ((type_ != NULL) && type_->IsNeverType()) {
+      cid_ = kNeverCid;
+    }
   }
 
-  if ((cid_ == kNullCid) || (cid_ == kDynamicCid)) {
-    return cid_;
+  if ((cid_ == kDynamicCid) || (can_be_null_ && (cid_ != kNullCid)) ||
+      (can_be_sentinel_ && (cid_ != kSentinelCid))) {
+    return kDynamicCid;
   }
 
-  return is_nullable_ ? static_cast<intptr_t>(kDynamicCid) : ToNullableCid();
+  return ToNullableCid();
 }
 
 intptr_t CompileType::ToNullableCid() {
@@ -724,6 +761,8 @@
       cid_ = kDynamicCid;
     } else if (type_->IsNullType()) {
       cid_ = kNullCid;
+    } else if (type_->IsNeverType()) {
+      cid_ = kNeverCid;
     } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
       cid_ = kClosureCid;
     } else if (type_->type_class_id() != kIllegalCid) {
@@ -758,11 +797,15 @@
     }
   }
 
+  if (can_be_sentinel_ && (cid_ != kSentinelCid)) {
+    return kDynamicCid;
+  }
+
   return cid_;
 }
 
 bool CompileType::HasDecidableNullability() {
-  return !is_nullable_ || IsNull();
+  return !can_be_null_ || IsNull();
 }
 
 bool CompileType::IsNull() {
@@ -838,9 +881,12 @@
   if (type_ != nullptr && type_->type_class_id() != kIllegalCid) {
     const Class& type_class = Class::Handle(type_->type_class());
     if (!CHA::ConcreteSubclasses(type_class, class_ids)) return false;
-    if (is_nullable_) {
+    if (can_be_null_) {
       class_ids->Add(kNullCid);
     }
+    if (can_be_sentinel_) {
+      class_ids->Add(kSentinelCid);
+    }
   }
   return false;
 }
@@ -905,7 +951,8 @@
     type_name = "!null";
   }
 
-  f->Printf("T{%s%s}", type_name, is_nullable_ ? "?" : "");
+  f->Printf("T{%s%s%s}", type_name, can_be_null_ ? "?" : "",
+            can_be_sentinel_ ? "~" : "");
 }
 
 const char* CompileType::ToCString() const {
@@ -974,15 +1021,17 @@
     // If either type is non-nullable, the resulting type is non-nullable.
     const bool is_nullable =
         value()->Type()->is_nullable() && constrained_type_->is_nullable();
+    const bool can_be_sentinel = value()->Type()->can_be_sentinel() &&
+                                 constrained_type_->can_be_sentinel();
 
     // If either type has a concrete cid, stick with it.
     if (value()->Type()->ToNullableCid() != kDynamicCid) {
-      return CompileType::CreateNullable(is_nullable,
-                                         value()->Type()->ToNullableCid());
+      return CompileType(is_nullable, can_be_sentinel,
+                         value()->Type()->ToNullableCid(), nullptr);
     }
     if (constrained_type_->ToNullableCid() != kDynamicCid) {
-      return CompileType::CreateNullable(is_nullable,
-                                         constrained_type_->ToNullableCid());
+      return CompileType(is_nullable, can_be_sentinel,
+                         constrained_type_->ToNullableCid(), nullptr);
     }
     if (value()->Type()->IsSubtypeOf(*constrained_type_->ToAbstractType())) {
       return is_nullable ? *value()->Type()
@@ -1088,7 +1137,8 @@
         graph_entry->parsed_function().RawParameterVariable(0)->type();
     if (type.IsObjectType() || type.IsNullType()) {
       // Receiver can be null.
-      return CompileType::FromAbstractType(type);
+      return CompileType::FromAbstractType(type, CompileType::kCanBeNull,
+                                           CompileType::kCannotBeSentinel);
     }
 
     // Receiver can't be null but can be an instance of a subclass.
@@ -1121,7 +1171,8 @@
       }
     }
 
-    return CompileType(CompileType::kNonNullable, cid, &type);
+    return CompileType(CompileType::kCannotBeNull,
+                       CompileType::kCannotBeSentinel, cid, &type);
   }
 
   const bool is_unchecked_entry_param =
@@ -1160,7 +1211,9 @@
       const bool is_nullable =
           (inferred_type == NULL) || inferred_type->is_nullable();
       TraceStrongModeType(this, param->type());
-      return CompileType::FromAbstractType(param->type(), is_nullable);
+      return CompileType::FromAbstractType(
+          param->type(), is_nullable,
+          block_->IsCatchBlockEntry() && param->is_late());
     }
     // Last resort: use inferred non-nullability.
     if (inferred_type != NULL) {
@@ -1184,16 +1237,17 @@
   intptr_t cid = value().GetClassId();
 
   if (cid == kSmiCid && !compiler::target::IsSmi(Smi::Cast(value()).Value())) {
-    return CompileType::Create(kMintCid,
-                               AbstractType::ZoneHandle(Type::MintType()));
+    return CompileType(CompileType::kCannotBeNull,
+                       CompileType::kCannotBeSentinel, kMintCid,
+                       &AbstractType::ZoneHandle(Type::MintType()));
   }
 
   if ((cid != kTypeArgumentsCid) && value().IsInstance()) {
     // Allocate in old-space since this may be invoked from the
     // background compiler.
-    return CompileType::Create(
-        cid,
-        AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld)));
+    return CompileType(
+        cid == kNullCid, cid == kSentinelCid, cid,
+        &AbstractType::ZoneHandle(Instance::Cast(value()).GetType(Heap::kOld)));
   } else {
     // Type info for non-instance objects.
     return CompileType::FromCid(cid);
@@ -1211,7 +1265,8 @@
       return *value_type;
     }
   }
-  return CompileType::FromAbstractType(*abs_type, value_type->is_nullable());
+  return CompileType::FromAbstractType(*abs_type, value_type->is_nullable(),
+                                       CompileType::kCannotBeSentinel);
 }
 
 bool AssertAssignableInstr::RecomputeType() {
@@ -1261,7 +1316,8 @@
     case kArgDescriptor:
       return CompileType::FromCid(kImmutableArrayCid);
     case kException:
-      return CompileType(CompileType::kNonNullable, kDynamicCid,
+      return CompileType(CompileType::kCannotBeNull,
+                         CompileType::kCannotBeSentinel, kDynamicCid,
                          &Object::dynamic_type());
     case kStackTrace:
       // We cannot use [kStackTraceCid] here because any kind of object can be
@@ -1273,18 +1329,18 @@
 }
 
 CompileType CloneContextInstr::ComputeType() const {
-  return CompileType(CompileType::kNonNullable, kContextCid,
-                     &Object::dynamic_type());
+  return CompileType(CompileType::kCannotBeNull, CompileType::kCannotBeSentinel,
+                     kContextCid, &Object::dynamic_type());
 }
 
 CompileType AllocateContextInstr::ComputeType() const {
-  return CompileType(CompileType::kNonNullable, kContextCid,
-                     &Object::dynamic_type());
+  return CompileType(CompileType::kCannotBeNull, CompileType::kCannotBeSentinel,
+                     kContextCid, &Object::dynamic_type());
 }
 
 CompileType AllocateUninitializedContextInstr::ComputeType() const {
-  return CompileType(CompileType::kNonNullable, kContextCid,
-                     &Object::dynamic_type());
+  return CompileType(CompileType::kCannotBeNull, CompileType::kCannotBeSentinel,
+                     kContextCid, &Object::dynamic_type());
 }
 
 CompileType InstanceCallBaseInstr::ComputeType() const {
@@ -1313,7 +1369,8 @@
       TraceStrongModeType(this, result_type);
       const bool is_nullable =
           (inferred_type == NULL) || inferred_type->is_nullable();
-      return CompileType::FromAbstractType(result_type, is_nullable);
+      return CompileType::FromAbstractType(result_type, is_nullable,
+                                           CompileType::kCannotBeSentinel);
     }
   }
 
@@ -1327,14 +1384,15 @@
   const auto& result_type = AbstractType::ZoneHandle(target.result_type());
   if (result_type.IsInstantiated()) {
     TraceStrongModeType(this, result_type);
-    return CompileType::FromAbstractType(result_type);
+    return CompileType::FromAbstractType(result_type, CompileType::kCanBeNull,
+                                         CompileType::kCannotBeSentinel);
   }
 
   return CompileType::Dynamic();
 }
 
 CompileType PolymorphicInstanceCallInstr::ComputeType() const {
-  bool is_nullable = CompileType::kNullable;
+  bool is_nullable = CompileType::kCanBeNull;
   if (IsSureToCallSingleRecognizedTarget()) {
     const Function& target = *targets_.TargetAt(0)->target;
     if (target.has_pragma()) {
@@ -1342,7 +1400,7 @@
       if (cid != kDynamicCid) {
         return CompileType::FromCid(cid);
       } else if (MethodRecognizer::HasNonNullableResultTypeFromPragma(target)) {
-        is_nullable = CompileType::kNonNullable;
+        is_nullable = CompileType::kCannotBeNull;
       }
     }
   }
@@ -1369,7 +1427,8 @@
         Type::ZoneHandle(Type::New(cls, type_args, Nullability::kNonNullable));
     ASSERT(type.IsInstantiated());
     type.SetIsFinalized();
-    return CompileType(CompileType::kNonNullable, cid, &type);
+    return CompileType(CompileType::kCannotBeNull,
+                       CompileType::kCannotBeSentinel, cid, &type);
   }
   return *inferred_type;
 }
@@ -1386,14 +1445,14 @@
     return *inferred_type;
   }
 
-  bool is_nullable = CompileType::kNullable;
+  bool is_nullable = CompileType::kCanBeNull;
   if (function_.has_pragma()) {
     const intptr_t cid = MethodRecognizer::ResultCidFromPragma(function_);
     if (cid != kDynamicCid) {
       return CompileType::FromCid(cid);
     }
     if (MethodRecognizer::HasNonNullableResultTypeFromPragma(function_)) {
-      is_nullable = CompileType::kNonNullable;
+      is_nullable = CompileType::kCannotBeNull;
     }
   }
 
@@ -1406,7 +1465,8 @@
     TraceStrongModeType(this, result_type);
     is_nullable = is_nullable &&
                   (inferred_type == nullptr || inferred_type->is_nullable());
-    return CompileType::FromAbstractType(result_type, is_nullable);
+    return CompileType::FromAbstractType(result_type, is_nullable,
+                                         CompileType::kCannotBeSentinel);
   }
 
   return CompileType::Dynamic();
@@ -1417,11 +1477,12 @@
     // We may not yet have checked the actual type of the parameter value.
     // Assuming that the value has the required type can lead to unsound
     // optimizations. See dartbug.com/43464.
-    return CompileType::FromCid(kDynamicCid);
+    return CompileType::Dynamic();
   }
   const AbstractType& local_type = local().type();
   TraceStrongModeType(this, local_type);
-  return CompileType::FromAbstractType(local_type);
+  return CompileType::FromAbstractType(local_type, CompileType::kCanBeNull,
+                                       local().is_late());
 }
 
 CompileType DropTempsInstr::ComputeType() const {
@@ -1448,7 +1509,7 @@
 
 CompileType LoadStaticFieldInstr::ComputeType() const {
   const Field& field = this->field();
-  bool is_nullable = CompileType::kNullable;
+  bool is_nullable = CompileType::kCanBeNull;
   intptr_t cid = kIllegalCid;  // Abstract type is known, calculate cid lazily.
   AbstractType* abstract_type = &AbstractType::ZoneHandle(field.type());
   TraceStrongModeType(this, *abstract_type);
@@ -1457,7 +1518,7 @@
   const bool is_initialized = IsFieldInitialized(&obj);
   if (field.is_final() && is_initialized) {
     if (!obj.IsNull()) {
-      is_nullable = CompileType::kNonNullable;
+      is_nullable = CompileType::kCannotBeNull;
       cid = obj.GetClassId();
       abstract_type = nullptr;  // Cid is known, calculate abstract type lazily.
     }
@@ -1473,7 +1534,9 @@
     DEBUG_ASSERT(IsolateGroup::Current()->HasAttemptedReload());
     return CompileType::Dynamic();
   }
-  return CompileType(is_nullable, cid, abstract_type);
+  const bool can_be_sentinel = !calls_initializer() && field.is_late() &&
+                               field.is_final() && !field.has_initializer();
+  return CompileType(is_nullable, can_be_sentinel, cid, abstract_type);
 }
 
 CompileType CreateArrayInstr::ComputeType() const {
@@ -1494,7 +1557,8 @@
   const auto& func = known_function();
   if (!func.IsNull()) {
     const auto& sig = FunctionType::ZoneHandle(func.signature());
-    return CompileType(CompileType::kNonNullable, kClosureCid, &sig);
+    return CompileType(CompileType::kCannotBeNull,
+                       CompileType::kCannotBeSentinel, kClosureCid, &sig);
   }
   return CompileType::FromCid(kClosureCid);
 }
@@ -1509,6 +1573,9 @@
 
 CompileType LoadFieldInstr::ComputeType() const {
   CompileType type = slot().ComputeCompileType();
+  if (calls_initializer()) {
+    type = type.CopyNonSentinel();
+  }
   TraceStrongModeType(this, &type);
   return type;
 }
@@ -1754,7 +1821,8 @@
   // 1. Try to extract element type from array value.
   auto& elem_type = AbstractType::Handle(GetElementTypeFromArray(array));
   if (!elem_type.IsDynamicType()) {
-    return CompileType::FromAbstractType(elem_type);
+    return CompileType::FromAbstractType(elem_type, CompileType::kCanBeNull,
+                                         CompileType::kCannotBeSentinel);
   }
 
   // 2. Array value may be loaded from GrowableObjectArray.data.
@@ -1764,7 +1832,8 @@
       array = load_field->instance();
       elem_type = GetElementTypeFromArray(array);
       if (!elem_type.IsDynamicType()) {
-        return CompileType::FromAbstractType(elem_type);
+        return CompileType::FromAbstractType(elem_type, CompileType::kCanBeNull,
+                                             CompileType::kCannotBeSentinel);
       }
     }
   }
@@ -1778,7 +1847,8 @@
           ExtractElementTypeFromArrayType(load_field->slot().static_type());
     }
   }
-  return CompileType::FromAbstractType(elem_type);
+  return CompileType::FromAbstractType(elem_type, CompileType::kCanBeNull,
+                                       CompileType::kCannotBeSentinel);
 }
 
 CompileType LoadIndexedInstr::ComputeType() const {
@@ -1793,7 +1863,8 @@
 
     case kTypeArgumentsCid:
       return CompileType::FromAbstractType(Object::dynamic_type(),
-                                           /*is_nullable=*/false);
+                                           CompileType::kCannotBeNull,
+                                           CompileType::kCannotBeSentinel);
 
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid:
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 60d58c4..4cb966e 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -481,7 +481,8 @@
     field ^= fields.At(i);
     type = field.type();
 
-    auto compile_type = CompileType::FromAbstractType(type);
+    auto compile_type = CompileType::FromAbstractType(
+        type, CompileType::kCanBeNull, CompileType::kCannotBeSentinel);
     if (compile_type.CanBeSmi() != expected_can_be_smi(field)) {
       dart::Expect(__FILE__, __LINE__)
           .Fail("expected that CanBeSmi() returns %s for compile type %s\n",
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index e1f2ce3..7160b17 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -576,7 +576,8 @@
 Fragment BaseFlowGraphBuilder::RedefinitionWithType(const AbstractType& type) {
   auto redefinition = new (Z) RedefinitionInstr(Pop());
   redefinition->set_constrained_type(
-      new (Z) CompileType(CompileType::FromAbstractType(type)));
+      new (Z) CompileType(CompileType::FromAbstractType(
+          type, CompileType::kCanBeNull, CompileType::kCannotBeSentinel)));
   Push(redefinition);
   return Fragment(redefinition);
 }
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 1bed607..7dc0384 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -976,9 +976,10 @@
       return CompileType::FromAbstractType(
           Type::ZoneHandle(
               zone, (IsNullable() ? Type::NullableIntType() : Type::IntType())),
-          IsNullable());
+          IsNullable(), CompileType::kCannotBeSentinel);
     } else {
-      return CompileType::CreateNullable(IsNullable(), cid);
+      return CompileType(IsNullable(), CompileType::kCannotBeSentinel, cid,
+                         nullptr);
     }
   }
 };
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 6b1fee9..8125ba0 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -26,10 +26,11 @@
                                  Representation representation = kTagged) {
   return param->was_type_checked_by_caller()
              ? CompileType::FromAbstractType(param->type(),
-                                             representation == kTagged)
+                                             representation == kTagged,
+                                             CompileType::kCannotBeSentinel)
              : ((representation == kTagged)
                     ? CompileType::Dynamic()
-                    : CompileType::FromCid(kDynamicCid).CopyNonNullable());
+                    : CompileType::Dynamic().CopyNonNullable());
 }
 
 bool PrologueBuilder::PrologueSkippableOnUncheckedEntry(
@@ -357,7 +358,8 @@
   store_type_args += LoadFpRelativeSlot(
       compiler::target::kWordSize *
           (1 + compiler::target::frame_layout.param_end_from_fp),
-      CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid));
+      CompileType(CompileType::kCanBeNull, CompileType::kCannotBeSentinel,
+                  kTypeArgumentsCid, nullptr));
   store_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var);
   store_type_args += Drop();
 
diff --git a/tests/lib/js/js_util/properties_test.dart b/tests/lib/js/js_util/properties_test.dart
index 64f74bd..a9db3d2 100644
--- a/tests/lib/js/js_util/properties_test.dart
+++ b/tests/lib/js/js_util/properties_test.dart
@@ -50,11 +50,20 @@
   external get b;
 }
 
-class ExampleTearoff {
+class DartClass {
   int x = 3;
-  foo() => x;
+  int getX() => x;
 }
 
+class GenericDartClass<T> {
+  final T myT;
+  GenericDartClass(this.myT);
+
+  T getT() => myT;
+}
+
+T getTopLevelGenerics<T>(T t) => t;
+
 String _getBarWithSideEffect() {
   var x = 5;
   expect(x, equals(5));
@@ -346,9 +355,19 @@
       String expected = dartFunction();
       expect(f.a, equals(expected));
 
-      // Using a tearoff as the property value
-      js_util.setProperty(f, 'tearoff', allowInterop(ExampleTearoff().foo));
+      // Using a tearoff as the property value.
+      js_util.setProperty(f, 'tearoff', allowInterop(DartClass().getX));
       expect(js_util.callMethod(f, 'tearoff', []), equals(3));
+
+      // Set property to instance method calls.
+      js_util.setProperty(f, 'a', DartClass().getX());
+      expect(f.a, equals(3));
+      js_util.setProperty(f, 'a', GenericDartClass<int>(5).getT());
+      expect(f.a, equals(5));
+
+      // Set property using a generics wrapper on value.
+      js_util.setProperty(f, 'a', getTopLevelGenerics<int>(10));
+      expect(f.a, equals(10));
     });
   });
 
diff --git a/tests/lib_2/js/js_util/properties_test.dart b/tests/lib_2/js/js_util/properties_test.dart
index 7bd608f..511780f 100644
--- a/tests/lib_2/js/js_util/properties_test.dart
+++ b/tests/lib_2/js/js_util/properties_test.dart
@@ -52,11 +52,20 @@
   external get b;
 }
 
-class ExampleTearoff {
+class DartClass {
   int x = 3;
-  foo() => x;
+  int getX() => x;
 }
 
+class GenericDartClass<T> {
+  final T myT;
+  GenericDartClass(this.myT);
+
+  T getT() => myT;
+}
+
+T getTopLevelGenerics<T>(T t) => t;
+
 String _getBarWithSideEffect() {
   var x = 5;
   expect(x, equals(5));
@@ -348,9 +357,19 @@
       String expected = dartFunction();
       expect(f.a, equals(expected));
 
-      // Using a tearoff as the property value
-      js_util.setProperty(f, 'tearoff', allowInterop(ExampleTearoff().foo));
+      // Using a tearoff as the property value.
+      js_util.setProperty(f, 'tearoff', allowInterop(DartClass().getX));
       expect(js_util.callMethod(f, 'tearoff', []), equals(3));
+
+      // Set property to instance method calls.
+      js_util.setProperty(f, 'a', DartClass().getX());
+      expect(f.a, equals(3));
+      js_util.setProperty(f, 'a', GenericDartClass<int>(5).getT());
+      expect(f.a, equals(5));
+
+      // Set property using a generics wrapper on value.
+      js_util.setProperty(f, 'a', getTopLevelGenerics<int>(10));
+      expect(f.a, equals(10));
     });
   });
 
diff --git a/tools/VERSION b/tools/VERSION
index 253e934..018052a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 188
+PRERELEASE 189
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/aot_smoke_tests.dart b/tools/bots/aot_smoke_tests.dart
deleted file mode 100755
index 406fb08..0000000
--- a/tools/bots/aot_smoke_tests.dart
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env dart
-// 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.
-
-// Smoke test runner for Dart AOT (dart2native, dartaotruntime).
-// aot_smoke_tests.dart and dart_aot_test.dart together form the test that the
-// AOT toolchain is compiled and included correctly in the SDK.
-// This tests that the AOT tools can both successfully compile Dart -> AOT and
-// run the resulting AOT blob with the AOT runtime.
-
-import 'dart:io';
-
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-
-final String newline = Platform.isWindows ? '\r\n' : '\n';
-final String executableSuffix = Platform.isWindows ? ".exe" : "";
-final String sdkBinDir = path.dirname(Platform.executable);
-final String dartaotruntime =
-    path.join(sdkBinDir, 'dartaotruntime${executableSuffix}');
-final String dart = path.join(sdkBinDir, 'dart${executableSuffix}');
-
-Future<void> withTempDir(Future fun(String dir)) async {
-  final Directory tempDir = Directory.systemTemp.createTempSync();
-  try {
-    await fun(tempDir.path);
-  } finally {
-    tempDir.deleteSync(recursive: true);
-  }
-}
-
-void main(List<String> args) {
-  test("Dart native: Can compile and run AOT snapshot", () async {
-    await withTempDir((String tmp) async {
-      final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
-      final String tmpAot = path.join(tmp, 'dart_aot_test.aot');
-
-      {
-        final ProcessResult result = await Process.run(
-            dart, ['compile', 'aot-snapshot', testCode, '--output', tmpAot]);
-        expect(result.stderr, '');
-        expect(result.exitCode, 0);
-      }
-
-      {
-        const String testStr = 'Dart AOT';
-        final ProcessResult result =
-            await Process.run(dartaotruntime, [tmpAot, testStr]);
-        expect(result.stderr, '');
-        expect(result.exitCode, 0);
-        expect(result.stdout, 'Hello, ${testStr}.${newline}');
-      }
-    });
-  });
-
-  test("Dart native: Can compile and run exe", () async {
-    await withTempDir((String tmp) async {
-      final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
-      final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
-
-      {
-        final ProcessResult result = await Process.run(
-            dart, ['compile', 'exe', testCode, '--output', tmpExe]);
-        expect(result.stderr, '');
-        expect(result.exitCode, 0);
-      }
-
-      {
-        const String testStr = 'Dart AOT';
-        final ProcessResult result = await Process.run(tmpExe, [testStr]);
-        expect(result.stderr, '');
-        expect(result.exitCode, 0);
-        expect(result.stdout, 'Hello, ${testStr}.${newline}');
-      }
-    });
-  });
-
-  test("Dart native: Returns non-zero on missing file.", () async {
-    await withTempDir((String tmp) async {
-      final String testCode = path.join(tmp, 'does_not_exist.dart');
-      final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
-
-      {
-        final ProcessResult result = await Process.run(
-            dart, ['compile', 'exe', testCode, '--output', tmpExe]);
-        expect(result.exitCode, isNonZero);
-      }
-    });
-  });
-
-  test("Dart native: Returns non-zero on non-file.", () async {
-    await withTempDir((String tmp) async {
-      final String testCode = tmp; // This is a directory, not a file.
-      final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
-
-      {
-        final ProcessResult result = await Process.run(
-            dart, ['compile', 'exe', testCode, '--output', tmpExe]);
-        expect(result.exitCode, isNonZero);
-      }
-    });
-  });
-}
diff --git a/tools/bots/dart_aot_test.dart b/tools/bots/dart_aot_test.dart
deleted file mode 100755
index 9449b27..0000000
--- a/tools/bots/dart_aot_test.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test program for Dart AOT (dart compile, dartaotruntime).
-
-void main(List<String> args) async {
-  final String who = !args.isEmpty ? args[0] : '世界';
-  print('Hello, ${who}.');
-}
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index d876320..4625472 100755
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -24,7 +24,7 @@
     if BUILD_OS == 'linux':
         return ['ia32', 'x64', 'arm', 'arm64']
     elif BUILD_OS == 'macos':
-        return ['x64']
+        return [BUILD_ARCHITECTURE]
     else:
         return ['ia32', 'x64']
 
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 1d078c0..6058679 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1833,6 +1833,7 @@
         "vm-kernel-linux-debug-x64c",
         "vm-kernel-mac-product-x64",
         "vm-kernel-mac-product-x64c",
+        "vm-kernel-mac-release-arm64",
         "vm-kernel-mac-release-x64",
         "vm-kernel-mac-release-x64c",
         "vm-kernel-mac-debug-x64",
@@ -2839,13 +2840,6 @@
           "script": "tools/bots/dart_sdk.py"
         },
         {
-          "name": "run AOT and Exe smoke tests",
-          "script": "out/ReleaseX64/dart-sdk/bin/dart",
-          "arguments": [
-            "tools/bots/aot_smoke_tests.dart"
-          ]
-        },
-        {
           "name": "build api docs",
           "script": "tools/bots/dart_sdk.py",
           "arguments": [
@@ -2856,7 +2850,8 @@
     },
     {
       "builders": [
-        "dart-sdk-mac"
+        "dart-sdk-mac",
+        "dart-sdk-mac-arm64"
       ],
       "meta": {
         "description": "This configuration is used by the sdk-builders for MacOS."
@@ -2866,7 +2861,6 @@
           "name": "build dart",
           "script": "tools/build.py",
           "arguments": [
-            "--arch=x64",
             "--mode=release",
             "--check-clean",
             "create_sdk"
@@ -2878,13 +2872,6 @@
         {
           "name": "upload sdk",
           "script": "tools/bots/dart_sdk.py"
-        },
-        {
-          "name": "run AOT and Exe smoke tests",
-          "script": "xcodebuild/ReleaseX64/dart-sdk/bin/dart",
-          "arguments": [
-            "tools/bots/aot_smoke_tests.dart"
-          ]
         }
       ]
     },
@@ -2909,13 +2896,6 @@
         {
           "name": "upload sdk",
           "script": "tools/bots/dart_sdk.py"
-        },
-        {
-          "name": "run AOT and Exe smoke tests",
-          "script": "out/ReleaseX64/dart-sdk/bin/dart.exe",
-          "arguments": [
-            "tools/bots/aot_smoke_tests.dart"
-          ]
         }
       ]
     },
@@ -3628,7 +3608,7 @@
         {
           "name": "analyze flutter/plugins",
           "script": "tools/bots/flutter/analyze_flutter_plugins.sh"
-        }        
+        }
       ]
     },
     {