Version 2.11.0-225.0.dev

Merge commit '00a28b579771f74efbcc274e3a40c5840f57820b' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index f28f239..1402523 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -235,14 +235,6 @@
         librariesLoaded += cycle.libraries.length;
       }
 
-      // We are about to load dart:core, but if we have just linked it, the
-      // linker might have set the type provider. So, clear it, and recreate
-      // the element factory - it is empty anyway.
-      if (!elementFactory.hasDartCore) {
-        analysisContext.clearTypeProvider();
-        _createElementFactory();
-      }
-
       var bundle = LinkedNodeBundle.fromBuffer(bytes);
       inputBundles.add(bundle);
       elementFactory.addBundle(
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 53409d0..bd7ab2fa 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -271,6 +271,49 @@
     return file.libraryCycle.signatureStr;
   }
 
+  /// Ensure that libraries necessary for resolving [path] are linked.
+  ///
+  /// Libraries are linked in library cycles, from the bottom to top, so that
+  /// when we link a cycle, everything it transitively depends is ready. We
+  /// load newly linked libraries from bytes, and when we link a new library
+  /// cycle we partially resynthesize AST and elements from previously
+  /// loaded libraries.
+  ///
+  /// But when we are done linking libraries, and want to resolve just the
+  /// very top library that transitively depends on the whole dependency
+  /// tree, this library will not reference as many elements in the
+  /// dependencies as we needed for linking. Most probably it references
+  /// elements from directly imported libraries, and a couple of layers below.
+  /// So, keeping all previously resynthesized data is usually a waste.
+  ///
+  /// This method ensures that we discard the libraries context, with all its
+  /// partially resynthesized data, and so prepare for loading linked summaries
+  /// from bytes, which will be done by [getErrors]. It is OK for it to
+  /// spend some more time on this.
+  void linkLibraries({
+    @required String path,
+  }) {
+    _throwIfNotAbsoluteNormalizedPath(path);
+
+    var performance = OperationPerformanceImpl('<unused>');
+
+    _withLibraryContextReset(() {
+      var fileContext = getFileContext(
+        path: path,
+        performance: performance,
+      );
+      var file = fileContext.file;
+      var libraryFile = file.partOfLibrary ?? file;
+
+      libraryContext.load2(
+        targetLibrary: libraryFile,
+        performance: performance,
+      );
+    });
+
+    _resetContextObjects();
+  }
+
   /// The [completionLine] and [completionColumn] are zero based.
   ResolvedUnitResult resolve({
     int completionLine,
@@ -531,6 +574,13 @@
     }
   }
 
+  void _resetContextObjects() {
+    if (libraryContext != null) {
+      contextObjects = null;
+      libraryContext = null;
+    }
+  }
+
   void _throwIfNotAbsoluteNormalizedPath(String path) {
     var pathContext = resourceProvider.pathContext;
     if (pathContext.normalize(path) != path) {
@@ -691,14 +741,6 @@
         performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
       }
 
-      // We are about to load dart:core, but if we have just linked it, the
-      // linker might have set the type provider. So, clear it, and recreate
-      // the element factory - it is empty anyway.
-      if (!elementFactory.hasDartCore) {
-        contextObjects.analysisContext.clearTypeProvider();
-        elementFactory.declareDartCoreDynamicNever();
-      }
-
       var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
       inputBundles.add(cBundle.bundle);
       elementFactory.addBundle(
@@ -715,6 +757,9 @@
           );
         }
       }
+
+      // We might have just linked dart:core, ensure the type provider.
+      _createElementFactoryTypeProvider();
     }
 
     logger.run('Prepare linked bundles', () {
@@ -732,7 +777,7 @@
   /// If we need these libraries later, we will relink and reattach them.
   void remove(List<FileState> removed) {
     elementFactory.removeLibraries(
-      removed.map((e) => e.uriStr).toList(),
+      removed.map((e) => e.uriStr).toSet(),
     );
 
     var removedSet = removed.toSet();
@@ -741,6 +786,16 @@
     });
   }
 
