[frontend_server] Migrate most of the rest of frontend_server to null safety

Bug:https://github.com/dart-lang/sdk/issues/49212

Based on https://dart-review.googlesource.com/c/sdk/+/253301

Change-Id: I248846c30f1ce30de415c8a0722b680add83b9a6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258922
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
diff --git a/pkg/frontend_server/lib/frontend_server.dart b/pkg/frontend_server/lib/frontend_server.dart
index 17464ec..47c365f 100644
--- a/pkg/frontend_server/lib/frontend_server.dart
+++ b/pkg/frontend_server/lib/frontend_server.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
 library frontend_server;
 
 import 'dart:async';
@@ -24,6 +23,8 @@
 // an effort to discourage further use.
 // ignore_for_file: implementation_imports
 import 'package:front_end/src/api_unstable/vm.dart';
+import 'package:front_end/src/api_unstable/ddc.dart' as ddc
+    show IncrementalCompiler;
 import 'package:front_end/widget_cache.dart';
 import 'package:kernel/ast.dart' show Library, Procedure, LibraryDependency;
 import 'package:kernel/binary/ast_to_binary.dart';
@@ -270,12 +271,12 @@
   Future<bool> compile(
     String entryPoint,
     ArgResults options, {
-    IncrementalCompiler generator,
+    IncrementalCompiler? generator,
   });
 
   /// Assuming some Dart program was previously compiled, recompile it again
   /// taking into account some changed(invalidated) sources.
-  Future<Null> recompileDelta({String entryPoint});
+  Future<Null> recompileDelta({String? entryPoint});
 
   /// Accept results of previous compilation so that next recompilation cycle
   /// won't recompile sources that were previously reported as changed.
@@ -309,8 +310,8 @@
       List<String> typeBounds,
       List<String> typeDefaults,
       String libraryUri,
-      String klass,
-      String method,
+      String? klass,
+      String? method,
       bool isStatic);
 
   /// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
