Version 2.16.0-51.0.dev

Merge commit '87c953bd0c917c70de84bbf3c36e17b246b459db' into 'dev'
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index eccfa92..8f8427c 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -344,7 +344,7 @@
         incrementalCompilerResult.component,
         cachedSdkInput.component,
         doneAdditionalDills,
-        incrementalCompiler.userCode.loader.hierarchy);
+        incrementalCompilerResult.classHierarchy);
   }
   compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983.
 
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
index 864b911..6d5c418 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler_worker.dart
@@ -375,8 +375,8 @@
       };
     }
 
-    var coreTypes = incrementalCompiler.getCoreTypes();
-    var hierarchy = incrementalCompiler.getClassHierarchy();
+    var coreTypes = incrementalCompilerResult.coreTypes;
+    var hierarchy = incrementalCompilerResult.classHierarchy;
 
     var kernel2jsCompiler = ProgramCompiler(
       finalComponent,
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
index 46bc90a..90f0eef 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -123,13 +123,13 @@
     // Initialize DDC.
     var moduleName = p.basenameWithoutExtension(output.toFilePath());
 
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
         soundNullSafety: setup.soundNullSafety,
         emitDebugMetadata: true);
-    var coreTypes = compiler.getCoreTypes();
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index 5f96bcb..8dc187d 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -82,13 +82,13 @@
 
     // initialize ddc
     var moduleName = 'foo.dart';
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
         soundNullSafety: setup.soundNullSafety,
         moduleFormats: [setup.moduleFormat]);
-    var coreTypes = compiler.getCoreTypes();
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
index a989d55..b607f71 100644
--- a/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
+++ b/pkg/dev_compiler/test/module_symbols/module_symbols_test_shared.dart
@@ -31,14 +31,14 @@
 
     // Initialize DDC.
     var moduleName = 'foo.dart';
-    var classHierarchy = compiler.getClassHierarchy();
+    var classHierarchy = compilerResult.classHierarchy;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
         soundNullSafety: setup.soundNullSafety,
         moduleFormats: [setup.moduleFormat],
         emitDebugSymbols: true);
-    var coreTypes = compiler.getCoreTypes();
+    var coreTypes = compilerResult.coreTypes;
 
     final importToSummary = Map<Library, Component>.identity();
     final summaryToModule = Map<Component, String>.identity();
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index dfd05f4..c358d01 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -76,14 +76,6 @@
   Future<IncrementalCompilerResult> computeDelta(
       {List<Uri>? entryPoints, bool fullComponent});
 
-  /// Returns [CoreTypes] used during compilation.
-  /// Valid after [computeDelta] is called.
-  CoreTypes? getCoreTypes();
-
-  /// Returns [ClassHierarchy] used during compilation.
-  /// Valid after [computeDelta] is called.
-  ClassHierarchy? getClassHierarchy();
-
   /// Remove the file associated with the given file [uri] from the set of
   /// valid files.  This guarantees that those files will be re-read on the
   /// next call to [computeDelta]).
@@ -154,6 +146,9 @@
 
 class IncrementalCompilerResult {
   final Component component;
+  final ClassHierarchy? classHierarchy;
+  final CoreTypes? coreTypes;
 
-  IncrementalCompilerResult(this.component);
+  IncrementalCompilerResult(this.component,
+      {this.classHierarchy, this.coreTypes});
 }
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 747a3af..ed7fe69 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -21,8 +21,6 @@
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, ClosedWorldClassHierarchy;
 
-import 'package:kernel/core_types.dart' show CoreTypes;
-
 import 'package:kernel/kernel.dart'
     show
         Class,
@@ -419,7 +417,9 @@
       _currentlyCompiling = null;
       currentlyCompilingLocal.complete();
 
-      return new IncrementalCompilerResult(result);
+      return new IncrementalCompilerResult(result,
+          classHierarchy: _userCode?.loader.hierarchy,
+          coreTypes: _userCode?.loader.coreTypes);
     });
   }
 
@@ -1346,12 +1346,6 @@
     typeBuilder!.bind(replacement as TypeDeclarationBuilder);
   }
 