+  /// Ensure that type provider is created.
+  void _createElementFactoryTypeProvider() {
+    var analysisContext = contextObjects.analysisContext;
+    if (analysisContext.typeProviderNonNullableByDefault == null) {
+      var dartCore = elementFactory.libraryOfUri('dart:core');
+      var dartAsync = elementFactory.libraryOfUri('dart:async');
+      elementFactory.createTypeProviders(dartCore, dartAsync);
+    }
+  }
+
   static CiderLinkedLibraryCycleBuilder serializeBundle(
       List<int> signature, link2.LinkResult linkResult) {
     return CiderLinkedLibraryCycleBuilder(
@@ -791,10 +846,7 @@
       if (resetTimeout != null) {
         _timer = Timer(resetTimeout, () {
           _timer = null;
-          if (fileResolver.libraryContext != null) {
-            fileResolver.contextObjects = null;
-            fileResolver.libraryContext = null;
-          }
+          fileResolver._resetContextObjects();
         });
       }
     }
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 8dd1b7c..abfaeec 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -28,7 +28,7 @@
   ) {
     ArgumentError.checkNotNull(analysisContext, 'analysisContext');
     ArgumentError.checkNotNull(analysisSession, 'analysisSession');
-    declareDartCoreDynamicNever();
+    _declareDartCoreDynamicNever();
   }
 
   Reference get dynamicRef {
@@ -95,12 +95,6 @@
     }
   }
 
-  void declareDartCoreDynamicNever() {
-    var dartCoreRef = rootReference.getChild('dart:core');
-    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
-    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
-  }
-
   Element elementOfReference(Reference reference) {
     if (reference.element != null) {
       return reference.element;
@@ -147,19 +141,38 @@
   /// We have linked the bundle, and need to disconnect its libraries, so
   /// that the client can re-add the bundle, this time read from bytes.
   void removeBundle(LinkedBundleContext context) {
-    var uriStrList = context.libraryMap.keys.toList();
-    removeLibraries(uriStrList);
+    var uriStrSet = context.libraryMap.keys.toSet();
+    removeLibraries(uriStrSet);
+
+    // This is the bundle with dart:core and dart:async, based on full ASTs.
+    // To link them, the linker set the type provider. We are removing these
+    // libraries, and we should also remove the type provider.
+    if (uriStrSet.contains('dart:core')) {
+      if (!uriStrSet.contains('dart:async')) {
+        throw StateError(
+          'Expected to link dart:core and dart:async together: '
+          '${uriStrSet.toList()}',
+        );
+      }
+      if (libraryMap.isNotEmpty) {
+        throw StateError(
+          'Expected to link dart:core and dart:async first: '
+          '${libraryMap.keys.toList()}',
+        );
+      }
+      analysisContext.clearTypeProvider();
+      _declareDartCoreDynamicNever();
+    }
   }
 
   /// Remove libraries with the specified URIs from the reference tree, and
   /// any session level caches.
-  void removeLibraries(List<String> uriStrList) {
-    for (var uriStr in uriStrList) {
+  void removeLibraries(Set<String> uriStrSet) {
+    for (var uriStr in uriStrSet) {
       libraryMap.remove(uriStr);
       rootReference.removeChild(uriStr);
     }
 
-    var uriStrSet = uriStrList.toSet();
     analysisSession.classHierarchy.removeOfLibraries(uriStrSet);
     analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
   }
@@ -181,6 +194,12 @@
     }
   }
 
+  void _declareDartCoreDynamicNever() {
+    var dartCoreRef = rootReference.getChild('dart:core');
+    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
+    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+  }
+
   void _setLibraryTypeSystem(LibraryElementImpl libraryElement) {
     // During linking we create libraries when typeProvider is not ready.
     // And if we link dart:core and dart:async, we cannot create it.
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 45500b8..5a7a974 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
@@ -464,6 +464,24 @@
     ]);
   }
 