@@ -357,50 +358,51 @@
 }
 
 class FrontendCompiler implements CompilerInterface {
-  FrontendCompiler(this._outputStream,
-      {this.printerFactory,
+  FrontendCompiler(StringSink? outputStream,
+      {BinaryPrinterFactory? printerFactory,
       this.transformer,
       this.unsafePackageSerialization,
       this.incrementalSerialization = true,
       this.useDebuggerModuleNames = false,
       this.emitDebugMetadata = false,
-      this.emitDebugSymbols = false}) {
-    _outputStream ??= stdout;
-    printerFactory ??= new BinaryPrinterFactory();
-  }
+      this.emitDebugSymbols = false})
+      : _outputStream = outputStream ?? stdout,
+        printerFactory = printerFactory ?? new BinaryPrinterFactory();
 
-  StringSink _outputStream;
-  BinaryPrinterFactory printerFactory;
-  bool unsafePackageSerialization;
-  bool incrementalSerialization;
-  bool useDebuggerModuleNames;
-  bool emitDebugMetadata;
-  bool emitDebugSymbols;
-  bool _printIncrementalDependencies;
-
-  CompilerOptions _compilerOptions;
-  ProcessedOptions _processedOptions;
-  FileSystem _fileSystem;
-  Uri _mainSource;
-  List<Uri> _additionalSources;
-  ArgResults _options;
-
-  IncrementalCompiler _generator;
-  IncrementalJavaScriptBundler _bundler;
-
-  WidgetCache _widgetCache;
-
-  String _kernelBinaryFilename;
-  String _kernelBinaryFilenameIncremental;
-  String _kernelBinaryFilenameFull;
-  String _initializeFromDill;
-  bool _assumeInitializeFromDillUpToDate;
-
+  /// Fields with initializers
+  final List<String> errors = <String>[];
   Set<Uri> previouslyReportedDependencies = Set<Uri>();
 
-  final ProgramTransformer transformer;
+  /// Initialized in the constructor
+  bool emitDebugMetadata;
+  bool emitDebugSymbols;
+  bool incrementalSerialization;
+  StringSink _outputStream;
+  BinaryPrinterFactory printerFactory;
+  bool useDebuggerModuleNames;
 
-  final List<String> errors = <String>[];
+  /// Initialized in [compile].
+  late List<Uri> _additionalSources;
+  late bool _assumeInitializeFromDillUpToDate;
+  late CompilerOptions _compilerOptions;
+  late FileSystem _fileSystem;
+  late IncrementalCompiler _generator;
+  late String _initializeFromDill;
+  late String _kernelBinaryFilename;
+  late String _kernelBinaryFilenameIncremental;
+  late String _kernelBinaryFilenameFull;
+  late Uri _mainSource;
+  late ArgResults _options;
+  late bool _printIncrementalDependencies;
+  late ProcessedOptions _processedOptions;
+
+  /// Initialized in [writeJavascriptBundle]
+  IncrementalJavaScriptBundler? _bundler;
+
+  /// Nullable fields
+  final ProgramTransformer? transformer;
+  bool? unsafePackageSerialization;
+  WidgetCache? _widgetCache;
 
   _onDiagnostic(DiagnosticMessage message) {
     switch (message.severity) {
@@ -428,7 +430,7 @@
   Future<bool> compile(
     String entryPoint,
     ArgResults options, {
-    IncrementalCompiler generator,
+    IncrementalCompiler? generator,
   }) async {
     _options = options;
     _fileSystem = createFrontEndFileSystem(
@@ -453,8 +455,8 @@
     final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
     final String platformKernelDill =
         options['platform'] ?? 'platform_strong.dill';
-    final String packagesOption = _options['packages'];
-    final bool nullSafety = _options['sound-null-safety'];
+    final String? packagesOption = _options['packages'];
+    final bool? nullSafety = _options['sound-null-safety'];
     final CompilerOptions compilerOptions = CompilerOptions()
       ..sdkRoot = sdkRoot
       ..fileSystem = _fileSystem
@@ -550,7 +552,7 @@
       return false;
     }
 
-    final String importDill = options['import-dill'];
+    final String? importDill = options['import-dill'];
     if (importDill != null) {
       compilerOptions.additionalDills = <Uri>[
         Uri.base.resolveUri(Uri.file(importDill))
@@ -559,11 +561,11 @@
 
     _processedOptions = ProcessedOptions(options: compilerOptions);
 
-    KernelCompilationResults results;
-    IncrementalSerializer incrementalSerializer;
+    KernelCompilationResults? results;
+    IncrementalSerializer? incrementalSerializer;
     if (options['incremental']) {
       _compilerOptions.environmentDefines =
-          _compilerOptions.target.updateEnvironmentDefines(environmentDefines);
+          _compilerOptions.target!.updateEnvironmentDefines(environmentDefines);
 
       _compilerOptions.omitPlatform = false;
       _generator = generator ?? _createGenerator(Uri.file(_initializeFromDill));
@@ -605,10 +607,10 @@
           treeShakeWriteOnlyFields: options['tree-shake-write-only-fields'],
           fromDillFile: options['from-dill']));
     }
-    if (results.component != null) {
-      transformer?.transform(results.component);
+    if (results!.component != null) {
+      transformer?.transform(results.component!);
 
-      if (_compilerOptions.target.name == 'dartdevc') {
+      if (_compilerOptions.target!.name == 'dartdevc') {
         await writeJavascriptBundle(results, _kernelBinaryFilename,
             options['filesystem-scheme'], options['dartdevc-module-format'],
             fullComponent: true);
@@ -618,12 +620,13 @@
           incrementalSerializer: incrementalSerializer);
 
       _outputStream.writeln(boundaryKey);
-      await _outputDependenciesDelta(results.compiledSources);
+      final compiledSources = results.compiledSources!;
+      await _outputDependenciesDelta(compiledSources);
       _outputStream
           .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
-      final String depfile = options['depfile'];
+      final String? depfile = options['depfile'];
       if (depfile != null) {
-        await writeDepfile(compilerOptions.fileSystem, results.compiledSources,
+        await writeDepfile(compilerOptions.fileSystem, compiledSources,
             _kernelBinaryFilename, depfile);
       }
 
@@ -639,10 +642,10 @@
     if (!_printIncrementalDependencies) {
       return;
     }
-    Set<Uri> uris = Set<Uri>();
+    Set<Uri> uris = {};
     for (Uri uri in compiledSources) {
       // Skip empty or corelib dependencies.
-      if (uri == null || uri.isScheme('org-dartlang-sdk')) continue;
+      if (uri.isScheme('org-dartlang-sdk')) continue;
       uris.add(uri);
     }
     for (Uri uri in uris) {
@@ -671,15 +674,16 @@
   /// Write a JavaScript bundle containing the provided component.
   Future<void> writeJavascriptBundle(KernelCompilationResults results,
       String filename, String fileSystemScheme, String moduleFormat,
-      {bool fullComponent}) async {
+      {required bool fullComponent}) async {
+    // ignore: unnecessary_null_comparison
     assert(fullComponent != null);
     var packageConfig = await loadPackageConfigUri(
         _compilerOptions.packagesFileUri ??
             File('.dart_tool/package_config.json').absolute.uri);
     var soundNullSafety = _compilerOptions.nnbdMode == NnbdMode.Strong;
-    final Component component = results.component;
+    final Component component = results.component!;
 
-    _bundler ??= IncrementalJavaScriptBundler(
+    final bundler = _bundler ??= IncrementalJavaScriptBundler(
       _compilerOptions.fileSystem,
       results.loadedLibraries,
       fileSystemScheme,
@@ -689,11 +693,11 @@
       soundNullSafety: soundNullSafety,
     );
     if (fullComponent) {
-      await _bundler.initialize(component, _mainSource, packageConfig);
+      await bundler.initialize(component, _mainSource, packageConfig);
     } else {
-      await _bundler.invalidate(
+      await bundler.invalidate(
           component,
-          _generator.lastKnownGoodResult?.component,
+          _generator.lastKnownGoodResult!.component,
           _mainSource,
           packageConfig);
     }
@@ -714,9 +718,9 @@
     final metadataFileSink =
         emitDebugMetadata ? metadataFile.openWrite() : null;
     final symbolsFileSink = emitDebugSymbols ? symbolsFile.openWrite() : null;
-    final kernel2JsCompilers = await _bundler.compile(
-        results.classHierarchy,
-        results.coreTypes,
+    final kernel2JsCompilers = await bundler.compile(
+        results.classHierarchy!,
+        results.coreTypes!,
         packageConfig,
         sourceFileSink,
         manifestFileSink,
@@ -735,8 +739,8 @@
 
   writeDillFile(KernelCompilationResults results, String filename,
       {bool filterExternal = false,
-      IncrementalSerializer incrementalSerializer}) async {
-    final Component component = results.component;
+      IncrementalSerializer? incrementalSerializer}) async {
+    final Component component = results.component!;
     final IOSink sink = File(filename).openWrite();
     final Set<Library> loadedLibraries = results.loadedLibraries;
     final BinaryPrinter printer = filterExternal
@@ -762,10 +766,10 @@
           _mainSource, _compilerOptions, results, filename);
     }
 
-    final String manifestFilename = _options['far-manifest'];
+    final String? manifestFilename = _options['far-manifest'];
     if (manifestFilename != null) {
       final String output = _options['output-dill'];
-      final String dataDir = _options.options.contains('component-name')
+      final String? dataDir = _options.options.contains('component-name')
           ? _options['component-name']
           : _options['data-dir'];
       await createFarManifest(output, dataDir, manifestFilename);
@@ -794,9 +798,9 @@
 
     nextUri:
     for (Uri uri in component.uriToSource.keys) {
-      if (uri == null || '$uri' == '') continue nextUri;
+      if ('$uri' == '') continue nextUri;
 
-      final List<int> oldBytes = component.uriToSource[uri].source;
+      final List<int> oldBytes = component.uriToSource[uri]!.source;
       FileSystemEntity entity;
       try {
         entity = _compilerOptions.fileSystem.entityForUri(uri);
@@ -831,7 +835,7 @@
   }
 
   @override
-  Future<Null> recompileDelta({String entryPoint}) async {
+  Future<Null> recompileDelta({String? entryPoint}) async {
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
     await invalidateIfInitializingFromDill();
@@ -843,9 +847,7 @@
     IncrementalCompilerResult deltaProgramResult = await _generator
         .compile(entryPoints: [_mainSource, ..._additionalSources]);
     Component deltaProgram = deltaProgramResult.component;
-    if (deltaProgram != null && transformer != null) {
-      transformer.transform(deltaProgram);
-    }
+    transformer?.transform(deltaProgram);
 
     KernelCompilationResults results = KernelCompilationResults(
         deltaProgram,
@@ -854,7 +856,7 @@
         deltaProgramResult.coreTypes,
         deltaProgram.uriToSource.keys);
 
-    if (_compilerOptions.target.name == 'dartdevc') {
+    if (_compilerOptions.target!.name == 'dartdevc') {
       await writeJavascriptBundle(results, _kernelBinaryFilename,
           _options['filesystem-scheme'], _options['dartdevc-module-format'],
           fullComponent: false);
@@ -865,7 +867,7 @@
     _updateWidgetCache(deltaProgram);
 
     _outputStream.writeln(boundaryKey);
-    await _outputDependenciesDelta(results.compiledSources);
+    await _outputDependenciesDelta(results.compiledSources!);
     _outputStream
         .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
     _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
@@ -880,12 +882,12 @@
       List<String> typeBounds,
       List<String> typeDefaults,
       String libraryUri,
-      String klass,
-      String method,
+      String? klass,
+      String? method,
       bool isStatic) async {
     final String boundaryKey = Uuid().generateV4();
     _outputStream.writeln('result $boundaryKey');
-    Procedure procedure = await _generator.compileExpression(
+    Procedure? procedure = await _generator.compileExpression(
         expression,
         definitions,
         definitionTypes,
@@ -942,8 +944,8 @@
     _processedOptions.ticker
         .logMs('Compiling expression to JavaScript in $moduleName');
 
-    final kernel2jsCompiler = cachedProgramCompilers[moduleName];
-    IncrementalCompilerResult compilerResult = _generator.lastKnownGoodResult;
+    final kernel2jsCompiler = cachedProgramCompilers[moduleName]!;
+    IncrementalCompilerResult compilerResult = _generator.lastKnownGoodResult!;
     Component component = compilerResult.component;
     component.computeCanonicalNames();
 
@@ -953,7 +955,7 @@
       _compilerOptions,
       parseModuleFormat(_options['dartdevc-module-format'] as String),
       errors,
-      _generator.generator,
+      _generator.generator as ddc.IncrementalCompiler,
       kernel2jsCompiler,
       component,
     );
@@ -961,7 +963,7 @@
     final procedure = await expressionCompiler.compileExpressionToJs(
         libraryUri, line, column, jsFrameValues, expression);
 
-    final result = errors.isNotEmpty ? errors[0] : procedure;
+    final result = errors.isNotEmpty ? errors[0] : procedure!;
 
     // TODO(annagrin): kernelBinaryFilename is too specific
     // rename to _outputFileName?
@@ -1003,8 +1005,6 @@
 
   writePackagesToSinkAndTrimComponent(
       Component deltaProgram, Sink<List<int>> ioSink) {
-    if (deltaProgram == null) return;
-
     List<Library> packageLibraries = <Library>[];
     List<Library> libraries = <Library>[];
     deltaProgram.computeCanonicalNames();
@@ -1028,25 +1028,24 @@
       if (alreadyAdded.add(data)) {
         ioSink.add(data);
         // Now also add all dependencies.
-        for (Uri dep in cachedPackageDependencies[uri]) {
-          addDataAndDependentData(cachedPackageLibraries[dep], dep);
+        for (Uri dep in cachedPackageDependencies[uri]!) {
+          addDataAndDependentData(cachedPackageLibraries[dep]!, dep);
         }
       }
     }
 
     for (Library lib in packageLibraries) {
-      List<int> data = cachedPackageLibraries[lib.fileUri];
+      List<int>? data = cachedPackageLibraries[lib.fileUri];
       if (data != null) {
         addDataAndDependentData(data, lib.fileUri);
       } else {
         String package = lib.importUri.pathSegments.first;
-        newPackages[package] ??= <Library>[];
-        newPackages[package].add(lib);
+        (newPackages[package] ??= <Library>[]).add(lib);
       }
     }
 
     for (String package in newPackages.keys) {
-      List<Library> libraries = newPackages[package];
+      List<Library> libraries = newPackages[package]!;
       Component singleLibrary = Component(
           libraries: libraries,
           uriToSource: deltaProgram.uriToSource,
@@ -1109,7 +1108,7 @@
     _kernelBinaryFilename = _kernelBinaryFilenameFull;
   }
 
-  IncrementalCompiler _createGenerator(Uri initializeFromDillUri) {
+  IncrementalCompiler _createGenerator(Uri? initializeFromDillUri) {
     return IncrementalCompiler(
         _compilerOptions, [_mainSource, ..._additionalSources],
         initializeFromDillUri: initializeFromDillUri,
@@ -1127,8 +1126,8 @@
     if (_widgetCache == null || _generator.fullComponent) {
       return;
     }
-    final String singleModifiedClassName =
-        _widgetCache.checkSingleWidgetTypeModified(
+    final String? singleModifiedClassName =
+        _widgetCache!.checkSingleWidgetTypeModified(
       _generator.lastKnownGoodResult?.component,
       partialComponent,
       _generator.lastKnownGoodResult?.classHierarchy,
@@ -1171,7 +1170,7 @@
 }
 
 class _CompileExpressionRequest {
-  String expression;
+  late String expression;
   // Note that FE will reject a compileExpression command by returning a null
   // procedure when defs or typeDefs include an illegal identifier.
   List<String> defs = <String>[];
@@ -1179,32 +1178,32 @@
   List<String> typeDefs = <String>[];
   List<String> typeBounds = <String>[];
   List<String> typeDefaults = <String>[];
-  String library;
-  String klass;
-  String method;
-  bool isStatic;
+  late String library;
+  String? klass;
+  String? method;
+  late bool isStatic;
 }
 
 class _CompileExpressionToJsRequest {
-  String libraryUri;
-  int line;
-  int column;
+  late String libraryUri;
+  late int line;
+  late int column;
   Map<String, String> jsModules = <String, String>{};
   Map<String, String> jsFrameValues = <String, String>{};
-  String moduleName;
-  String expression;
+  late String moduleName;
+  late String expression;
 }
 
 /// Listens for the compilation commands on [input] stream.
 /// This supports "interactive" recompilation mode of execution.
 StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
     Stream<List<int>> input, ArgResults options, Completer<int> completer,
-    {IncrementalCompiler generator}) {
+    {IncrementalCompiler? generator}) {
   _State state = _State.READY_FOR_INSTRUCTION;
-  _CompileExpressionRequest compileExpressionRequest;
-  _CompileExpressionToJsRequest compileExpressionToJsRequest;
-  String boundaryKey;
-  String recompileEntryPoint;
+  late _CompileExpressionRequest compileExpressionRequest;
+  late _CompileExpressionToJsRequest compileExpressionToJsRequest;
+  late String boundaryKey;
+  String? recompileEntryPoint;
   return input
       .transform(utf8.decoder)
       .transform(const LineSplitter())
diff --git a/pkg/frontend_server/lib/src/javascript_bundle.dart b/pkg/frontend_server/lib/src/javascript_bundle.dart
index e214fd8..e265560 100644
--- a/pkg/frontend_server/lib/src/javascript_bundle.dart
+++ b/pkg/frontend_server/lib/src/javascript_bundle.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 'dart:convert';
 import 'dart:io';
 
@@ -33,7 +32,7 @@
     this.emitDebugMetadata = false,
     this.emitDebugSymbols = false,
     this.soundNullSafety = false,
-    String moduleFormat,
+    String? moduleFormat,
   }) : _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd');
 
   final bool useDebuggerModuleNames;
@@ -41,7 +40,7 @@
   final bool emitDebugSymbols;
   final ModuleFormat _moduleFormat;
   final bool soundNullSafety;
-  final FileSystem _fileSystem;
+  final FileSystem? _fileSystem;
   final Set<Library> _loadedLibraries;
   final Map<Uri, Component> _uriToComponent = <Uri, Component>{};
   final _importToSummary = Map<Library, Component>.identity();
@@ -50,9 +49,9 @@
   final Map<Uri, String> _moduleImportNameForSummary = <Uri, String>{};
   final String _fileSystemScheme;
 
-  Component _lastFullComponent;
-  Component _currentComponent;
-  StrongComponents _strongComponents;
+  late Component _lastFullComponent;
+  late Component _currentComponent;
+  late StrongComponents _strongComponents;
 
   /// Initialize the incremental bundler from a full component.
   Future<void> initialize(
@@ -91,7 +90,7 @@
     });
     var invalidated = <Uri>{
       for (Library library in partialComponent.libraries)
-        _strongComponents.moduleAssignment[library.importUri],
+        _strongComponents.moduleAssignment[library.importUri]!,
     };
     _updateSummaries(invalidated, packageConfig);
   }
@@ -121,7 +120,7 @@
   /// Update the summaries [moduleKeys].
   void _updateSummaries(Iterable<Uri> moduleKeys, PackageConfig packageConfig) {
     for (Uri uri in moduleKeys) {
-      final List<Library> libraries = _strongComponents.modules[uri].toList();
+      final List<Library> libraries = _strongComponents.modules[uri]!.toList();
       final Component summaryComponent = Component(
         libraries: libraries,
         nameRoot: _lastFullComponent.root,
@@ -136,7 +135,7 @@
 
       _uriToComponent[uri] = summaryComponent;
       // module loaders loads modules by modules names, not paths
-      var moduleImport = _moduleImportNameForSummary[uri];
+      var moduleImport = _moduleImportNameForSummary[uri]!;
 
       var oldSummaries = <Component>[];
       for (Component summary in _summaryToModule.keys) {
@@ -166,8 +165,8 @@
     IOSink codeSink,
     IOSink manifestSink,
     IOSink sourceMapsSink,
-    IOSink metadataSink,
-    IOSink symbolsSink,
+    IOSink? metadataSink,
+    IOSink? symbolsSink,
   ) async {
     var codeOffset = 0;
     var sourceMapOffset = 0;
@@ -183,13 +182,13 @@
         continue;
       }
       final Uri moduleUri =
-          _strongComponents.moduleAssignment[library.importUri];
+          _strongComponents.moduleAssignment[library.importUri]!;
       if (visited.contains(moduleUri)) {
         continue;
       }
       visited.add(moduleUri);
 
-      final summaryComponent = _uriToComponent[moduleUri];
+      final summaryComponent = _uriToComponent[moduleUri]!;
 
       // module name to use in trackLibraries
       // use full path for tracking if module uri is not a package uri.
@@ -217,12 +216,12 @@
       // Save program compiler to reuse for expression evaluation.
       kernel2JsCompilers[moduleName] = compiler;
 
-      String sourceMapBase;
+      String? sourceMapBase;
       if (moduleUri.isScheme('package')) {
         // Source locations come through as absolute file uris. In order to
         // make relative paths in the source map we get the absolute uri for
         // the module and make them relative to that.
-        sourceMapBase = p.dirname((packageConfig.resolve(moduleUri)).path);
+        sourceMapBase = p.dirname((packageConfig.resolve(moduleUri))!.path);
       }
 
       final code = jsProgramToCode(
@@ -249,12 +248,12 @@
       codeSink.add(codeBytes);
       sourceMapsSink.add(sourceMapBytes);
       if (emitDebugMetadata) {
-        metadataSink.add(metadataBytes);
+        metadataSink!.add(metadataBytes!);
       }
       if (emitDebugSymbols) {
-        symbolsSink.add(symbolsBytes);
+        symbolsSink!.add(symbolsBytes!);
       }
-      final String moduleKey = _moduleImportForSummary[moduleUri];
+      final String moduleKey = _moduleImportForSummary[moduleUri]!;
       manifest[moduleKey] = {
         'code': <int>[codeOffset, codeOffset += codeBytes.length],
         'sourcemap': <int>[
@@ -264,12 +263,12 @@
         if (emitDebugMetadata)
           'metadata': <int>[
             metadataOffset,
-            metadataOffset += metadataBytes.length
+            metadataOffset += metadataBytes!.length
           ],
         if (emitDebugSymbols)
           'symbols': <int>[
             symbolsOffset,
-            symbolsOffset += symbolsBytes.length,
+            symbolsOffset += symbolsBytes!.length,
           ],
       };
     }
@@ -304,8 +303,8 @@
     // Match relative directory structure of server paths to the
     // actual directory structure, so the sourcemaps relative paths
     // can be resolved by the browser.
-    final resolvedUri = packageConfig.resolve(componentUri);
-    final package = packageConfig.packageOf(resolvedUri);
+    final resolvedUri = packageConfig.resolve(componentUri)!;
+    final package = packageConfig.packageOf(resolvedUri)!;
     final root = package.root;
     final relativeRoot = root.pathSegments
         .lastWhere((segment) => segment.isNotEmpty, orElse: null);
@@ -313,8 +312,6 @@
 
     // Relative component url (used as server path in the browser):
     // `packages/<package directory>/<path to file.dart>`
-    return relativeRoot == null
-        ? 'packages/$relativeUrl'
-        : 'packages/$relativeRoot/$relativeUrl';
+    return 'packages/$relativeRoot/$relativeUrl';
   }
 }
diff --git a/pkg/frontend_server/lib/src/resident_frontend_server.dart b/pkg/frontend_server/lib/src/resident_frontend_server.dart
index c2eb765..7488ef3 100644
--- a/pkg/frontend_server/lib/src/resident_frontend_server.dart
+++ b/pkg/frontend_server/lib/src/resident_frontend_server.dart
@@ -2,17 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.9
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io'
-    show
-        exit,
-        File,
-        InternetAddress,
-        ProcessSignal,
-        ServerSocket,
-        Socket;
+    show exit, File, InternetAddress, ProcessSignal, ServerSocket, Socket;
 import 'dart:typed_data' show Uint8List;
 
 import 'package:args/args.dart';
@@ -34,7 +27,7 @@
 
 /// Ensures the info file is removed if Ctrl-C is sent to the server.
 /// Mostly used when debugging.
-StreamSubscription<ProcessSignal> _cleanupHandler;
+StreamSubscription<ProcessSignal>? _cleanupHandler;
 
 extension on DateTime {
   /// Truncates by [amount].
@@ -74,9 +67,9 @@
 class ResidentCompiler {
   File _entryPoint;
   File _outputDill;
-  File _currentPackage;
+  File? _currentPackage;
   ArgResults _compileOptions;
-  FrontendCompiler _compiler;
+  late FrontendCompiler _compiler;
   DateTime _lastCompileStartTime = DateTime.now().floorTime();
   _ResidentState _state = _ResidentState.WAITING_FOR_FIRST_COMPILE;
   final StringBuffer _compilerOutput = StringBuffer();
@@ -115,7 +108,7 @@
     }
     return _currentPackage != null &&
         !_lastCompileStartTime
-            .isAfter(_currentPackage.statSync().modified.floorTime());
+            .isAfter(_currentPackage!.statSync().modified.floorTime());
   }
 
   /// Compiles the entry point that this ResidentCompiler is hooked to.
@@ -359,20 +352,20 @@
   /// Returns a JSON string that the resident compiler will be able to
   /// interpret.
   static String createCompileJSON(
-      {String executable,
-      String packages,
-      String outputDill,
-      bool supportMirrors,
-      bool enableAsserts,
-      bool soundNullSafety,
-      String verbosity,
-      bool aot,
-      bool tfa,
-      bool rta,
-      bool treeShakeWriteOnlyFields,
-      bool protobufTreeShakerV2,
-      List<String> define,
-      List<String> enableExperiement,
+      {required String executable,
+      String? packages,
+      required String outputDill,
+      bool? supportMirrors,
+      bool? enableAsserts,
+      bool? soundNullSafety,
+      String? verbosity,
+      bool? aot,
+      bool? tfa,
+      bool? rta,
+      bool? treeShakeWriteOnlyFields,
+      bool? protobufTreeShakerV2,
+      List<String>? define,
+      List<String>? enableExperiement,
       bool verbose = false}) {
     return jsonEncode(<String, Object>{
       "command": "compile",
@@ -403,7 +396,7 @@
 /// ResidentFrontendServer instance.
 Future<Map<String, dynamic>> sendAndReceiveResponse(
     InternetAddress address, int port, String request) async {
-  Socket client;
+  Socket? client;
   Map<String, dynamic> jsonResponse;
   try {
     client = await Socket.connect(address, port);
@@ -428,7 +421,7 @@
     ServerSocket server, File serverInfoFile) async {
   try {
     if (_cleanupHandler != null) {
-      _cleanupHandler.cancel();
+      _cleanupHandler!.cancel();
     }
   } catch (_) {
   } finally {
@@ -455,7 +448,7 @@
 /// provided [address] and [port].
 /// If the last request exceeds the amount of time specified by
 /// [inactivityTimeout], the server will bring itself down
-Future<StreamSubscription<Socket>> residentListenAndCompile(
+Future<StreamSubscription<Socket>?> residentListenAndCompile(
     InternetAddress address, int port, File serverInfoFile,
     {Duration inactivityTimeout = const Duration(minutes: 30)}) async {
   ServerSocket server;
diff --git a/pkg/frontend_server/lib/starter.dart b/pkg/frontend_server/lib/starter.dart
index e88a7dd..33c17a6 100644
--- a/pkg/frontend_server/lib/starter.dart
+++ b/pkg/frontend_server/lib/starter.dart
@@ -2,7 +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.md file.
 
-// @dart = 2.9
 import 'dart:async';
 import 'dart:io' show Directory, File, InternetAddress, stdin;
 
@@ -21,11 +20,11 @@
 /// version for testing.
 Future<int> starter(
   List<String> args, {
-  CompilerInterface compiler,
-  Stream<List<int>> input,
-  StringSink output,
-  IncrementalCompiler generator,
-  BinaryPrinterFactory binaryPrinterFactory,
+  CompilerInterface? compiler,
+  Stream<List<int>>? input,
+  StringSink? output,
+  IncrementalCompiler? generator,
+  BinaryPrinterFactory? binaryPrinterFactory,
 }) async {
   ArgResults options;
   try {
@@ -50,7 +49,7 @@
 
     final String input = options.rest[0];
     final String sdkRoot = options['sdk-root'];
-    final String platform = options['platform'];
+    final String? platform = options['platform'];
     final Directory temp =
         Directory.systemTemp.createTempSync('train_frontend_server');
     try {
diff --git a/pkg/frontend_server/test/frontend_server_flutter.dart b/pkg/frontend_server/test/frontend_server_flutter.dart
index 160b1fd..109567a 100644
--- a/pkg/frontend_server/test/frontend_server_flutter.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter.dart
@@ -2,7 +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.md file.
 
-// @dart = 2.9
 import 'dart:async' show StreamController;
 import 'dart:convert' show utf8, LineSplitter;
 import 'dart:io' show Directory, File, FileSystemEntity, IOSink, exitCode;
@@ -20,8 +19,8 @@
 import 'package:frontend_server/starter.dart';
 
 main(List<String> args) async {
-  String flutterDir;
-  String flutterPlatformDir;
+  String? flutterDir;
+  String? flutterPlatformDir;
   for (String arg in args) {
     if (arg.startsWith("--flutterDir=")) {
       flutterDir = arg.substring(13);
@@ -47,8 +46,9 @@
   return NnbdMode.Strong;
 }
 
-Future compileTests(String flutterDir, String flutterPlatformDir, Logger logger,
-    {String filter, int shards = 1, int shard = 0}) async {
+Future compileTests(
+    String? flutterDir, String? flutterPlatformDir, Logger logger,
+    {String? filter, int shards = 1, int shard = 0}) async {
   if (flutterDir == null || !(new Directory(flutterDir).existsSync())) {
     throw "Didn't get a valid flutter directory to work with.";
   }
@@ -206,7 +206,7 @@
     Directory testDir,
     Directory flutterDirectory,
     Logger logger,
-    String filter,
+    String? filter,
     List<String> allCompilationErrors) async {
   Directory tempDir = systemTempDir.createTempSync('flutter_frontend_test');
   try {
@@ -237,7 +237,7 @@
     Directory testDir,
     Directory flutterDirectory,
     Logger logger,
-    String filter) async {
+    String? filter) async {
   if (testFiles.isEmpty) return [];
 
   File dillFile = new File('${tempDir.path}/dill.dill');
@@ -355,10 +355,10 @@
   bool expectSources = true;
 
   StreamController<Result> _receivedResults;
-  List<String> _receivedSources;
+  List<String>? _receivedSources;
 
-  String _boundaryKey;
-  bool _readingSources;
+  String? _boundaryKey;
+  bool _readingSources = false;
 
   List<String> allReceived = <String>[];
 
@@ -374,7 +374,7 @@
       return;
     }
 
-    if (s.startsWith(_boundaryKey)) {
+    if (s.startsWith(_boundaryKey!)) {
       // First boundaryKey separates compiler output from list of sources
       // (if we expect list of sources, which is indicated by receivedSources
       // being not null)
@@ -385,30 +385,27 @@
       // Second boundaryKey indicates end of frontend server response
       expectSources = true;
       _receivedResults.add(new Result(
-          s.length > _boundaryKey.length
-              ? s.substring(_boundaryKey.length + 1)
+          s.length > _boundaryKey!.length
+              ? s.substring(_boundaryKey!.length + 1)
               : null,
           _receivedSources));
       _boundaryKey = null;
     } else {
       if (_readingSources) {
-        if (_receivedSources == null) {
-          _receivedSources = <String>[];
-        }
-        _receivedSources.add(s);
+        (_receivedSources ??= <String>[]).add(s);
       }
     }
   }
 }
 
 class Result {
-  String status;
-  List<String> sources;
+  String? status;
+  List<String>? sources;
 
   Result(this.status, this.sources);
 
-  void expectNoErrors({String filename}) {
-    CompilationResult result = new CompilationResult.parse(status);
+  void expectNoErrors({String? filename}) {
+    CompilationResult result = new CompilationResult.parse(status!);
     if (result.errorsCount != 0) {
       throw "Got ${result.errorsCount} errors. Expected 0.";
     }
@@ -421,10 +418,10 @@
 }
 
 class CompilationResult {
-  String filename;
-  int errorsCount;
+  late String filename;
+  late int errorsCount;
 
-  CompilationResult.parse(String filenameAndErrorCount) {
+  CompilationResult.parse(String? filenameAndErrorCount) {
     if (filenameAndErrorCount == null) {
       return;
     }
diff --git a/pkg/frontend_server/test/frontend_server_flutter_suite.dart b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
index 8473358..c574c15 100644
--- a/pkg/frontend_server/test/frontend_server_flutter_suite.dart
+++ b/pkg/frontend_server/test/frontend_server_flutter_suite.dart
@@ -2,7 +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.md file.
 
-// @dart = 2.9
 import 'dart:async' show StreamSubscription, Timer;
 import 'dart:convert' show jsonEncode;
 import 'dart:io' show File, exitCode;
@@ -19,7 +18,7 @@
   final bool verbose;
   final bool printFailureLog;
   final Uri outputDirectory;
-  final String testFilter;
+  final String? testFilter;
   final String flutterDir;
   final String flutterPlatformDir;
 
@@ -49,7 +48,7 @@
     var parsedArguments = parser.parse(args);
     String outputPath = parsedArguments["output-directory"] ?? ".";
     Uri outputDirectory = Uri.base.resolveUri(Uri.directory(outputPath));
-    String filter;
+    String? filter;
     if (parsedArguments.rest.length == 1) {
       filter = parsedArguments.rest.single;
       if (filter.startsWith("$suiteNamePrefix/")) {
@@ -82,7 +81,7 @@
       "configuration": suiteConfiguration.configurationName,
       "suite": suiteNamePrefix,
       "test_name": testName,
-      "time_ms": stopwatches[testName].elapsedMilliseconds,
+      "time_ms": stopwatches[testName]!.elapsedMilliseconds,
       "expected": "Pass",
       "result": matchedExpectations ? "Pass" : "Fail",
       "matches": matchedExpectations,
@@ -145,7 +144,7 @@
   final bool verbose;
   final bool printFailureLog;
   final String configurationName;
-  final String testFilter;
+  final String? testFilter;
 
   final int shard;
   final int shards;
@@ -194,7 +193,7 @@
     ..listen((resultEntry) => results.add(resultEntry));
   ReceivePort logsPort = new ReceivePort()
     ..listen((logEntry) => logs.add(logEntry));
-  String filter = options.testFilter;
+  String? filter = options.testFilter;
 
   const int shards = 4;
   List<Future<bool>> futures = [];
diff --git a/pkg/frontend_server/test/src/javascript_bundle_test.dart b/pkg/frontend_server/test/src/javascript_bundle_test.dart
index 7e13464..21fa080 100644
--- a/pkg/frontend_server/test/src/javascript_bundle_test.dart
+++ b/pkg/frontend_server/test/src/javascript_bundle_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 'dart:convert';
 import 'dart:io';
 
@@ -190,7 +189,7 @@
 
       test('converts package: uris into /packages/ uris', () async {
         var importUri = Uri.parse('package:a/a.dart');
-        var fileUri = packageConfig.resolve(importUri);
+        var fileUri = packageConfig.resolve(importUri)!;
         final library = Library(
           importUri,
           fileUri: fileUri,
@@ -595,8 +594,7 @@
 ) {
   final result = Map<String, List<String>>.from(left);
   for (String key in right.keys) {
-    result[key] ??= [];
-    result[key].addAll(right[key]);
+    (result[key] ??= []).addAll(right[key]!);
   }
   return result;
 }
diff --git a/pkg/frontend_server/test/src/resident_frontend_server_test.dart b/pkg/frontend_server/test/src/resident_frontend_server_test.dart
index b2cbe8a..1145ac5 100644
--- a/pkg/frontend_server/test/src/resident_frontend_server_test.dart
+++ b/pkg/frontend_server/test/src/resident_frontend_server_test.dart
@@ -2,7 +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.md file.
 
-// @dart = 2.9
 import 'dart:convert';
 import 'dart:io';
 
@@ -66,8 +65,8 @@
   });
 
   group('Resident Frontend Server: compile tests: ', () {
-    Directory d;
-    File executable, package, cachedDill;
+    late Directory d;
+    late File executable, package, cachedDill;
 
     setUp(() async {
       d = Directory.systemTemp.createTempSync();
@@ -188,11 +187,11 @@
       expect(compileResults2['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
     });
 
@@ -243,19 +242,19 @@
           allOf(true, equals(compileResults2['success'])));
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.first,
+              .compilers[executable2.path]!.trackedSources.first,
           equals(Uri.file(executable2.path)));
       expect(ResidentFrontendServer.compilers.length, 2);
     });
@@ -322,11 +321,11 @@
       expect(compileResult1['incremental'], null);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
 
       // switching entrypoints, packages, and modifying packages
@@ -355,10 +354,10 @@
       expect(compileResult2['returnedStoredKernel'], null);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           greaterThanOrEqualTo(2));
       expect(
-          ResidentFrontendServer.compilers[executable2.path].trackedSources,
+          ResidentFrontendServer.compilers[executable2.path]!.trackedSources,
           containsAll(
               <Uri>{Uri.file(executable2.path), Uri.file(executable3.path)}));
 
@@ -374,9 +373,9 @@
       expect(compileResult3['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable2.path].trackedSources.length,
+              .compilers[executable2.path]!.trackedSources.length,
           greaterThanOrEqualTo(1));
-      expect(ResidentFrontendServer.compilers[executable2.path].trackedSources,
+      expect(ResidentFrontendServer.compilers[executable2.path]!.trackedSources,
           containsAll(<Uri>{Uri.file(executable2.path)}));
     });
 
@@ -408,11 +407,11 @@
       expect(compileResults2['incremental'], true);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.length,
+              .compilers[executable.path]!.trackedSources.length,
           1);
       expect(
           ResidentFrontendServer
-              .compilers[executable.path].trackedSources.first,
+              .compilers[executable.path]!.trackedSources.first,
           equals(Uri.file(executable.path)));
     });
 
@@ -507,8 +506,8 @@
   });
 
   group('Resident Frontend Server: socket tests: ', () {
-    Directory d;
-    File serverInfo;
+    late Directory d;
+    late File serverInfo;
 
     setUp(() {
       d = Directory.systemTemp.createTempSync();