Version 2.12.0-140.0.dev

Merge commit '8e663541c9a25f491be015c684c170dbe57f3276' into 'dev'
diff --git a/DEPS b/DEPS
index 80e12ef..4c67d48 100644
--- a/DEPS
+++ b/DEPS
@@ -81,7 +81,7 @@
   "cli_util_rev" : "50cc840b146615899e97b892578848401b2028d5",
   "clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3",
   "collection_rev": "e4bb038ce2d8e66fb15818aa40685c68d53692ab",
-  "convert_rev": "dd3bd28f63be7cb8ab961f38bc73229e4473b555",
+  "convert_rev": "6513985a1b1ea8a0b987fbef699250ce2cdc3cca",
   "crypto_rev": "a5ec902dda5a635a35c6b363ec64458cf84c5872",
   "csslib_rev": "6f77b3dcee957d3e2d5083f666221a220e9ed1f1",
   "dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 2357561..f782575 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -828,7 +828,7 @@
 
 /// The lazy initialized map from [ErrorCode.uniqueName] to the [ErrorCode]
 /// instance.
-HashMap<String, ErrorCode> _uniqueNameToCodeMap;
+/*late final*/ HashMap<String, ErrorCode> _uniqueNameToCodeMap;
 
 /// Return the [ErrorCode] with the given [uniqueName], or `null` if not
 /// found.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 0b09d2e..1d90610 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -14,7 +14,7 @@
 /// An analysis context whose implementation is based on an analysis driver.
 class DriverBasedAnalysisContext implements AnalysisContext {
   /// The resource provider used to access the file system.
-  final ResourceProvider resourceProvider;
+  final ResourceProvider /*!*/ resourceProvider;
 
   @override
   final ContextRoot contextRoot;
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 0ab40ba..8806048 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -116,12 +116,12 @@
   }
 
   @override