-  @override
-  CoreTypes? getCoreTypes() => _userCode?.loader.coreTypes;
-
-  @override
-  ClassHierarchy? getClassHierarchy() => _userCode?.loader.hierarchy;
-
   /// Allows for updating the list of needed libraries.
   ///
   /// Useful if a class hierarchy has been used externally.
diff --git a/pkg/front_end/lib/widget_cache.dart b/pkg/front_end/lib/widget_cache.dart
index f80f493..752b969 100644
--- a/pkg/front_end/lib/widget_cache.dart
+++ b/pkg/front_end/lib/widget_cache.dart
@@ -59,7 +59,7 @@
   String? checkSingleWidgetTypeModified(
     Component? lastGoodComponent,
     Component partialComponent,
-    ClassHierarchy classHierarchy,
+    ClassHierarchy? classHierarchy,
   ) {
     if (!_frameworkTypesLocated ||
         lastGoodComponent == null ||
@@ -124,7 +124,7 @@
     }
 
     // Update the class references to stateless, stateful, and state classes.
-    for (Library library in classHierarchy.knownLibraries) {
+    for (Library library in classHierarchy!.knownLibraries) {
       if (library.importUri == _frameworkLibrary) {
         _locatedClassDeclarations(library);
       }
diff --git a/pkg/front_end/test/ast_nodes_has_to_string_test.dart b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
index de8baa2..0c27d6f 100644
--- a/pkg/front_end/test/ast_nodes_has_to_string_test.dart
+++ b/pkg/front_end/test/ast_nodes_has_to_string_test.dart
@@ -29,7 +29,7 @@
             /*Uri initializeFrom*/ null, /*bool outlineOnly*/ true);
     IncrementalCompilerResult compilerResult = await compiler.computeDelta();
     c = compilerResult.component;
-    classHierarchy = compiler.getClassHierarchy()!;
+    classHierarchy = compilerResult.classHierarchy!;
     List<Library> libraries = c.libraries
         .where((Library lib) =>
             (lib.importUri.toString() == "package:kernel/ast.dart"))
diff --git a/pkg/front_end/test/incremental_suite.dart b/pkg/front_end/test/incremental_suite.dart
index 9c6d54f..9f00b3f 100644
--- a/pkg/front_end/test/incremental_suite.dart
+++ b/pkg/front_end/test/incremental_suite.dart
@@ -798,8 +798,7 @@
       result = checkExpectFile(data, worldNum, "", context, actualSerialized);
       if (result != null) return result;
       if (world["skipClassHierarchyTest"] != true) {
-        result =
-            checkClassHierarchy(compiler, component!, data, worldNum, context);
+        result = checkClassHierarchy(compilerResult, data, worldNum, context);
         if (result != null) return result;
       }
 
@@ -1190,10 +1189,10 @@
 ///
 /// This has the option to do expect files, but it's disabled by default
 /// while we're trying to figure out if it's useful or not.
-Result<TestData>? checkClassHierarchy(TestIncrementalCompiler compiler,
-    Component component, TestData data, int worldNum, Context context,
+Result<TestData>? checkClassHierarchy(IncrementalCompilerResult compilerResult,
+    TestData data, int worldNum, Context context,
     {bool checkExpectFile: false}) {
-  ClassHierarchy? classHierarchy = compiler.getClassHierarchy();
+  ClassHierarchy? classHierarchy = compilerResult.classHierarchy;
   if (classHierarchy is! ClosedWorldClassHierarchy) {
     return new Result<TestData>(
         data,
@@ -1213,6 +1212,7 @@
     classHierarchyMap[info.classNode] = info;
   }
 
+  Component component = compilerResult.component;
   StringBuffer sb = new StringBuffer();
   for (Library library in component.libraries) {
     if (library.importUri.scheme == "dart") continue;
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 3cd6887..706448e 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.dart
@@ -527,13 +527,14 @@
       _compilerOptions.omitPlatform = false;
       _generator = generator ?? _createGenerator(Uri.file(_initializeFromDill));
       await invalidateIfInitializingFromDill();
-      Component component =
+      IncrementalCompilerResult compilerResult =
           await _runWithPrintRedirection(() => _generator.compile());
+      Component component = compilerResult.component;
       results = KernelCompilationResults(
           component,
           const {},
-          _generator.getClassHierarchy(),
-          _generator.getCoreTypes(),
+          compilerResult.classHierarchy,
+          compilerResult.coreTypes,
           component.uriToSource.keys);
 
       incrementalSerializer = _generator.incrementalSerializer;
@@ -783,7 +784,9 @@
     }
     errors.clear();
 
-    Component deltaProgram = await _generator.compile(entryPoint: _mainSource);
+    IncrementalCompilerResult deltaProgramResult =
+        await _generator.compile(entryPoint: _mainSource);
+    Component deltaProgram = deltaProgramResult.component;
     if (deltaProgram != null && transformer != null) {
       transformer.transform(deltaProgram);
     }
@@ -791,8 +794,8 @@
     KernelCompilationResults results = KernelCompilationResults(
         deltaProgram,
         const {},
-        _generator.getClassHierarchy(),
-        _generator.getCoreTypes(),
+        deltaProgramResult.classHierarchy,
+        deltaProgramResult.coreTypes,
         deltaProgram.uriToSource.keys);
 
     if (_compilerOptions.target.name == 'dartdevc') {
@@ -871,7 +874,8 @@
         .logMs('Compiling expression to JavaScript in $moduleName');
 
     final kernel2jsCompiler = cachedProgramCompilers[moduleName];
-    Component component = _generator.lastKnownGoodComponent;
+    IncrementalCompilerResult compilerResult = _generator.lastKnownGoodResult;
+    Component component = compilerResult.component;
     component.computeCanonicalNames();
 
     _processedOptions.ticker.logMs('Computed component');
@@ -1055,9 +1059,9 @@
     }
     final String singleModifiedClassName =
         _widgetCache.checkSingleWidgetTypeModified(
-      _generator.lastKnownGoodComponent,
+      _generator.lastKnownGoodResult?.component,
       partialComponent,
-      _generator.getClassHierarchy(),
+      _generator.lastKnownGoodResult?.classHierarchy,
     );
     final File outputFile = File('$_kernelBinaryFilename.widget_cache');
     if (singleModifiedClassName != null) {
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index a586bf7..35f6315 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_test.dart
@@ -3,6 +3,7 @@
 import 'dart:io';
 import 'dart:isolate';
 
+import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
 import 'package:kernel/ast.dart' show Component;
 import 'package:kernel/kernel.dart' show loadComponentFromBinary;
@@ -420,10 +421,12 @@
 
       final _MockedIncrementalCompiler generator = _MockedIncrementalCompiler();
       when(generator.initialized).thenAnswer((_) => false);
-      when(generator.compile())
-          .thenAnswer((_) => Future<Component>.value(Component()));
-      when(generator.compile(entryPoint: anyNamed("entryPoint")))
-          .thenAnswer((_) => Future<Component>.value(Component()));
+      when(generator.compile()).thenAnswer((_) =>
+          Future<IncrementalCompilerResult>.value(
+              IncrementalCompilerResult(Component())));
+      when(generator.compile(entryPoint: anyNamed("entryPoint"))).thenAnswer(
+          (_) => Future<IncrementalCompilerResult>.value(
+              IncrementalCompilerResult(Component())));
       final _MockedBinaryPrinterFactory printerFactory =
           _MockedBinaryPrinterFactory();
       when(printerFactory.newBinaryPrinter(any))
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 8854910..f18f0d2 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -333,9 +333,10 @@
     final generator = this.generator ??= IncrementalCompiler(options, script);
     errorsPlain.clear();
     errorsColorized.clear();
-    final component = await generator.compile(entryPoint: script);
+    final compilerResult = await generator.compile(entryPoint: script);
+    final component = compilerResult.component;
     return new CompilerResult(component, const {},
-        generator.getClassHierarchy(), generator.getCoreTypes());
+        compilerResult.classHierarchy, compilerResult.coreTypes);
   }
 
   void accept() => generator!.accept();
@@ -353,7 +354,8 @@
     // TODO(VM TEAM): This does not seem safe. What if cloning while having
     // pending deltas for instance?
     generator.resetDeltaState();
-    Component fullComponent = await generator.compile();
+    IncrementalCompilerResult compilerResult = await generator.compile();
+    Component fullComponent = compilerResult.component;
 
     // Assume fileSystem is HybridFileSystem because that is the setup where
     // clone should be used for.
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index 2bf3af3..08b00e7 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -23,8 +23,8 @@
 
   // Component that reflect the state that was most recently accepted by the
   // client. Is [null], if no compilation results were accepted by the client.
-  Component? _lastKnownGood;
-  late List<Component> _pendingDeltas;
+  IncrementalCompilerResult? _lastKnownGood;
+  late List<IncrementalCompilerResult> _pendingDeltas;
   CompilerOptions _compilerOptions;
   bool initialized = false;
   bool fullComponent = false;
@@ -34,7 +34,7 @@
 
   Uri get entryPoint => _entryPoint;
   IncrementalKernelGenerator get generator => _generator;
-  Component? get lastKnownGoodComponent => _lastKnownGood;
+  IncrementalCompilerResult? get lastKnownGoodResult => _lastKnownGood;
 
   IncrementalCompiler(this._compilerOptions, this._entryPoint,
       {this.initializeFromDillUri, bool incrementalSerialization: true})
@@ -44,7 +44,7 @@
     }
     _generator = new IncrementalKernelGenerator(_compilerOptions, _entryPoint,
         initializeFromDillUri, false, incrementalSerializer);
-    _pendingDeltas = <Component>[];
+    _pendingDeltas = <IncrementalCompilerResult>[];
   }
 
   IncrementalCompiler.forExpressionCompilationOnly(
@@ -52,14 +52,14 @@
       : forExpressionCompilationOnly = true {
     _generator = new IncrementalKernelGenerator.forExpressionCompilationOnly(
         _compilerOptions, _entryPoint, component);
-    _pendingDeltas = <Component>[];
+    _pendingDeltas = <IncrementalCompilerResult>[];
   }
 
   /// Recompiles invalidated files, produces incremental component.
   ///
   /// If [entryPoint] is specified, that points to new entry point for the
   /// compilation. Otherwise, previously set entryPoint is used.
-  Future<Component> compile({Uri? entryPoint}) async {
+  Future<IncrementalCompilerResult> compile({Uri? entryPoint}) async {
     final task = new TimelineTask();
     try {
       task.start("IncrementalCompiler.compile");
@@ -68,26 +68,30 @@
       if (entryPoint != null) entryPoints = [entryPoint];
       IncrementalCompilerResult compilerResult = await _generator.computeDelta(
           entryPoints: entryPoints, fullComponent: fullComponent);
-      Component component = compilerResult.component;
       initialized = true;
       fullComponent = false;
-      _pendingDeltas.add(component);
+      _pendingDeltas.add(compilerResult);
       return _combinePendingDeltas(false);
     } finally {
       task.finish();
     }
   }
 
-  _combinePendingDeltas(bool includePlatform) {
+  IncrementalCompilerResult _combinePendingDeltas(bool includePlatform) {
     Procedure? mainMethod;
     NonNullableByDefaultCompiledMode compilationMode =
         NonNullableByDefaultCompiledMode.Invalid;
     Map<Uri, Library> combined = <Uri, Library>{};
     Map<Uri, Source> uriToSource = new Map<Uri, Source>();
-    for (Component delta in _pendingDeltas) {
+    ClassHierarchy? classHierarchy;
+    CoreTypes? coreTypes;
+    for (IncrementalCompilerResult deltaResult in _pendingDeltas) {
+      Component delta = deltaResult.component;
       if (delta.mainMethod != null) {
         mainMethod = delta.mainMethod;
       }
+      classHierarchy ??= deltaResult.classHierarchy;
+      coreTypes ??= deltaResult.coreTypes;
       compilationMode = delta.mode;
       uriToSource.addAll(delta.uriToSource);
       for (Library library in delta.libraries) {
@@ -99,14 +103,14 @@
     }
 
     // TODO(vegorov) this needs to merge metadata repositories from deltas.
-    return new Component(
-        libraries: combined.values.toList(), uriToSource: uriToSource)
-      ..setMainMethodAndMode(mainMethod?.reference, true, compilationMode);
+    return new IncrementalCompilerResult(
+        new Component(
+            libraries: combined.values.toList(), uriToSource: uriToSource)
+          ..setMainMethodAndMode(mainMethod?.reference, true, compilationMode),
+        classHierarchy: classHierarchy,
+        coreTypes: coreTypes);
   }
 
-  CoreTypes? getCoreTypes() => _generator.getCoreTypes();
-  ClassHierarchy? getClassHierarchy() => _generator.getClassHierarchy();
-
   /// This lets incremental compiler know that results of last [compile] call
   /// were accepted, don't need to be included into subsequent [compile] calls
   /// results.
@@ -118,29 +122,33 @@
     Map<Uri, Library> combined = <Uri, Library>{};
     Map<Uri, Source> uriToSource = <Uri, Source>{};
 
-    Component? lastKnownGood = _lastKnownGood;
+    IncrementalCompilerResult? lastKnownGood = _lastKnownGood;
     if (lastKnownGood != null) {
       // TODO(aam): Figure out how to skip no-longer-used libraries from
       // [_lastKnownGood] libraries.
-      for (Library library in lastKnownGood.libraries) {
+      for (Library library in lastKnownGood.component.libraries) {
         combined[library.importUri] = library;
       }
-      uriToSource.addAll(lastKnownGood.uriToSource);
+      uriToSource.addAll(lastKnownGood.component.uriToSource);
     }
 
-    Component candidate = _combinePendingDeltas(true);
+    IncrementalCompilerResult result = _combinePendingDeltas(true);
+    Component candidate = result.component;
     for (Library library in candidate.libraries) {
       combined[library.importUri] = library;
     }
     uriToSource.addAll(candidate.uriToSource);
 
-    _lastKnownGood = lastKnownGood = new Component(
-      libraries: combined.values.toList(),
-      uriToSource: uriToSource,
-    )..setMainMethodAndMode(
-        candidate.mainMethod?.reference, true, candidate.mode);
+    _lastKnownGood = lastKnownGood = new IncrementalCompilerResult(
+        new Component(
+          libraries: combined.values.toList(),
+          uriToSource: uriToSource,
+        )..setMainMethodAndMode(
+            candidate.mainMethod?.reference, true, candidate.mode),
+        classHierarchy: result.classHierarchy,
+        coreTypes: result.coreTypes);
     for (final repo in candidate.metadata.values) {
-      lastKnownGood.addMetadataRepository(repo);
+      lastKnownGood.component.addMetadataRepository(repo);
     }
     _pendingDeltas.clear();
   }
@@ -165,10 +173,10 @@
     // sure it's "updated back".
     // Note that if accept was never called [_lastKnownGood] is null (and
     // loading from it below is basically nonsense, it will just start over).
-    _lastKnownGood?.relink();
+    _lastKnownGood?.component.relink();
 
     _generator = new IncrementalKernelGenerator.fromComponent(_compilerOptions,
-        _entryPoint, _lastKnownGood, false, incrementalSerializer);
+        _entryPoint, _lastKnownGood?.component, false, incrementalSerializer);
     await _generator.computeDelta(entryPoints: [_entryPoint]);
   }
 
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index b24cb9e..62a66f4 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -12,6 +12,7 @@
         CompilerOptions,
         DiagnosticMessage,
         ExperimentalFlag,
+        IncrementalCompilerResult,
         computePlatformBinariesLocation;
 import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
 import 'package:kernel/binary/ast_to_binary.dart';
@@ -65,7 +66,8 @@
 
     test('compile', () async {
       IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
 
       final StringBuffer buffer = new StringBuffer();
       new Printer(buffer, showMetadata: true)
@@ -83,7 +85,8 @@
         ..embedSourceText = false;
       IncrementalCompiler compiler =
           new IncrementalCompiler(optionsExcludeSources, main.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
 
       for (Source source in component.uriToSource.values) {
         expect(source.source.length, equals(0));
@@ -319,7 +322,8 @@
 
     compileAndSerialize(
         File mainDill, File libDill, IncrementalCompiler compiler) async {
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
       new BinaryPrinter(new DevNullSink<List<int>>())
           .writeComponentFile(component);
       IOSink sink = mainDill.openWrite();
@@ -621,7 +625,8 @@
       // collector helper in this file.
       File libDill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
       IncrementalCompiler compiler = new IncrementalCompiler(options, lib1.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
       expect(component.libraries.length, equals(1));
       expect(component.libraries.single.fileUri, equals(lib1.uri));
       IOSink sink = libDill.openWrite();
@@ -649,7 +654,8 @@
       // Then compile lib, run and verify coverage (un-named constructor
       // covered, and the named constructor coveraged too).
       File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
-      component = await compiler.compile(entryPoint: main.uri);
+      compilerResult = await compiler.compile(entryPoint: main.uri);
+      component = compilerResult.component;
       expect(component.libraries.length, equals(1));
       expect(component.libraries.single.fileUri, equals(main.uri));
       sink = mainDill.openWrite();
@@ -706,7 +712,8 @@
       int newLineForUnnamedConstructor = 8;
       int newLineForNamedConstructor = 9;
       compiler.invalidate(lib1.uri);
-      component = await compiler.compile(entryPoint: lib1.uri);
+      compilerResult = await compiler.compile(entryPoint: lib1.uri);
+      component = compilerResult.component;
       expect(component.libraries.length, equals(1));
       expect(component.libraries.single.fileUri, equals(lib1.uri));
       sink = libDill.openWrite();
@@ -794,7 +801,8 @@
 
     compileAndSerialize(File mainDill, File lib1Dill, File lib2Dill,
         IncrementalCompiler compiler) async {
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
       new BinaryPrinter(new DevNullSink<List<int>>())
           .writeComponentFile(component);
       IOSink sink = mainDill.openWrite();
@@ -901,7 +909,8 @@
           "openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");
 
       IncrementalCompiler compiler = new IncrementalCompiler(options, file.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
 
       File outputFile = new File('${mytest.path}/foo.dart.dill');
       await _writeProgramToFile(component, outputFile);
@@ -948,7 +957,8 @@
       compiler.accept();
 
       // Confirm that without changes VM reloads nothing.
-      component = await compiler.compile();
+      compilerResult = await compiler.compile();
+      component = compilerResult.component;
       await _writeProgramToFile(component, outputFile);
       var reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isTrue);
@@ -957,7 +967,8 @@
       // Introduce a change that force VM to reject the change.
       fileBar.writeAsStringSync("class A<T,U> { int _a = 0; }\n");
       compiler.invalidate(fileBar.uri);
-      component = await compiler.compile();
+      compilerResult = await compiler.compile();
+      component = compilerResult.component;
       await _writeProgramToFile(component, outputFile);
       reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isFalse);
@@ -965,7 +976,8 @@
       // Fix a change so VM is happy to accept the change.
       fileBar.writeAsStringSync("class A<T> { int _a = 0; hi() => _a; }\n");
       compiler.invalidate(fileBar.uri);
-      component = await compiler.compile();
+      compilerResult = await compiler.compile();
+      component = compilerResult.component;
       await _writeProgramToFile(component, outputFile);
       reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isTrue);
@@ -1018,7 +1030,9 @@
       IncrementalCompiler compiler =
           new IncrementalCompiler(optionsModified, packageEntry);
       {
-        Component component = await compiler.compile(entryPoint: packageEntry);
+        IncrementalCompilerResult compilerResult =
+            await compiler.compile(entryPoint: packageEntry);
+        Component component = compilerResult.component;
         File outputFile = new File('${mytest.path}/foo.dart.dill');
         await _writeProgramToFile(component, outputFile);
       }
@@ -1033,7 +1047,9 @@
           .writeAsStringSync("class A { static int b; }\n");
       compiler.invalidate(barUri);
       {
-        Component component = await compiler.compile(entryPoint: packageEntry);
+        IncrementalCompilerResult compilerResult =
+            await compiler.compile(entryPoint: packageEntry);
+        Component component = compilerResult.component;
         File outputFile = new File('${mytest.path}/foo1.dart.dill');
         await _writeProgramToFile(component, outputFile);
       }
@@ -1076,7 +1092,9 @@
       Library fooLib;
       Library barLib;
       {
-        final Component component = await compiler.compile(entryPoint: fooUri);
+        final IncrementalCompilerResult compilerResult =
+            await compiler.compile(entryPoint: fooUri);
+        final Component component = compilerResult.component;
         expect(component.libraries.length, equals(2));
         fooLib = component.libraries.firstWhere((lib) => lib.fileUri == fooUri);
         barLib = component.libraries.firstWhere((lib) => lib.fileUri == barUri);
@@ -1104,7 +1122,9 @@
         """);
       compiler.invalidate(barUri);
       {
-        final Component component = await compiler.compile(entryPoint: fooUri);
+        final IncrementalCompilerResult compilerResult =
+            await compiler.compile(entryPoint: fooUri);
+        final Component component = compilerResult.component;
         final Library? fooLib2 = component.libraries
             .firstWhereOrNull((lib) => lib.fileUri == fooUri);
         expect(fooLib2, isNull);
@@ -1125,10 +1145,10 @@
         expect(lrc.librariesReferenced, equals(<Library>{barLib}));
       }
       {
-        // Verify that the saved "last known good" compnent only contains links
+        // Verify that the saved "last known good" component only contains links
         // to the original 'foo' and 'bar' libraries.
         final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
-        compiler.lastKnownGoodComponent!.accept(lrc);
+        compiler.lastKnownGoodResult!.component.accept(lrc);
         expect(lrc.librariesReferenced, equals(<Library>{fooLib, barLib}));
       }
       {
@@ -1272,7 +1292,8 @@
       """);
       IncrementalCompiler compiler =
           new IncrementalCompiler(options, mainFile.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
       File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
       IOSink sink = mainDill.openWrite();
       new BinaryPrinter(sink).writeComponentFile(component);
@@ -1345,7 +1366,8 @@
       """);
       IncrementalCompiler compiler =
           new IncrementalCompiler(options, mainFile.uri);
-      Component component = await compiler.compile();
+      IncrementalCompilerResult compilerResult = await compiler.compile();
+      Component component = compilerResult.component;
       File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
       IOSink sink = mainDill.openWrite();
       new BinaryPrinter(sink).writeComponentFile(component);
@@ -1367,7 +1389,8 @@
         }
       """);
       compiler.invalidate(helperFile.uri);
-      component = await compiler.compile();
+      compilerResult = await compiler.compile();
+      component = compilerResult.component;
       File partial1Dill =
           new File.fromUri(mainFile.uri.resolve("partial1.dill"));
       sink = partial1Dill.openWrite();
@@ -1393,7 +1416,8 @@
         }
       """);
       compiler.invalidate(helperFile.uri);
-      component = await compiler.compile();
+      compilerResult = await compiler.compile();
+      component = compilerResult.component;
       File partial2Dill =
           new File.fromUri(mainFile.uri.resolve("partial2.dill"));
       sink = partial2Dill.openWrite();
@@ -1519,7 +1543,8 @@
         IncrementalCompiler compiler =
             new IncrementalCompiler(optionsModified, mainUri);
 
-        Component component = await compiler.compile();
+        IncrementalCompilerResult compilerResult = await compiler.compile();
+        Component component = compilerResult.component;
         File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
         IOSink sink = mainDill.openWrite();
         new BinaryPrinter(sink).writeComponentFile(component);
diff --git a/tools/VERSION b/tools/VERSION
index 076f009..717f643 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 50
+PRERELEASE 51
 PRERELEASE_PATCH 0
\ No newline at end of file