Migrate parts of  package:frontend_server to null safety.

This is a re-land of https://dart-review.googlesource.com/c/sdk/+/247601 with some additional changes to allow for certain null uris in some previously migrated package:front_end code.

Note that nulls were flowing through these apis already, this just acknowledges that fact :).

Bug: https://github.com/dart-lang/sdk/issues/49212
Change-Id: I4528bfdec1bc9114715afd3fea06d1249054d2a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247765
Commit-Queue: Jake Macdonald <jakemac@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 217bb40..f30a919 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -60,9 +60,9 @@
 Future<InitializedCompilerState> initializeIncrementalCompiler(
     InitializedCompilerState? oldState,
     Set<String> tags,
-    Uri sdkSummary,
-    Uri packagesFile,
-    Uri librariesSpecificationUri,
+    Uri? sdkSummary,
+    Uri? packagesFile,
+    Uri? librariesSpecificationUri,
     List<Uri> additionalDills,
     Map<Uri, List<int>> workerInputDigests,
     Target target,
@@ -100,9 +100,9 @@
 
 InitializedCompilerState initializeCompiler(
   InitializedCompilerState? oldState,
-  Uri sdkSummary,
-  Uri librariesSpecificationUri,
-  Uri packagesFile,
+  Uri? sdkSummary,
+  Uri? librariesSpecificationUri,
+  Uri? packagesFile,
   List<Uri> additionalDills,
   Target target,
   FileSystem fileSystem,
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
index 346a4ae..88b68de 100644
--- a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -40,9 +40,9 @@
     InitializedCompilerState? oldState,
     Set<String> tags,
     List<Component> outputLoadedAdditionalDills,
-    Uri sdkSummary,
-    Uri packagesFile,
-    Uri librariesSpecificationUri,
+    Uri? sdkSummary,
+    Uri? packagesFile,
+    Uri? librariesSpecificationUri,
     List<Uri> additionalDills,
     Map<Uri, List<int>> workerInputDigests,
     Target target,
@@ -59,8 +59,9 @@
   bool isRetry = false;
   while (true) {
     try {
-      final List<int>? sdkDigest = workerInputDigests[sdkSummary];
-      if (sdkDigest == null) {
+      final List<int>? sdkDigest =
+          sdkSummary == null ? null : workerInputDigests[sdkSummary];
+      if (sdkDigest == null && sdkSummary != null) {
         throw new StateError("Expected to get digest for $sdkSummary");
       }
 
@@ -69,7 +70,8 @@
       Map<Uri, Uri> workerInputCacheLibs =
           oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
 
-      WorkerInputComponent? cachedSdkInput = workerInputCache[sdkSummary];
+      WorkerInputComponent? cachedSdkInput =
+          sdkSummary == null ? null : workerInputCache[sdkSummary];
 
       IncrementalCompiler incrementalCompiler;
       CompilerOptions options;
@@ -84,8 +86,9 @@
               explicitExperimentalFlags) ||
           !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
           !equalSets(oldState.tags, tags) ||
-          cachedSdkInput == null ||
-          !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
+          (sdkSummary != null &&
+              (cachedSdkInput == null ||
+                  !digestsEqual(cachedSdkInput.digest, sdkDigest)))) {
         // No - or immediately not correct - previous state.
         // We'll load a new sdk, anything loaded already will have a wrong root.
         workerInputCache.clear();
@@ -107,28 +110,30 @@
           ..nnbdMode = nnbdMode;
 
         processedOpts = new ProcessedOptions(options: options);
-        cachedSdkInput = new WorkerInputComponent(
-            sdkDigest, (await processedOpts.loadSdkSummary(null))!);
-        workerInputCache[sdkSummary] = cachedSdkInput;
-        for (Library lib in cachedSdkInput.component.libraries) {
-          if (workerInputCacheLibs.containsKey(lib.importUri)) {
-            throw new StateError("Duplicate sources in sdk.");
+        if (sdkSummary != null && sdkDigest != null) {
+          cachedSdkInput = new WorkerInputComponent(
+              sdkDigest, (await processedOpts.loadSdkSummary(null))!);
+          workerInputCache[sdkSummary] = cachedSdkInput;
+          for (Library lib in cachedSdkInput.component.libraries) {
+            if (workerInputCacheLibs.containsKey(lib.importUri)) {
+              throw new StateError("Duplicate sources in sdk.");
+            }
+            workerInputCacheLibs[lib.importUri] = sdkSummary;
           }
-          workerInputCacheLibs[lib.importUri] = sdkSummary;
         }
 
         incrementalCompiler = new IncrementalCompiler.fromComponent(
             new CompilerContext(processedOpts),
-            cachedSdkInput.component,
+            cachedSdkInput?.component,
             outlineOnly);
       } else {
         options = oldState.options;
         processedOpts = oldState.processedOpts;
-        Component sdkComponent = cachedSdkInput.component;
+        Component? sdkComponent = cachedSdkInput?.component;
 
         // Make sure the canonical name root knows about the sdk - otherwise we
         // won't be able to link to it when loading more outlines.
-        sdkComponent.adoptChildren();
+        sdkComponent?.adoptChildren();
 
         // TODO(jensj): This is - at least currently - necessary,
         // although it's not entirely obvious why.
@@ -149,7 +154,7 @@
       }
 
       // Then read all the input summary components.
-      CanonicalName nameRoot = cachedSdkInput.component.root;
+      CanonicalName? nameRoot = cachedSdkInput?.component.root;
       Map<Uri, Uri>? libraryToInputDill;
       if (trackNeededDillLibraries) {
         libraryToInputDill = new Map<Uri, Uri>();
diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
index 2c70e9d..918c891 100644
--- a/pkg/frontend_server/lib/compute_kernel.dart
+++ b/pkg/frontend_server/lib/compute_kernel.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.8
-
 /// A library to invoke the CFE to compute kernel summary files.
 ///
 /// Used by `utils/bazel/kernel_worker.dart`.
@@ -119,7 +117,7 @@
 
 class ComputeKernelResult {
   final bool succeeded;
-  final fe.InitializedCompilerState previousState;
+  final fe.InitializedCompilerState? previousState;
 
   ComputeKernelResult(this.succeeded, this.previousState);
 }
@@ -134,9 +132,9 @@
 /// Returns whether or not the summary was successfully output.
 Future<ComputeKernelResult> computeKernel(List<String> args,
     {bool isWorker: false,
-    StringBuffer outputBuffer,
-    Map<Uri, List<int>> inputDigests,
-    fe.InitializedCompilerState previousState}) async {
+    StringBuffer? outputBuffer,
+    Map<Uri, List<int>>? inputDigests,
+    fe.InitializedCompilerState? previousState}) async {
   inputDigests ??= <Uri, List<int>>{};
   dynamic out = outputBuffer ?? stderr;
   bool succeeded = true;
@@ -172,7 +170,7 @@
   // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
   // compatible while we migrate existing clients of this tool.
   var targetName =
-      (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
+      (parsedArgs['target'] as String?) ?? (summaryOnly ? 'ddc' : 'vm');
   var targetFlags = new TargetFlags(
       trackWidgetCreation: trackWidgetCreation,
       enableNullSafety: nnbdMode == fe.NnbdMode.Strong);
@@ -225,6 +223,7 @@
       break;
     default:
       out.writeln('error: unsupported target: $targetName');
+      return ComputeKernelResult(false, previousState);
   }
 
   List<Uri> linkedInputs =
@@ -239,6 +238,7 @@
   var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
   var verbose = parsedArgs['verbose'] as bool;
   var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
+  Uri? sdkSummaryUri = toUriNullable(parsedArgs['dart-sdk-summary']);
 
   if (parsedArgs['use-incremental-compiler']) {
     usingIncrementalCompiler = true;
@@ -248,7 +248,9 @@
     // fake input digests).
     if (!isWorker && inputDigests.isEmpty) {
       previousState = null;
-      inputDigests[toUri(parsedArgs['dart-sdk-summary'])] = const [0];
+      if (sdkSummaryUri != null) {
+        inputDigests[sdkSummaryUri] = const [0];
+      }
       for (Uri uri in summaryInputs) {
         inputDigests[uri] = const [0];
       }
@@ -265,9 +267,9 @@
           "multiRootScheme=${fileSystem.markerScheme}",
           "multiRootRoots=${fileSystem.roots}",
         },
-        toUri(parsedArgs['dart-sdk-summary']),
-        toUri(parsedArgs['packages-file']),
-        toUri(parsedArgs['libraries-file']),
+        sdkSummaryUri,
+        toUriNullable(parsedArgs['packages-file']),
+        toUriNullable(parsedArgs['libraries-file']),
         [...summaryInputs, ...linkedInputs],
         inputDigests,
         target,
@@ -282,9 +284,9 @@
     state = fe.initializeCompiler(
         // TODO(sigmund): pass an old state once we can make use of it.
         null,
-        toUri(parsedArgs['dart-sdk-summary']),
-        toUri(parsedArgs['libraries-file']),
-        toUri(parsedArgs['packages-file']),
+        sdkSummaryUri,
+        toUriNullable(parsedArgs['libraries-file']),
+        toUriNullable(parsedArgs['packages-file']),
         [...summaryInputs, ...linkedInputs],
         target,
         fileSystem,
@@ -360,12 +362,12 @@
     }
   }
 
-  List<int> kernel;
+  List<int>? kernel;
   bool wroteUsedDills = false;
   if (usingIncrementalCompiler) {
     state.options.onDiagnostic = onDiagnostic;
     IncrementalCompilerResult incrementalCompilerResult =
-        await state.incrementalCompiler.computeDelta(
+        await state.incrementalCompiler!.computeDelta(
             entryPoints: sources,
             fullComponent: true,
             trackNeededDillLibraries: recordUsedInputs);
@@ -373,9 +375,9 @@
 
     if (recordUsedInputs) {
       Set<Uri> usedOutlines = {};
-      for (Library lib in incrementalCompilerResult.neededDillLibraries) {
+      for (Library lib in incrementalCompilerResult.neededDillLibraries!) {
         if (lib.importUri.isScheme("dart")) continue;
-        Uri uri = state.libraryToInputDill[lib.importUri];
+        Uri? uri = state.libraryToInputDill![lib.importUri];
         if (uri == null) {
           throw new StateError("Library ${lib.importUri} was recorded as used, "
               "but was not in the list of known libraries.");
@@ -388,7 +390,7 @@
       wroteUsedDills = true;
     }
 
-    kernel = await state.incrementalCompiler.context.runInContext((_) {
+    kernel = await state.incrementalCompiler!.context.runInContext((_) {
       if (summaryOnly) {
         incrementalComponent.uriToSource.clear();
         incrementalComponent.problemsAsJson = null;
@@ -412,13 +414,15 @@
     kernel = await fe.compileSummary(state, sources, onDiagnostic,
         includeOffsets: false);
   } else {
-    Component component = await fe
+    Component? component = await fe
         .compileComponent(state, sources, onDiagnostic, buildSummary: summary);
-    kernel = fe.serializeComponent(component,
-        filter: excludeNonSources
-            ? (library) => sources.contains(library.importUri)
-            : null,
-        includeOffsets: true);
+    if (component != null) {
+      kernel = fe.serializeComponent(component,
+          filter: excludeNonSources
+              ? (library) => sources.contains(library.importUri)
+              : null,
+          includeOffsets: true);
+    }
   }
   state.options.onDiagnostic = null; // See http://dartbug.com/36983.
 
@@ -467,8 +471,12 @@
       : super(targetFlags);
 }
 
-Uri toUri(String uriString) {
+Uri? toUriNullable(String? uriString) {
   if (uriString == null) return null;
+  return toUri(uriString);
+}
+
+Uri toUri(String uriString) {
   // Windows-style paths use '\', so convert them to '/' in case they've been
   // concatenated with Unix-style paths.
   return Uri.base.resolve(uriString.replaceAll("\\", "/"));
diff --git a/pkg/frontend_server/lib/src/strong_components.dart b/pkg/frontend_server/lib/src/strong_components.dart
index 0711f2d..a436b7c 100644
--- a/pkg/frontend_server/lib/src/strong_components.dart
+++ b/pkg/frontend_server/lib/src/strong_components.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.9
 import 'package:kernel/ast.dart';
 import 'package:kernel/util/graph.dart';
 
@@ -45,7 +44,7 @@
   final Uri mainUri;
 
   /// The filesystem instance for resolving files.
-  final FileSystem fileSystem;
+  final FileSystem? fileSystem;
 
   /// The set of libraries for each module URI.
   ///
@@ -68,10 +67,13 @@
     }
     // If we don't have a file uri, just use the first library in the
     // component.
-    Library entrypoint = component.libraries.firstWhere(
-        (Library library) =>
-            library.fileUri == mainUri || library.importUri == mainUri,
-        orElse: () => null);
+    Library? entrypoint;
+    for (Library library in component.libraries) {
+      if (library.fileUri == mainUri || library.importUri == mainUri) {
+        entrypoint = library;
+        break;
+      }
+    }
 
     if (entrypoint == null) {
       throw Exception('Could not find entrypoint ${mainUri} in Component.');
diff --git a/pkg/frontend_server/test/src/strong_components_test.dart b/pkg/frontend_server/test/src/strong_components_test.dart
index 2281e82..9bb6596 100644
--- a/pkg/frontend_server/test/src/strong_components_test.dart
+++ b/pkg/frontend_server/test/src/strong_components_test.dart
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.9
 import 'package:frontend_server/src/strong_components.dart';
 import 'package:kernel/ast.dart';
 import 'package:test/test.dart';