+  test_linkLibraries_getErrors() {
+    addTestFile(r'''
+var a = b;
+var foo = 0;
+''');
+
+    var path = convertPath('/workspace/dart/test/lib/test.dart');
+    fileResolver.linkLibraries(path: path);
+
+    var result = getTestErrors();
+    expect(result.path, path);
+    expect(result.uri.toString(), 'package:dart.test/test.dart');
+    assertErrorsInList(result.errors, [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 8, 1),
+    ]);
+    expect(result.lineInfo.lineStarts, [0, 11, 24]);
+  }
+
   test_nullSafety_enabled() async {
     typeToStringWithNullability = true;
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index d54ecef..d12313b 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1776,14 +1776,23 @@
   js_ast.Fun _emitNativeFunctionBody(Procedure node) {
     var name = _annotationName(node, isJSAnnotation) ?? node.name.text;
     if (node.isGetter) {
-      return js_ast.Fun([], js.block('{ return this.#; }', [name]));
+      var returnValue = js('this.#', [name]);
+      if (_isNullCheckableNative(node)) {
+        // Add a potential null-check on native getter if type is non-nullable.
+        returnValue = runtimeCall('checkNativeNonNull(#)', [returnValue]);
+      }
+      return js_ast.Fun([], js.block('{ return #; }', [returnValue]));
     } else if (node.isSetter) {
       var params = _emitParameters(node.function);
       return js_ast.Fun(
           params, js.block('{ this.# = #; }', [name, params.last]));
     } else {
-      return js.fun(
-          'function (...args) { return this.#.apply(this, args); }', name);
+      var returnValue = js('this.#.apply(this, args)', [name]);
+      if (_isNullCheckableNative(node)) {
+        // Add a potential null-check on return value if type is non-nullable.
+        returnValue = runtimeCall('checkNativeNonNull(#)', [returnValue]);
+      }
+      return js.fun('function (...args) { return #; }', [returnValue]);
     }
   }
 
@@ -2270,6 +2279,9 @@
       // Fields on a native class are implicitly native.
       // Methods/getters/setters are marked external/native.
       if (member is Field || _isExternal(member)) {
+        // If the native member needs to be null-checked, we require symbolizing
+        // it in order to access the null-check at the member definition.
+        if (_isNullCheckableNative(member)) return true;
         var jsName = _annotationName(member, isJSName);
         return jsName != null && jsName != name;
       } else {
@@ -4215,14 +4227,8 @@
 
   @override
   js_ast.Expression visitPropertyGet(PropertyGet node) {
-    var propertyGet =
-        _emitPropertyGet(node.receiver, node.interfaceTarget, node.name.text);
-    if (_isCheckableNative(node.interfaceTarget)) {
-      // If target is a native getter with a non-nullable type, add a null check
-      // for soundness.
-      return runtimeCall('checkNativeNonNull(#)', [propertyGet]);
-    }
-    return propertyGet;
+    return _emitPropertyGet(
+        node.receiver, node.interfaceTarget, node.name.text);
   }
 
   @override
@@ -4276,8 +4282,8 @@
   }
 
   /// Return whether [member] returns a native object whose type needs to be
-  /// checked.
-  bool _isCheckableNative(Member member) =>
+  /// null-checked. This is true for non-nullable native return types.
+  bool _isNullCheckableNative(Member member) =>
       member != null &&
       member.isExternal &&
       _extensionTypes.isNativeClass(member.enclosingClass) &&
@@ -4355,14 +4361,8 @@
 
   @override
   js_ast.Expression visitMethodInvocation(MethodInvocation node) {
-    var methodCall = _emitMethodCall(
+    return _emitMethodCall(
         node.receiver, node.interfaceTarget, node.arguments, node);
-    if (_isCheckableNative(node.interfaceTarget)) {
-      // If target is a native method with a non-nullable type, add a null check
-      // for soundness.
-      return runtimeCall('checkNativeNonNull(#)', [methodCall]);
-    }
-    return methodCall;
   }
 
   js_ast.Expression _emitMethodCall(Expression receiver, Member target,
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 7165b63..b1531d0 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -61,10 +61,6 @@
     --mode2            : m2, and values one of
         jit-[debug-][ia32|x64|arm32|arm64]               = Dart JIT
         aot-[debug-][x64|arm32|arm64]                    = Dart AOT
-        kbc-[int|mix|cmp]-[debug-][ia32|x64|arm32|arm64] = Dart KBC
-                                                           (interpreted/
-                                                            mixed-mode/
-                                                            compiled bytecode)
         djs-x64                                          = dart2js + Node.JS
     --[no-]rerun       : re-run a testcase if there is only a divergence in
                          the return codes outside the range [-255,+255];
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 8093309..8e826fa 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -51,26 +51,6 @@
     String prefix = mode.substring(0, 3).toUpperCase();
     String tag = getTag(mode);
     List<String> extraFlags = [];
-    // Required extra flags for kbc.
-    if (mode.startsWith('kbc-int')) {
-      prefix += '-INT';
-      extraFlags += [
-        '--enable-interpreter',
-        '--compilation-counter-threshold=-1'
-      ];
-    } else if (mode.startsWith('kbc-mix')) {
-      prefix += '-MIX';
-      extraFlags += ['--enable-interpreter'];
-    } else if (mode.startsWith('kbc-cmp')) {
-      prefix += '-CMP';
-      extraFlags += ['--use-bytecode-compiler'];
-    }
-    // Every once in a while, go directly from source for kbc.
-    bool kbcSrc = false;
-    if (mode.startsWith('kbc') && rand.nextInt(4) == 0) {
-      prefix += '-SRC';
-      kbcSrc = true;
-    }
     // Every once in a while, stress test JIT.
     if (mode.startsWith('jit') && rand.nextInt(4) == 0) {
       final r = rand.nextInt(7);
@@ -126,9 +106,6 @@
       return TestRunnerJIT(prefix, tag, top, tmp, env, fileName, extraFlags);
     } else if (mode.startsWith('aot')) {
       return TestRunnerAOT(prefix, tag, top, tmp, env, fileName, extraFlags);
-    } else if (mode.startsWith('kbc')) {
-      return TestRunnerKBC(
-          prefix, tag, top, tmp, env, fileName, extraFlags, kbcSrc);
     } else if (mode.startsWith('djs')) {
       return TestRunnerDJS(prefix, tag, top, tmp, env, fileName);
     }
@@ -227,60 +204,6 @@
   List<String> cmd;
 }
 
-/// Concrete test runner of bytecode.
-class TestRunnerKBC implements TestRunner {
-  TestRunnerKBC(String prefix, String tag, this.top, this.tmp, this.env,
-      this.fileName, List<String> extraFlags, bool kbcSrc) {
-    description = '$prefix-$tag';
-    dart = '$top/out/$tag/dart';
-    if (kbcSrc) {
-      cmd = [
-        dart,
-        ...extraFlags,
-        '--old_gen_heap_size=${dartHeapSize}',
-        fileName
-      ];
-    } else {
-      generate = '$top/pkg/vm/tool/gen_kernel';
-      platform = '--platform=$top/out/$tag/vm_platform_strong.dill';
-      dill = '$tmp/out.dill';
-      cmd = [dart, ...extraFlags, '--old_gen_heap_size=${dartHeapSize}', dill];
-    }
-  }
-
-  TestResult run() {
-    if (generate != null) {
-      TestResult result = runCommand(
-          [generate, '--gen-bytecode', platform, '-o', dill, fileName], env);
-      if (result.exitCode != 0) {
-        return result;
-      }
-    }
-    return runCommand(cmd, env);
-  }
-
-  void printReproductionCommand() {
-    if (generate != null) {
-      print([generate, '--gen-bytecode', platform, '-o', dill, fileName]
-          .join(" ")
-          .replaceAll('$top/', '')
-          .replaceAll('$tmp/', ''));
-    }
-    print(cmd.join(" ").replaceAll('$top/', '').replaceAll('$tmp/', ''));
-  }
-
-  String description;
-  String generate;
-  String platform;
-  String dill;
-  String dart;
-  String fileName;
-  final String top;
-  final String tmp;
-  Map<String, String> env;
-  List<String> cmd;
-}
-
 /// Concrete test runner of Dart2JS.
 class TestRunnerDJS implements TestRunner {
   TestRunnerDJS(
@@ -413,8 +336,8 @@
           (mode1.contains('ia32') && mode2.contains('ia32')));
 
   bool ffiCapable(String mode1, String mode2) =>
-      (mode1.startsWith('jit') || mode1.startsWith('kbc')) &&
-      (mode2.startsWith('jit') || mode2.startsWith('kbc')) &&
+      mode1.startsWith('jit') &&
+      mode2.startsWith('jit') &&
       (!mode1.contains('arm') && !mode2.contains('arm'));
 
   bool nestedTypesAllowed(String mode1, String mode2) =>
@@ -759,30 +682,6 @@
     'jit-arm64',
     'aot-debug-x64',
     'aot-x64',
-    'kbc-int-debug-ia32',
-    'kbc-cmp-debug-ia32',
-    'kbc-mix-debug-ia32',
-    'kbc-int-debug-x64',
-    'kbc-cmp-debug-x64',
-    'kbc-mix-debug-x64',
-    'kbc-int-debug-arm32',
-    'kbc-cmp-debug-arm32',
-    'kbc-mix-debug-arm32',
-    'kbc-int-debug-arm64',
-    'kbc-cmp-debug-arm64',
-    'kbc-mix-debug-arm64',
-    'kbc-int-ia32',
-    'kbc-cmp-ia32',
-    'kbc-mix-ia32',
-    'kbc-int-x64',
-    'kbc-cmp-x64',
-    'kbc-mix-x64',
-    'kbc-int-arm32',
-    'kbc-cmp-arm32',
-    'kbc-mix-arm32',
-    'kbc-int-arm64',
-    'kbc-cmp-arm64',
-    'kbc-mix-arm64',
   ];
 
   // Modes not used on cluster runs because they have outstanding issues.
diff --git a/tests/language/nnbd/inference/late_variable_type_for_promotion_test.dart b/tests/language/nnbd/inference/late_variable_type_for_promotion_test.dart
index d6223d5..fd4ebed 100644
--- a/tests/language/nnbd/inference/late_variable_type_for_promotion_test.dart
+++ b/tests/language/nnbd/inference/late_variable_type_for_promotion_test.dart
@@ -95,7 +95,7 @@
 }
 
 void uninitializedUntyped() {
-  late x;
+  late var x;
   x = 0;
   x.expectStaticType<Exactly<dynamic>>();
   // Attempting to promote to `int?` should be ok, since `int?` is a subtype of
diff --git a/tools/VERSION b/tools/VERSION
index f320424..70adc94 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 224
+PRERELEASE 225
 PRERELEASE_PATCH 0
\ No newline at end of file