-  ClassElement get boolElement {
+  ClassElement /*!*/ get boolElement {
     return _boolElement ??= _getClassElement(_coreLibrary, 'bool');
   }
 
   @override
-  InterfaceType get boolType {
+  InterfaceType /*!*/ get boolType {
     _boolType ??= _getType(_coreLibrary, "bool");
     return _boolType;
   }
@@ -135,37 +135,37 @@
   }
 
   @override
-  InterfaceType get deprecatedType {
+  InterfaceType /*!*/ get deprecatedType {
     _deprecatedType ??= _getType(_coreLibrary, "Deprecated");
     return _deprecatedType;
   }
 
   @override
-  ClassElement get doubleElement {
+  ClassElement /*!*/ get doubleElement {
     return _doubleElement ??= _getClassElement(_coreLibrary, "double");
   }
 
   @override
-  InterfaceType get doubleType {
+  InterfaceType /*!*/ get doubleType {
     _doubleType ??= _getType(_coreLibrary, "double");
     return _doubleType;
   }
 
-  InterfaceType get doubleTypeQuestion =>
+  InterfaceType /*!*/ get doubleTypeQuestion =>
       _doubleTypeQuestion ??= (doubleType as InterfaceTypeImpl)
           .withNullability(NullabilitySuffix.question);
 
   @override
-  DartType get dynamicType => DynamicTypeImpl.instance;
+  DartType /*!*/ get dynamicType => DynamicTypeImpl.instance;
 
   @override
-  InterfaceType get functionType {
+  InterfaceType /*!*/ get functionType {
     _functionType ??= _getType(_coreLibrary, "Function");
     return _functionType;
   }
 
   @override
-  InterfaceType get futureDynamicType {
+  InterfaceType /*!*/ get futureDynamicType {
     _futureDynamicType ??= InterfaceTypeImpl(
       element: futureElement,
       typeArguments: [dynamicType],
@@ -175,12 +175,12 @@
   }
 
   @override
-  ClassElement get futureElement {
+  ClassElement /*!*/ get futureElement {
     return _futureElement ??= _getClassElement(_asyncLibrary, 'Future');
   }
 
   @override
-  InterfaceType get futureNullType {
+  InterfaceType /*!*/ get futureNullType {
     _futureNullType ??= InterfaceTypeImpl(
       element: futureElement,
       typeArguments: [nullType],
@@ -190,12 +190,12 @@
   }
 
   @override
-  ClassElement get futureOrElement {
+  ClassElement /*!*/ get futureOrElement {
     return _futureOrElement ??= _getClassElement(_asyncLibrary, 'FutureOr');
   }
 
   @override
-  InterfaceType get futureOrNullType {
+  InterfaceType /*!*/ get futureOrNullType {
     _futureOrNullType ??= InterfaceTypeImpl(
       element: futureOrElement,
       typeArguments: [nullType],
@@ -205,22 +205,22 @@
   }
 
   @override
-  ClassElement get intElement {
+  ClassElement /*!*/ get intElement {
     return _intElement ??= _getClassElement(_coreLibrary, "int");
   }
 
   @override
-  InterfaceType get intType {
+  InterfaceType /*!*/ get intType {
     _intType ??= _getType(_coreLibrary, "int");
     return _intType;
   }
 
-  InterfaceType get intTypeQuestion =>
+  InterfaceType /*!*/ get intTypeQuestion =>
       _intTypeQuestion ??= (intType as InterfaceTypeImpl)
           .withNullability(NullabilitySuffix.question);
 
   @override
-  InterfaceType get iterableDynamicType {
+  InterfaceType /*!*/ get iterableDynamicType {
     _iterableDynamicType ??= InterfaceTypeImpl(
       element: iterableElement,
       typeArguments: [dynamicType],
@@ -230,12 +230,12 @@
   }
 
   @override
-  ClassElement get iterableElement {
+  ClassElement /*!*/ get iterableElement {
     return _iterableElement ??= _getClassElement(_coreLibrary, 'Iterable');
   }
 
   @override
-  InterfaceType get iterableObjectType {
+  InterfaceType /*!*/ get iterableObjectType {
     _iterableObjectType ??= InterfaceTypeImpl(
       element: iterableElement,
       typeArguments: [objectType],
@@ -245,17 +245,17 @@
   }
 
   @override
-  ClassElement get listElement {
+  ClassElement /*!*/ get listElement {
     return _listElement ??= _getClassElement(_coreLibrary, 'List');
   }
 
   @override
-  ClassElement get mapElement {
+  ClassElement /*!*/ get mapElement {
     return _mapElement ??= _getClassElement(_coreLibrary, 'Map');
   }
 
   @override
-  InterfaceType get mapObjectObjectType {
+  InterfaceType /*!*/ get mapObjectObjectType {
     _mapObjectObjectType ??= InterfaceTypeImpl(
       element: mapElement,
       typeArguments: [objectType, objectType],
@@ -265,12 +265,13 @@
   }
 
   @override
-  DartType get neverType => isNonNullableByDefault
+  DartType /*!*/ get neverType => isNonNullableByDefault
       ? NeverTypeImpl.instance
       : NeverTypeImpl.instanceLegacy;
 
   @override
-  Set<ClassElement> get nonSubtypableClasses => _nonSubtypableClasses ??= {
+  Set<ClassElement> /*!*/ get nonSubtypableClasses =>
+      _nonSubtypableClasses ??= {
         boolElement,
         doubleElement,
         futureOrElement,
@@ -281,11 +282,11 @@
       };
 
   @override
-  ClassElement get nullElement {
+  ClassElement /*!*/ get nullElement {
     return _nullElement ??= _getClassElement(_coreLibrary, 'Null');
   }
 
-  InterfaceTypeImpl get nullStar {
+  InterfaceTypeImpl /*!*/ get nullStar {
     return _nullStar ??= nullElement.instantiate(
       typeArguments: const [],
       nullabilitySuffix: NullabilitySuffix.star,
@@ -293,49 +294,49 @@
   }
 
   @override
-  InterfaceType get nullType {
+  InterfaceType /*!*/ get nullType {
     _nullType ??= _getType(_coreLibrary, "Null");
     return _nullType;
   }
 
   @override
-  ClassElement get numElement {
+  ClassElement /*!*/ get numElement {
     return _numElement ??= _getClassElement(_coreLibrary, 'num');
   }
 
   @override
-  InterfaceType get numType {
+  InterfaceType /*!*/ get numType {
     _numType ??= _getType(_coreLibrary, "num");
     return _numType;
   }
 
-  InterfaceType get numTypeQuestion =>
+  InterfaceType /*!*/ get numTypeQuestion =>
       _numTypeQuestion ??= (numType as InterfaceTypeImpl)
           .withNullability(NullabilitySuffix.question);
 
-  ClassElement get objectElement {
+  ClassElement /*!*/ get objectElement {
     return _objectElement ??= _getClassElement(_coreLibrary, 'Object');
   }
 
   @override
-  InterfaceType get objectType {
+  InterfaceType /*!*/ get objectType {
     _objectType ??= _getType(_coreLibrary, "Object");
     return _objectType;
   }
 
   @override
-  ClassElement get setElement {
+  ClassElement /*!*/ get setElement {
     return _setElement ??= _getClassElement(_coreLibrary, 'Set');
   }
 
   @override
-  InterfaceType get stackTraceType {
+  InterfaceType /*!*/ get stackTraceType {
     _stackTraceType ??= _getType(_coreLibrary, "StackTrace");
     return _stackTraceType;
   }
 
   @override
-  InterfaceType get streamDynamicType {
+  InterfaceType /*!*/ get streamDynamicType {
     _streamDynamicType ??= InterfaceTypeImpl(
       element: streamElement,
       typeArguments: [dynamicType],
@@ -345,34 +346,34 @@
   }
 
   @override
-  ClassElement get streamElement {
+  ClassElement /*!*/ get streamElement {
     return _streamElement ??= _getClassElement(_asyncLibrary, 'Stream');
   }
 
   @override
-  ClassElement get stringElement {
+  ClassElement /*!*/ get stringElement {
     return _stringElement ??= _getClassElement(_coreLibrary, 'String');
   }
 
   @override
-  InterfaceType get stringType {
+  InterfaceType /*!*/ get stringType {
     _stringType ??= _getType(_coreLibrary, "String");
     return _stringType;
   }
 
   @override
-  ClassElement get symbolElement {
+  ClassElement /*!*/ get symbolElement {
     return _symbolElement ??= _getClassElement(_coreLibrary, 'Symbol');
   }
 
   @override
-  InterfaceType get symbolType {
+  InterfaceType /*!*/ get symbolType {
     _symbolType ??= _getType(_coreLibrary, "Symbol");
     return _symbolType;
   }
 
   @override
-  InterfaceType get typeType {
+  InterfaceType /*!*/ get typeType {
     _typeType ??= _getType(_coreLibrary, "Type");
     return _typeType;
   }
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 0a0d0fa..8b55ebf 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -29,7 +29,7 @@
 /// library map.
 abstract class AbstractDartSdk implements DartSdk {
   /// The resource provider used to access the file system.
-  ResourceProvider resourceProvider;
+  /*late final*/ ResourceProvider resourceProvider;
 
   /// A mapping from Dart library URI's to the library represented by that URI.
   LibraryMap libraryMap = LibraryMap();
@@ -130,7 +130,7 @@
   }
 
   @override
-  Source mapDartUri(String dartUri) {
+  Source mapDartUri(String /*!*/ dartUri) {
     Source source = _uriToSourceMap[dartUri];
     if (source == null) {
       source = internalMapDartUri(dartUri);
@@ -288,9 +288,9 @@
   ///
   /// If a key doesn't begin with `dart:` it is ignored.
   void _processEmbedderYaml(Folder libDir, YamlMap map) {
-    YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
-    if (embedded_libs is YamlMap) {
-      embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
+    YamlNode embeddedLibs = map[_EMBEDDED_LIB_MAP_KEY];
+    if (embeddedLibs is YamlMap) {
+      embeddedLibs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
     }
   }
 }
@@ -351,17 +351,17 @@
   final Folder _sdkDirectory;
 
   /// The directory within the SDK directory that contains the libraries.
-  Folder _libraryDirectory;
+  /*late final*/ Folder _libraryDirectory;
 
   /// The revision number of this SDK, or `"0"` if the revision number cannot be
   /// discovered.
-  String _sdkVersion;
+  /*late final*/ String _sdkVersion;
 
   /// The cached language version of this SDK.
-  Version _languageVersion;
+  /*late final*/ Version _languageVersion;
 
   /// The file containing the pub executable.
-  File _pubExecutable;
+  /*late final*/ File _pubExecutable;
 
   /// Initialize a newly created SDK to represent the Dart SDK installed in the
   /// [sdkDirectory].
@@ -473,8 +473,8 @@
   /// Return the initialized library map.
   LibraryMap initialLibraryMap() {
     List<String> searchedPaths = <String>[];
-    StackTrace lastStackTrace;
-    Object lastException;
+    /*late*/ StackTrace lastStackTrace;
+    /*late*/ Object lastException;
     for (File librariesFile in _libraryMapLocations) {
       try {
         String contents = librariesFile.readAsStringSync();
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 0e9ad99..729e32c 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -210,8 +210,8 @@
   }
 
   void createTypeProviders(
-    LibraryElementImpl dartCore,
-    LibraryElementImpl dartAsync,
+    LibraryElementImpl /*!*/ dartCore,
+    LibraryElementImpl /*!*/ dartAsync,
   ) {
     if (analysisContext.typeProviderNonNullableByDefault != null) {
       return;
diff --git a/pkg/analyzer/test/embedder_tests.dart b/pkg/analyzer/test/embedder_tests.dart
index c59eb00..ac01db8 100644
--- a/pkg/analyzer/test/embedder_tests.dart
+++ b/pkg/analyzer/test/embedder_tests.dart
@@ -14,8 +14,8 @@
   final String foxPath = '/home/.pub-cache/fox';
   final String foxLib = '/home/.pub-cache/fox/lib';
 
-  TestPathTranslator pathTranslator;
-  ResourceProvider resourceProvider;
+  /*late*/ TestPathTranslator pathTranslator;
+  /*late*/ ResourceProvider resourceProvider;
 
   buildResourceProvider() {
     MemoryResourceProvider rawProvider = MemoryResourceProvider();
@@ -34,16 +34,7 @@
 ''');
   }
 
-  clearResourceProvider() {
-    resourceProvider = null;
-    pathTranslator = null;
-  }
-
   void setUp() {
     buildResourceProvider();
   }
-
-  void tearDown() {
-    clearResourceProvider();
-  }
 }
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index b5a67dd..148b6cd 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -2140,6 +2140,10 @@
       } else if (node is ir.Constructor) {
         parts.add(utils.reconstructConstructorName(getMember(node)));
         break;
+      } else if (node is ir.Field) {
+        // Add the field name for closures in field initializers.
+        String name = node.name?.name;
+        if (name != null) parts.add(name);
       }
       current = current.parent;
     }
diff --git a/pkg/js/README.md b/pkg/js/README.md
index e5563a1..7279082 100644
--- a/pkg/js/README.md
+++ b/pkg/js/README.md
@@ -201,3 +201,10 @@
 **Workaround:** Avoid importing `dart:js` and only use the `package:js` provided
 approach. To handle object literals use `@anonymous` on an `@JS()` annotated
 class.
+
+#### `is` checks and `as` casts between JS interop types will always succeed
+
+For any two `@JS()` types, with or without `@anonymous`, a check of whether an
+object of one type `is` another type will always return true, regardless of
+whether those two types are in the same prototype chain. Similarly, an explicit
+cast using `as` will also succeed.
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index 6ca0990..c07969e 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -133,6 +133,7 @@
 
   @visibleForTesting
   static String optCodeOutOfNullSafety(String code) {
+    var newline = '\n';
     var length = code.length;
 
     if (length == 0) {
@@ -156,12 +157,19 @@
 
     // Skip past blank lines.
     var line = getLine();
+    if (code.codeUnitAt(index - 1) == $lf) {
+      if (index - 2 >= 0 && code.codeUnitAt(index - 2) == $cr) {
+        // Looks like Windows-style line endings ("\r\n"). Use "\r\n" for all
+        // inserted line endings.
+        newline = '\r\n';
+      }
+    }
     var lineStart = line.indexOf(_nonWhitespaceChar);
     while (lineStart < 0) {
       line = getLine();
       if (index == length) {
         // [code] consists _only_ of blank lines.
-        return '// @dart=2.9\n\n$code';
+        return '// @dart=2.9$newline$newline$code';
       }
       lineStart = line.indexOf(_nonWhitespaceChar);
     }
@@ -173,7 +181,7 @@
       // Comment.
       if (index == length) {
         // [code] consists _only_ of one comment line.
-        return '$code\n\n// @dart=2.9\n';
+        return '$code$newline$newline// @dart=2.9$newline';
       }
       line = getLine();
       lineStart = line.indexOf(_nonWhitespaceChar);
@@ -185,17 +193,17 @@
         line = getLine();
         if (index == length) {
           // [code] consists _only_ of this block comment.
-          return '$code\n\n// @dart=2.9\n';
+          return '$code$newline$newline// @dart=2.9$newline';
         }
         lineStart = line.indexOf(_nonWhitespaceChar);
       }
       // [index] points to the start of [line], which is the first
       // non-comment line following the first comment.
-      return '${code.substring(0, index)}\n// @dart=2.9\n\n'
+      return '${code.substring(0, index)}$newline// @dart=2.9$newline$newline'
           '${code.substring(index)}';
     } else {
       // [code] does not start with a block comment.
-      return '// @dart=2.9\n\n$code';
+      return '// @dart=2.9$newline$newline$code';
     }
   }
 }
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 6cb416a..c725f02 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -145,12 +145,24 @@
         equals('// @dart=2.9\n\n  \n  \n'));
   }
 
+  void test_optOutOfNullSafety_blankLines_windows() {
+    expect(IncrementalPlan.optCodeOutOfNullSafety('  \r\n  \r\n'),
+        equals('// @dart=2.9\r\n\r\n  \r\n  \r\n'));
+  }
+
   void test_optOutOfNullSafety_commentThenCode() {
     expect(
         IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
         equals('// comment\n\n\n// @dart=2.9\n\nvoid main() {}'));
   }
 
+  void test_optOutOfNullSafety_commentThenCode_windows() {
+    expect(
+        IncrementalPlan.optCodeOutOfNullSafety(
+            '// comment\r\n\r\nvoid main() {}'),
+        equals('// comment\r\n\r\n\r\n// @dart=2.9\r\n\r\nvoid main() {}'));
+  }
+
   void test_optOutOfNullSafety_empty() {
     expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
   }
@@ -185,6 +197,11 @@
         equals('// @dart=2.9\n\n\n\nvoid main() {}'));
   }
 
+  void test_optOutOfNullSafety_singleLine_windows() {
+    expect(IncrementalPlan.optCodeOutOfNullSafety('void main() {}\r\n'),
+        equals('// @dart=2.9\r\n\r\nvoid main() {}\r\n'));
+  }
+
   void test_performEdit() {
     final path = convertPath('/test.dart');
     final file = getFile(path);
@@ -373,39 +390,6 @@
     expect(getFile(path).readAsStringSync(), '// @dart=2.9');
   }
 
-  void test_applyMigration_optOutOne_migrateAnother() async {
-    final pathA = convertPath('$projectPath/lib/a.dart');
-    final pathB = convertPath('$projectPath/lib/b.dart');
-    final content = 'void main() {}';
-    await setUpMigrationInfo({pathA: content, pathB: content});
-    site.unitInfoMap[pathA] = UnitInfo(pathA)
-      ..diskContent = content
-      ..wasExplicitlyOptedOut = false;
-    site.unitInfoMap[pathB] = UnitInfo(pathB)
-      ..diskContent = content
-      ..wasExplicitlyOptedOut = false;
-    dartfixListener.addSourceFileEdit(
-        'test change',
-        Location(pathA, 10, 0, 1, 10),
-        SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
-    dartfixListener.addSourceFileEdit(
-        'test change',
-        Location(pathB, 10, 0, 1, 10),
-        SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
-    var navigationTree =
-        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
-    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
-    (libDir.subtree[0] as NavigationTreeFileNode).migrationStatus =
-        UnitMigrationStatus.optingOut;
-    site.performApply(navigationTree);
-    expect(getFile(pathA).readAsStringSync(), '''
-// @dart=2.9
-
-void main() {}''');
-    expect(getFile(pathB).readAsStringSync(), '''
-void main(List args) {}''');
-  }
-
   void test_applyMigration_optOutFileWithEdits() async {
     final path = convertPath('$projectPath/lib/a.dart');
     final content = 'void main() {}';
@@ -448,6 +432,39 @@
 void main() {}''');
   }
 
+  void test_applyMigration_optOutOne_migrateAnother() async {
+    final pathA = convertPath('$projectPath/lib/a.dart');
+    final pathB = convertPath('$projectPath/lib/b.dart');
+    final content = 'void main() {}';
+    await setUpMigrationInfo({pathA: content, pathB: content});
+    site.unitInfoMap[pathA] = UnitInfo(pathA)
+      ..diskContent = content
+      ..wasExplicitlyOptedOut = false;
+    site.unitInfoMap[pathB] = UnitInfo(pathB)
+      ..diskContent = content
+      ..wasExplicitlyOptedOut = false;
+    dartfixListener.addSourceFileEdit(
+        'test change',
+        Location(pathA, 10, 0, 1, 10),
+        SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
+    dartfixListener.addSourceFileEdit(
+        'test change',
+        Location(pathB, 10, 0, 1, 10),
+        SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
+    var navigationTree =
+        NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
+    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
+    (libDir.subtree[0] as NavigationTreeFileNode).migrationStatus =
+        UnitMigrationStatus.optingOut;
+    site.performApply(navigationTree);
+    expect(getFile(pathA).readAsStringSync(), '''
+// @dart=2.9
+
+void main() {}''');
+    expect(getFile(pathB).readAsStringSync(), '''
+void main(List args) {}''');
+  }
+
   void test_applyMigration_optOutPreviouslyOptedOutFile() async {
     final path = convertPath('$projectPath/lib/a.dart');
     final content = '''
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index f0fa4f0..7fa6bbe 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -240,18 +240,13 @@
   Object rawJSTypeForCheck() => _getRawJSType() ?? jsobject;
 
   @notNull
-  bool isRawJSType(obj) {
-    var raw = _getRawJSType();
-    if (raw != null) return JS('!', '# instanceof #', obj, raw);
-    return _isJsObject(obj);
-  }
-
-  @notNull
   @JSExportName('is')
-  bool is_T(obj) => isRawJSType(obj) || instanceOf(obj, this);
+  bool is_T(obj) =>
+      obj != null &&
+      (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));
 
   @JSExportName('as')
-  as_T(obj) => obj == null || is_T(obj) ? obj : castError(obj, this);
+  as_T(obj) => is_T(obj) ? obj : castError(obj, this);
 }
 
 /// An anonymous JS type
@@ -263,10 +258,12 @@
   toString() => _dartName;
 
   @JSExportName('is')
-  bool is_T(obj) => _isJsObject(obj) || instanceOf(obj, this);
+  bool is_T(obj) =>
+      obj != null &&
+      (_isJsObject(obj) || isSubtypeOf(getReifiedType(obj), this));
 
   @JSExportName('as')
-  as_T(obj) => obj == null || _isJsObject(obj) ? obj : cast(obj, this);
+  as_T(obj) => is_T(obj) ? obj : castError(obj, this);
 }
 
 void _warn(arg) {
diff --git a/tests/lib/html/js_mock_test.dart b/tests/lib/html/js_mock_test.dart
deleted file mode 100644
index 310abc9..0000000
--- a/tests/lib/html/js_mock_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@JS()
-library mock;
-
-import 'package:js/js.dart';
-import 'package:expect/minitest.dart';
-
-@JS('Node')
-class Node {}
-
-@JS('HTMLDocument')
-class Document extends Node {
-  external Element get body;
-}
-
-@JS()
-external get foo;
-
-@JS()
-external Document get document;
-
-@JS('Element')
-class Element extends Node {
-  external String get tagName;
-}
-
-class MockDocument implements Document {
-  final Element body = new MockElement();
-}
-
-class MockElement implements Element {
-  final tagName = 'MockBody';
-}
-
-void main() {
-  test('js', () {
-    var f = foo;
-    expect(f, isNull);
-
-    var doc = document;
-    expect(doc is Document, isTrue);
-    // Fails in dart2js
-    //expect(doc is! Element, isTrue);
-
-    expect(doc is Node, isTrue);
-
-    expect(doc is! MockDocument, isTrue);
-    expect(doc is! MockElement, isTrue);
-  });
-
-  test('mock', () {
-    var doc = new MockDocument();
-    expect(doc is Document, isTrue);
-    // Fails in dart2js
-    // expect(doc is! Element, isTrue);
-    expect(doc is Node, isTrue);
-
-    var body = doc.body;
-    // Fails in dart2js
-    // expect(body is! Document, isTrue);
-    expect(body is Element, isTrue);
-    expect(body is Node, isTrue);
-  });
-}
diff --git a/tests/lib/html/js_typed_interop_lazy_test.dart b/tests/lib/html/js_typed_interop_lazy_test.dart
index 98b26ff..63c578d 100644
--- a/tests/lib/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib/html/js_typed_interop_lazy_test.dart
@@ -133,7 +133,6 @@
       expect(l is AnonClass, isTrue);
       expect((l as AnonClass) == l, isTrue);
       expect((l as AnonClass2) == l, isTrue);
-      expect(anon is! LazyClass, isTrue); //# 01: ok
       expect(anon is AnonClass, isTrue);
       expect(anon is AnonClass2, isTrue);
 
@@ -226,7 +225,6 @@
       expect(l is AnonClass, isTrue);
       expect((l as AnonClass) == l, isTrue);
       expect((l as AnonClass2) == l, isTrue);
-      expect(anon is! NestedLazyClass, isTrue); //# 01: ok
       expect(anon is AnonClass, isTrue);
       expect(anon is AnonClass2, isTrue);
 
diff --git a/tests/lib/js/is_check_and_as_cast_test.dart b/tests/lib/js/is_check_and_as_cast_test.dart
index d88255c..b84e625 100644
--- a/tests/lib/js/is_check_and_as_cast_test.dart
+++ b/tests/lib/js/is_check_and_as_cast_test.dart
@@ -136,12 +136,21 @@
   expect(() => (a as DartClass), throws);
 
   // Test that nullability is still respected with JS types.
+  expect(foo is Foo?, isTrue);
+  expect(() => (foo as Foo?), returnsNormally);
   Foo? nullableFoo = null;
-  expect(nullableFoo is Foo, false);
+  expect(nullableFoo is Foo?, isTrue);
+  expect(() => (nullableFoo as Foo?), returnsNormally);
+  expect(nullableFoo is Foo, isFalse);
   expect(() => (nullableFoo as Foo),
       hasUnsoundNullSafety ? returnsNormally : throws);
+
+  expect(a is LiteralA?, isTrue);
+  expect(() => (a as LiteralA?), returnsNormally);
   LiteralA? nullableA = null;
-  expect(nullableA is LiteralA, false);
+  expect(nullableA is LiteralA?, isTrue);
+  expect(() => (nullableA as LiteralA?), returnsNormally);
+  expect(nullableA is LiteralA, isFalse);
   expect(() => (nullableA as LiteralA),
       hasUnsoundNullSafety ? returnsNormally : throws);
 }
diff --git a/tests/lib/js/mock_test.dart b/tests/lib/js/mock_test.dart
new file mode 100644
index 0000000..a33ac5e
--- /dev/null
+++ b/tests/lib/js/mock_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library mock_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class JSClass {}
+
+@JS()
+class DerivedA extends JSClass {
+  external DerivedB get derivedB;
+}
+
+@JS()
+external DerivedA get derivedA;
+
+@JS()
+class DerivedB extends JSClass {}
+
+class MockDerivedA implements DerivedA {
+  final DerivedB derivedB = new MockDerivedB();
+}
+
+class MockDerivedB implements DerivedB {}
+
+void main() {
+  eval(r"""
+    function inherits(child, parent) {
+      if (child.prototype.__proto__) {
+        child.prototype.__proto__ = parent.prototype;
+      } else {
+        function tmp() {};
+        tmp.prototype = parent.prototype;
+        child.prototype = new tmp();
+        child.prototype.constructor = child;
+      }
+    }
+    function JSClass() {
+    }
+    function DerivedA() {
+      JSClass.call(this);
+      this.derivedB = new DerivedB();
+    }
+    inherits(DerivedA, JSClass);
+    function DerivedB() {
+      JSClass.call(this);
+    }
+    inherits(DerivedB, JSClass);
+    var derivedA = new DerivedA();
+  """);
+  test('js', () {
+    var jsA = derivedA;
+    // `is` checks will return true for any two JS interop types.
+    expect(jsA is JSClass, isTrue);
+    expect(jsA is DerivedA, isTrue);
+    expect(jsA is DerivedB, isTrue);
+
+    expect(jsA is! MockDerivedA, isTrue);
+    expect(jsA is! MockDerivedB, isTrue);
+  });
+
+  test('mock', () {
+    var mockA = new MockDerivedA();
+    expect(mockA is JSClass, isTrue); //# 44252: ok
+    expect(mockA is DerivedA, isTrue);
+    // Fails in dart2js
+    // expect(mockA is! DerivedB, isTrue);
+    expect(mockA is MockDerivedA, isTrue);
+    expect(mockA is! MockDerivedB, isTrue);
+
+    var mockB = mockA.derivedB;
+    expect(mockB is JSClass, isTrue); //# 44252: continued
+    // Fails in dart2js
+    // expect(mockB is! DerivedA, isTrue);
+    expect(mockB is DerivedB, isTrue);
+    expect(mockB is! MockDerivedA, isTrue);
+    expect(mockB is MockDerivedB, isTrue);
+  });
+}
diff --git a/tests/lib_2/html/js_mock_test.dart b/tests/lib_2/html/js_mock_test.dart
deleted file mode 100644
index 310abc9..0000000
--- a/tests/lib_2/html/js_mock_test.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-@JS()
-library mock;
-
-import 'package:js/js.dart';
-import 'package:expect/minitest.dart';
-
-@JS('Node')
-class Node {}
-
-@JS('HTMLDocument')
-class Document extends Node {
-  external Element get body;
-}
-
-@JS()
-external get foo;
-
-@JS()
-external Document get document;
-
-@JS('Element')
-class Element extends Node {
-  external String get tagName;
-}
-
-class MockDocument implements Document {
-  final Element body = new MockElement();
-}
-
-class MockElement implements Element {
-  final tagName = 'MockBody';
-}
-
-void main() {
-  test('js', () {
-    var f = foo;
-    expect(f, isNull);
-
-    var doc = document;
-    expect(doc is Document, isTrue);
-    // Fails in dart2js
-    //expect(doc is! Element, isTrue);
-
-    expect(doc is Node, isTrue);
-
-    expect(doc is! MockDocument, isTrue);
-    expect(doc is! MockElement, isTrue);
-  });
-
-  test('mock', () {
-    var doc = new MockDocument();
-    expect(doc is Document, isTrue);
-    // Fails in dart2js
-    // expect(doc is! Element, isTrue);
-    expect(doc is Node, isTrue);
-
-    var body = doc.body;
-    // Fails in dart2js
-    // expect(body is! Document, isTrue);
-    expect(body is Element, isTrue);
-    expect(body is Node, isTrue);
-  });
-}
diff --git a/tests/lib_2/html/js_typed_interop_lazy_test.dart b/tests/lib_2/html/js_typed_interop_lazy_test.dart
index 429e135..3fce5a0 100644
--- a/tests/lib_2/html/js_typed_interop_lazy_test.dart
+++ b/tests/lib_2/html/js_typed_interop_lazy_test.dart
@@ -133,7 +133,6 @@
       expect(l is AnonClass, isTrue);
       expect((l as AnonClass) == l, isTrue);
       expect((l as AnonClass2) == l, isTrue);
-      expect(anon is! LazyClass, isTrue); //# 01: ok
       expect(anon is AnonClass, isTrue);
       expect(anon is AnonClass2, isTrue);
 
@@ -226,7 +225,6 @@
       expect(l is AnonClass, isTrue);
       expect((l as AnonClass) == l, isTrue);
       expect((l as AnonClass2) == l, isTrue);
-      expect(anon is! NestedLazyClass, isTrue); //# 01: ok
       expect(anon is AnonClass, isTrue);
       expect(anon is AnonClass2, isTrue);
 
diff --git a/tests/lib_2/js/mock_test.dart b/tests/lib_2/js/mock_test.dart
new file mode 100644
index 0000000..a33ac5e
--- /dev/null
+++ b/tests/lib_2/js/mock_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library mock_test;
+
+import 'package:js/js.dart';
+import 'package:expect/minitest.dart';
+
+@JS()
+external void eval(String code);
+
+@JS()
+class JSClass {}
+
+@JS()
+class DerivedA extends JSClass {
+  external DerivedB get derivedB;
+}
+
+@JS()
+external DerivedA get derivedA;
+
+@JS()
+class DerivedB extends JSClass {}
+
+class MockDerivedA implements DerivedA {
+  final DerivedB derivedB = new MockDerivedB();
+}
+
+class MockDerivedB implements DerivedB {}
+
+void main() {
+  eval(r"""
+    function inherits(child, parent) {
+      if (child.prototype.__proto__) {
+        child.prototype.__proto__ = parent.prototype;
+      } else {
+        function tmp() {};
+        tmp.prototype = parent.prototype;
+        child.prototype = new tmp();
+        child.prototype.constructor = child;
+      }
+    }
+    function JSClass() {
+    }
+    function DerivedA() {
+      JSClass.call(this);
+      this.derivedB = new DerivedB();
+    }
+    inherits(DerivedA, JSClass);
+    function DerivedB() {
+      JSClass.call(this);
+    }
+    inherits(DerivedB, JSClass);
+    var derivedA = new DerivedA();
+  """);
+  test('js', () {
+    var jsA = derivedA;
+    // `is` checks will return true for any two JS interop types.
+    expect(jsA is JSClass, isTrue);
+    expect(jsA is DerivedA, isTrue);
+    expect(jsA is DerivedB, isTrue);
+
+    expect(jsA is! MockDerivedA, isTrue);
+    expect(jsA is! MockDerivedB, isTrue);
+  });
+
+  test('mock', () {
+    var mockA = new MockDerivedA();
+    expect(mockA is JSClass, isTrue); //# 44252: ok
+    expect(mockA is DerivedA, isTrue);
+    // Fails in dart2js
+    // expect(mockA is! DerivedB, isTrue);
+    expect(mockA is MockDerivedA, isTrue);
+    expect(mockA is! MockDerivedB, isTrue);
+
+    var mockB = mockA.derivedB;
+    expect(mockB is JSClass, isTrue); //# 44252: continued
+    // Fails in dart2js
+    // expect(mockB is! DerivedA, isTrue);
+    expect(mockB is DerivedB, isTrue);
+    expect(mockB is! MockDerivedA, isTrue);
+    expect(mockB is MockDerivedB, isTrue);
+  });
+}
diff --git a/tools/VERSION b/tools/VERSION
index af89db5..7cff4c5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 139
+PRERELEASE 140
 PRERELEASE_PATCH 0
\ No newline at end of file