Version 2.14.0-39.0.dev

Merge commit '30d27c6f61ac74eb2d42fe9889a5fb46789d4582' into 'dev'
diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart
index 5276220..3816e5f 100644
--- a/pkg/analysis_server/benchmark/benchmarks.dart
+++ b/pkg/analysis_server/benchmark/benchmarks.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.9
-
 import 'dart:convert';
 import 'dart:io';
 import 'dart:math' as math;
@@ -44,7 +42,7 @@
   ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
   var stateLocation = resourceProvider.getStateLocation('.analysis-driver');
   try {
-    if (stateLocation.exists) {
+    if (stateLocation != null && stateLocation.exists) {
       stateLocation.delete();
     }
   } catch (e) {
@@ -122,8 +120,8 @@
 
   @override
   BenchMarkResult combine(BenchMarkResult other) {
-    BenchMarkResult _combine(BenchMarkResult a, BenchMarkResult b) {
-      if (a == null) return b;
+    BenchMarkResult _combine(BenchMarkResult? a, BenchMarkResult? b) {
+      if (a == null) return b!;
       if (b == null) return a;
       return a.combine(b);
     }
@@ -144,8 +142,8 @@
   @override
   Map toJson() {
     var m = <String, dynamic>{};
-    for (var key in results.keys) {
-      m['$name-$key'] = results[key].toJson();
+    for (var entry in results.entries) {
+      m['$name-${entry.key}'] = entry.value.toJson();
     }
     return m;
   }
@@ -166,14 +164,14 @@
   String get description => 'List available benchmarks.';
 
   @override
-  String get invocation => '${runner.executableName} $name';
+  String get invocation => '${runner!.executableName} $name';
 
   @override
   String get name => 'list';
 
   @override
   void run() {
-    if (argResults['machine'] as bool) {
+    if (argResults!['machine'] as bool) {
       var map = <String, dynamic>{
         'benchmarks': benchmarks.map((b) => b.toJson()).toList()
       };
@@ -206,22 +204,22 @@
   String get description => 'Run a given benchmark.';
 
   @override
-  String get invocation => '${runner.executableName} $name <benchmark-id>';
+  String get invocation => '${runner!.executableName} $name <benchmark-id>';
 
   @override
   String get name => 'run';
 
   @override
   Future run() async {
-    if (argResults.rest.isEmpty) {
+    if (argResults!.rest.isEmpty) {
       printUsage();
       exit(1);
     }
 
-    var benchmarkId = argResults.rest.first;
-    var repeatCount = int.parse(argResults['repeat'] as String);
-    var quick = argResults['quick'];
-    var verbose = argResults['verbose'];
+    var benchmarkId = argResults!.rest.first;
+    var repeatCount = int.parse(argResults!['repeat'] as String);
+    var quick = argResults!['quick'];
+    var verbose = argResults!['verbose'];
 
     var benchmark =
         benchmarks.firstWhere((b) => b.id == benchmarkId, orElse: () {
@@ -240,7 +238,7 @@
     }
 
     try {
-      BenchMarkResult result;
+      BenchMarkResult? result;
       var time = Stopwatch()..start();
       print('Running $benchmarkId $actualIterations times...');
 
@@ -257,7 +255,7 @@
       print('Finished in ${time.elapsed.inSeconds} seconds.\n');
       var m = <String, dynamic>{
         'benchmark': benchmarkId,
-        'result': result.toJson()
+        'result': result!.toJson()
       };
       print(json.encode(m));
 
diff --git a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart b/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart
index 1a59fa6..fab0850 100644
--- a/pkg/analysis_server/benchmark/perf/benchmarks_impl.dart
+++ b/pkg/analysis_server/benchmark/perf/benchmarks_impl.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.9
-
 import 'dart:async';
 import 'dart:io';
 
diff --git a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
index 171aab6..048666b 100644
--- a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
+++ b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.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.9
-
 import 'dart:convert';
 import 'dart:io';
 
@@ -14,7 +12,7 @@
 Future<int> _runProcess(
   String command,
   List<String> args, {
-  String cwd,
+  String? cwd,
   bool failOnError = true,
 }) async {
   print('\n$command ${args.join(' ')}');
@@ -43,7 +41,7 @@
 /// benchmarks:
 ///   - analysis-flutter-analyze
 class FlutterAnalyzeBenchmark extends Benchmark {
-  Directory flutterDir;
+  late Directory flutterDir;
 
   FlutterAnalyzeBenchmark()
       : super(
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index 9a2c30c..a7b3682 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.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.9
-
 import 'dart:async';
 import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:io';
@@ -159,7 +157,7 @@
 
   @override
   Future<void> complete(String filePath, int offset) {
-    final contents = _fileContents[filePath];
+    final contents = _fileContents[filePath]!;
     final position = _test.positionFromOffset(offset, contents);
     return _test.getCompletion(Uri.file(filePath), position);
   }
@@ -221,7 +219,7 @@
   Map<String, List<Diagnostic>> currentAnalysisErrors = {};
 
   @override
-  void expect(actual, matcher, {String reason}) =>
+  void expect(actual, matcher, {String? reason}) =>
       outOfTestExpect(actual, matcher, reason: reason);
 
   /// The server is automatically started before every test.
@@ -247,7 +245,7 @@
 }
 
 mixin ServerMemoryUsageMixin {
-  int _vmServicePort;
+  late int _vmServicePort;
 
   Future<int> getMemoryUsage() async {
     var uri = Uri.parse('ws://127.0.0.1:$_vmServicePort/ws');
@@ -262,8 +260,8 @@
           await service.call('getIsolate', {'isolateId': isolateRef['id']});
 
       Map _heaps = isolate['_heaps'];
-      total += _heaps['new']['used'] + _heaps['new']['external'];
-      total += _heaps['old']['used'] + _heaps['old']['external'];
+      total += _heaps['new']['used'] + _heaps['new']['external'] as int;
+      total += _heaps['old']['used'] + _heaps['old']['external'] as int;
     }
 
     service.dispose();
@@ -292,7 +290,7 @@
       'method': method,
       'args': args
     };
-    if (args != null) m['params'] = args;
+    m['params'] = args;
     var message = jsonEncode(m);
     socket.add(message);
     return completer.future;
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 0521a2a..bf400ba 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.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.9
-
 import 'dart:async';
 import 'dart:io';
 import 'dart:isolate';
@@ -117,12 +115,12 @@
 
   /// An optional manager to handle file systems which may not always be
   /// available.
-  DetachableFileSystemManager detachableFileSystemManager;
+  DetachableFileSystemManager? detachableFileSystemManager;
 
   /// The instrumentation service that is to be used by the analysis server.
-  InstrumentationService instrumentationService;
+  InstrumentationService? instrumentationService;
 
-  HttpAnalysisServer httpServer;
+  HttpAnalysisServer? httpServer;
 
   Driver();
 
@@ -133,7 +131,7 @@
   @override
   void start(
     List<String> arguments, {
-    SendPort sendPort,
+    SendPort? sendPort,
     bool defaultToLsp = false,
   }) {
     var parser = createArgParser(defaultToLsp: defaultToLsp);
@@ -237,11 +235,11 @@
     //
     // Initialize the instrumentation service.
     //
-    String logFilePath =
+    var logFilePath =
         results[PROTOCOL_TRAFFIC_LOG] ?? results[PROTOCOL_TRAFFIC_LOG_ALIAS];
-    var allInstrumentationServices = instrumentationService == null
+    var allInstrumentationServices = this.instrumentationService == null
         ? <InstrumentationService>[]
-        : [instrumentationService];
+        : [this.instrumentationService!];
     if (logFilePath != null) {
       _rollLogFiles(logFilePath, 5);
       allInstrumentationServices.add(
@@ -251,22 +249,23 @@
     var errorNotifier = ErrorNotifier();
     allInstrumentationServices
         .add(CrashReportingInstrumentation(crashReportSender));
-    instrumentationService =
+    final instrumentationService =
         MulticastInstrumentationService(allInstrumentationServices);
+    this.instrumentationService = instrumentationService;
 
     instrumentationService.logVersion(
       results[TRAIN_USING] != null
           ? 'training-0'
           : _readUuid(instrumentationService),
-      analysisServerOptions.clientId,
-      analysisServerOptions.clientVersion,
+      analysisServerOptions.clientId ?? '',
+      analysisServerOptions.clientVersion ?? '',
       PROTOCOL_VERSION,
       defaultSdk.languageVersion.toString(),
     );
     AnalysisEngine.instance.instrumentationService = instrumentationService;
 
-    int diagnosticServerPort;
-    final String portValue =
+    int? diagnosticServerPort;
+    final String? portValue =
         results[DIAGNOSTIC_PORT] ?? results[DIAGNOSTIC_PORT_ALIAS];
     if (portValue != null) {
       try {
@@ -312,14 +311,14 @@
     InstrumentationService instrumentationService,
     RequestStatisticsHelper requestStatistics,
     telemetry.Analytics analytics,
-    int diagnosticServerPort,
+    int? diagnosticServerPort,
     ErrorNotifier errorNotifier,
-    SendPort sendPort,
+    SendPort? sendPort,
   ) {
     var capture = results[DISABLE_SERVER_EXCEPTION_HANDLING]
-        ? (_, Function f, {Function(String) print}) => f()
+        ? (_, Function f, {Function(String)? print}) => f()
         : _captureExceptions;
-    String trainDirectory = results[TRAIN_USING];
+    var trainDirectory = results[TRAIN_USING];
     if (trainDirectory != null) {
       if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
         print("Training directory '$trainDirectory' not found.\n");
@@ -327,8 +326,6 @@
         return null;
       }
     }
-    final serve_http = diagnosticServerPort != null;
-
     //
     // Register lint rules.
     //
@@ -354,8 +351,8 @@
 
     errorNotifier.server = socketServer.analysisServer;
 
-    diagnosticServer.httpServer = httpServer;
-    if (serve_http) {
+    diagnosticServer.httpServer = httpServer!;
+    if (diagnosticServerPort != null) {
       diagnosticServer.startOnPort(diagnosticServerPort);
     }
 
@@ -384,12 +381,13 @@
         exitCode = await devServer.processDirectories([trainDirectory]);
         if (exitCode != 0) exit(exitCode);
 
-        if (serve_http) {
+        final httpServer = this.httpServer;
+        if (httpServer != null) {
           httpServer.close();
         }
         await instrumentationService.shutdown();
 
-        socketServer.analysisServer.shutdown();
+        socketServer.analysisServer!.shutdown();
 
         try {
           tempDriverDir.deleteSync(recursive: true);
@@ -410,17 +408,18 @@
           serveResult = isolateAnalysisServer.serveIsolate(sendPort);
         }
         serveResult.then((_) async {
-          if (serve_http) {
+          final httpServer = this.httpServer;
+          if (httpServer != null) {
             httpServer.close();
           }
           await instrumentationService.shutdown();
-          socketServer.analysisServer.shutdown();
+          socketServer.analysisServer!.shutdown();
           if (sendPort == null) exit(0);
         });
       },
           print: results[INTERNAL_PRINT_TO_CONSOLE]
               ? null
-              : httpServer.recordPrint);
+              : httpServer!.recordPrint);
     }
   }
 
@@ -429,13 +428,12 @@
     AnalysisServerOptions analysisServerOptions,
     DartSdkManager dartSdkManager,
     InstrumentationService instrumentationService,
-    int diagnosticServerPort,
+    int? diagnosticServerPort,
     ErrorNotifier errorNotifier,
   ) {
     var capture = args[DISABLE_SERVER_EXCEPTION_HANDLING]
-        ? (_, Function f, {Function(String) print}) => f()
+        ? (_, Function f, {Function(String)? print}) => f()
         : _captureExceptions;
-    final serve_http = diagnosticServerPort != null;
 
     linter.registerLintRules();
 
@@ -449,10 +447,9 @@
     );
     errorNotifier.server = socketServer.analysisServer;
 
-    httpServer = HttpAnalysisServer(socketServer);
+    diagnosticServer.httpServer = httpServer = HttpAnalysisServer(socketServer);
 
-    diagnosticServer.httpServer = httpServer;
-    if (serve_http) {
+    if (diagnosticServerPort != null) {
       diagnosticServer.startOnPort(diagnosticServerPort);
     }
 
@@ -461,8 +458,8 @@
       stdioServer.serveStdio().then((_) async {
         // Only shutdown the server and exit if the server is not already
         // handling the shutdown.
-        if (!socketServer.analysisServer.willExit) {
-          socketServer.analysisServer.shutdown();
+        if (!socketServer.analysisServer!.willExit) {
+          socketServer.analysisServer!.shutdown();
           exit(0);
         }
       });
@@ -475,7 +472,7 @@
   /// capture any data printed by the callback and redirect it to the function.
   void _captureExceptions(
       InstrumentationService service, void Function() callback,
-      {void Function(String line) print}) {
+      {void Function(String line)? print}) {
     void errorFunction(Zone self, ZoneDelegate parent, Zone zone,
         dynamic exception, StackTrace stackTrace) {
       service.logException(exception, stackTrace);
@@ -510,7 +507,7 @@
   }
 
   String _getSdkPath(ArgResults args) {
-    String sdkPath;
+    String? sdkPath;
 
     void tryCandidateArgument(String argumentName) {
       var argumentValue = args[argumentName];
@@ -521,11 +518,11 @@
 
     tryCandidateArgument(DART_SDK);
     tryCandidateArgument(DART_SDK_ALIAS);
-    sdkPath ??= getSdkPath();
+    var sdkPath2 = sdkPath ?? getSdkPath();
 
     var pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
     return pathContext.normalize(
-      pathContext.absolute(sdkPath),
+      pathContext.absolute(sdkPath2),
     );
   }
 
@@ -563,7 +560,7 @@
     try {
       if (uuidFile.existsSync()) {
         var uuid = uuidFile.readAsStringSync();
-        if (uuid != null && uuid.length > 5) {
+        if (uuid.length > 5) {
           return uuid;
         }
       }
@@ -584,7 +581,7 @@
 
   /// Create and return the parser used to parse the command-line arguments.
   static ArgParser createArgParser({
-    int usageLineLength,
+    int? usageLineLength,
     bool includeHelpFlag = true,
     bool defaultToLsp = false,
   }) {
@@ -732,12 +729,12 @@
 
 /// Implements the [DiagnosticServer] class by wrapping an [HttpAnalysisServer].
 class _DiagnosticServerImpl extends DiagnosticServer {
-  HttpAnalysisServer httpServer;
+  late HttpAnalysisServer httpServer;
 
   _DiagnosticServerImpl();
 
   @override
-  Future<int> getServerPort() => httpServer.serveHttp();
+  Future<int> getServerPort() async => (await httpServer.serveHttp())!;
 
   Future startOnPort(int port) {
     return httpServer.serveHttp(port);
diff --git a/pkg/analysis_server/lib/src/server/error_notifier.dart b/pkg/analysis_server/lib/src/server/error_notifier.dart
index a533aae..9ed325a 100644
--- a/pkg/analysis_server/lib/src/server/error_notifier.dart
+++ b/pkg/analysis_server/lib/src/server/error_notifier.dart
@@ -9,7 +9,7 @@
 /// An instrumentation service to show instrumentation errors as error
 /// notifications to the user.
 class ErrorNotifier extends NoopInstrumentationService {
-  late AbstractAnalysisServer server;
+  AbstractAnalysisServer? server;
 
   @override
   void logException(
@@ -17,7 +17,8 @@
     StackTrace? stackTrace,
     List<InstrumentationServiceAttachment>? attachments,
   ]) {
-    if (exception is SilentException) {
+    final server = this.server;
+    if (server == null || exception is SilentException) {
       // Silent exceptions should not be reported to the user.
       return;
     }
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index 1e6fc74..9826d89 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.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.9
-
 import 'dart:io';
 
 import 'package:analysis_server/src/socket_server.dart';
@@ -29,10 +27,10 @@
   AbstractSocketServer socketServer;
 
   /// An object that can handle GET requests.
-  AbstractGetHandler getHandler;
+  AbstractGetHandler? getHandler;
 
   /// Future that is completed with the HTTP server once it is running.
-  Future<HttpServer> _serverFuture;
+  Future<HttpServer>? _serverFuture;
 
   /// Last PRINT_BUFFER_LENGTH lines printed.
   final List<String> _printBuffer = <String>[];
@@ -41,7 +39,7 @@
   HttpAnalysisServer(this.socketServer);
 
   /// Return the port this server is bound to.
-  Future<int> get boundPort async {
+  Future<int?> get boundPort async {
     return (await _serverFuture)?.port;
   }
 
@@ -61,7 +59,7 @@
   }
 
   /// Begin serving HTTP requests over the given port.
-  Future<int> serveHttp([int initialPort]) async {
+  Future<int?> serveHttp([int? initialPort]) async {
     if (_serverFuture != null) {
       return boundPort;
     }
@@ -70,7 +68,7 @@
       _serverFuture =
           HttpServer.bind(InternetAddress.loopbackIPv4, initialPort ?? 0);
 
-      var server = await _serverFuture;
+      var server = (await _serverFuture)!;
       _handleServer(server);
       return server.port;
     } catch (ignore) {
@@ -87,7 +85,7 @@
     getHandler ??= DiagnosticsSite(socketServer, _printBuffer);
     // TODO(brianwilkerson) Determine if await is necessary, if so, change the
     // return type of [AbstractGetHandler.handleGetRequest] to `Future<void>`.
-    await (getHandler.handleGetRequest(request) as dynamic);
+    await (getHandler!.handleGetRequest(request) as dynamic);
   }
 
   /// Attach a listener to a newly created HTTP server.
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 86da984..10bf891 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.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.9
-
 import 'dart:developer' as developer;
 import 'dart:io';
 
@@ -25,12 +23,14 @@
 import 'package:analysis_server/src/utilities/profiling.dart';
 import 'package:analyzer/dart/analysis/context_root.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:collection/collection.dart';
 import 'package:path/path.dart' as path;
 
 final String kCustomCss = '''
@@ -206,7 +206,7 @@
     buf.writeln(
         '<tr><th>Time</th><th>Results</th><th>Source</th><th>Snippet</th></tr>');
     for (var completion in completions) {
-      var shortName = pathContext.basename(completion.path);
+      var shortName = pathContext.basename(completion.path ?? '<missing path>');
       buf.writeln('<tr>'
           '<td class="pre right">${printMilliseconds(completion.elapsedInMilliseconds)}</td>'
           '<td class="right">${completion.suggestionCountStr}</td>'
@@ -219,13 +219,13 @@
 }
 
 class AstPage extends DiagnosticPageWithNav {
-  String _description;
+  String? _description;
 
   AstPage(DiagnosticsSite site)
       : super(site, 'ast', 'AST', description: 'The AST for a file.');
 
   @override
-  String get description => _description ?? super.description;
+  String? get description => _description ?? super.description;
 
   @override
   bool get showInNav => false;
@@ -246,7 +246,7 @@
     var result = await driver.getResult2(filePath);
     if (result is ResolvedUnitResult) {
       var writer = AstWriter(buf);
-      result.unit.accept(writer);
+      result.unit!.accept(writer);
     } else {
       p(
           'An AST could not be produced for the file '
@@ -274,7 +274,7 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    void writeRow(List<String> data, {List<String> classes}) {
+    void writeRow(List<String> data, {List<String?>? classes}) {
       buf.write('<tr>');
       for (var i = 0; i < data.length; i++) {
         var c = classes == null ? null : classes[i];
@@ -289,11 +289,12 @@
 
     buf.writeln('<div class="columns">');
 
-    if (server.performanceAfterStartup != null) {
+    var performanceAfterStartup = server.performanceAfterStartup;
+    if (performanceAfterStartup != null) {
       buf.writeln('<div class="column one-half">');
 
       h3('Current');
-      _writePerformanceTable(server.performanceAfterStartup, writeRow);
+      _writePerformanceTable(performanceAfterStartup, writeRow);
 
       var time = server.uptime.toString();
       if (time.contains('.')) {
@@ -309,8 +310,8 @@
     h3('Startup');
     _writePerformanceTable(server.performanceDuringStartup, writeRow);
 
-    if (server.performanceAfterStartup != null) {
-      var startupTime = server.performanceAfterStartup.startTime -
+    if (performanceAfterStartup != null) {
+      var startupTime = performanceAfterStartup.startTime -
           server.performanceDuringStartup.startTime;
       buf.writeln(
           writeOption('Initial analysis time', printMilliseconds(startupTime)));
@@ -322,7 +323,7 @@
   }
 
   void _writePerformanceTable(ServerPerformance perf,
-      void Function(List<String> data, {List<String> classes}) writeRow) {
+      void Function(List<String> data, {List<String?> classes}) writeRow) {
     var requestCount = perf.requestCount;
     var latencyCount = perf.latencyCount;
     var averageLatency =
@@ -355,7 +356,8 @@
   CompletionPage(DiagnosticsSite site, this.server) : super(site);
 
   CompletionDomainHandler get completionDomain => server.handlers
-      .firstWhere((handler) => handler is CompletionDomainHandler);
+          .firstWhere((handler) => handler is CompletionDomainHandler)
+      as CompletionDomainHandler;
 
   @override
   path.Context get pathContext =>
@@ -367,14 +369,14 @@
 }
 
 class ContentsPage extends DiagnosticPageWithNav {
-  String _description;
+  String? _description;
 
   ContentsPage(DiagnosticsSite site)
       : super(site, 'contents', 'Contents',
             description: 'The Contents/Overlay of a file.');
 
   @override
-  String get description => _description ?? super.description;
+  String? get description => _description ?? super.description;
 
   @override
   bool get showInNav => false;
@@ -453,22 +455,23 @@
     }
 
     var contextPath = params['context'];
-    var folders = driverMap.keys.toList();
-    folders
-        .sort((first, second) => first.shortName.compareTo(second.shortName));
-    var folder =
-        folders.firstWhere((f) => f.path == contextPath, orElse: () => null);
+    var entries = driverMap.entries.toList();
+    entries.sort(
+        (first, second) => first.key.shortName.compareTo(second.key.shortName));
+    var entry = entries.firstWhereOrNull((f) => f.key.path == contextPath);
 
-    if (folder == null) {
-      folder = folders.first;
-      contextPath = folder.path;
+    if (entry == null) {
+      entry = entries.first;
+      contextPath = entry.key.path;
     }
 
-    var driver = driverMap[folder];
+    var folder = entry.key;
+    var driver = entry.value;
 
     buf.writeln('<div class="tabnav">');
     buf.writeln('<nav class="tabnav-tabs">');
-    for (var f in folders) {
+    for (var entry in entries) {
+      var f = entry.key;
       if (f == folder) {
         buf.writeln(
             '<a class="tabnav-tab selected">${escape(f.shortName)}</a>');
@@ -485,15 +488,15 @@
     buf.writeln(writeOption(
         'Analysis options path',
         escape(
-            driver.analysisContext?.contextRoot?.optionsFile?.path ?? 'none')));
+            driver.analysisContext?.contextRoot.optionsFile?.path ?? 'none')));
     buf.writeln(
-        writeOption('SDK root', escape(driver.analysisContext.sdkRoot?.path)));
+        writeOption('SDK root', escape(driver.analysisContext?.sdkRoot?.path)));
 
     buf.writeln('<div class="columns">');
 
     buf.writeln('<div class="column one-half">');
     h3('Analysis options');
-    p(describe(driver.analysisOptions), raw: true);
+    p(describe(driver.analysisOptions as AnalysisOptionsImpl), raw: true);
 
     h3('Pub files');
     buf.writeln('<p>');
@@ -584,7 +587,7 @@
 
     h3('Dartdoc template info');
     var info = server.declarationsTracker
-            ?.getContext(driver.analysisContext)
+            ?.getContext(driver.analysisContext!)
             ?.dartdocDirectiveInfo ??
         DartdocDirectiveInfo();
     buf.write('<p class="scroll-table">');
@@ -622,19 +625,19 @@
 abstract class DiagnosticPage extends Page {
   final DiagnosticsSite site;
 
-  DiagnosticPage(this.site, String id, String title, {String description})
+  DiagnosticPage(this.site, String id, String title, {String? description})
       : super(id, title, description: description);
 
   bool get isNavPage => false;
 
-  AbstractAnalysisServer get server => site.socketServer.analysisServer;
+  AbstractAnalysisServer get server => site.socketServer.analysisServer!;
 
   Future<void> generateContainer(Map<String, String> params) async {
     buf.writeln('<div class="columns docs-layout">');
     buf.writeln('<div class="three-fourths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      p(description);
+      p(description ?? 'Unknown Page');
       await generateContent(params);
     }, classes: 'markdown-body');
     buf.writeln('</div>');
@@ -701,13 +704,13 @@
 
 abstract class DiagnosticPageWithNav extends DiagnosticPage {
   DiagnosticPageWithNav(DiagnosticsSite site, String id, String title,
-      {String description})
+      {String? description})
       : super(site, id, title, description: description);
 
   @override
   bool get isNavPage => true;
 
-  String get navDetail => null;
+  String? get navDetail => null;
 
   bool get showInNav => true;
 
@@ -736,7 +739,7 @@
     buf.writeln('<div class="four-fifths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      p(description);
+      p(description ?? 'Unknown Page');
       await generateContent(params);
     }, classes: 'markdown-body');
     buf.writeln('</div>');
@@ -764,8 +767,9 @@
     // Add server-specific pages. Ordering doesn't matter as the items are
     // sorted later.
     var server = socketServer.analysisServer;
-    pages.add(PluginsPage(this, server));
-
+    if (server != null) {
+      pages.add(PluginsPage(this, server));
+    }
     if (server is AnalysisServer) {
       pages.add(CompletionPage(this, server));
       pages.add(SubscriptionsPage(this, server));
@@ -804,14 +808,14 @@
 }
 
 class ElementModelPage extends DiagnosticPageWithNav {
-  String _description;
+  String? _description;
 
   ElementModelPage(DiagnosticsSite site)
       : super(site, 'element', 'Element model',
             description: 'The element model for a file.');
 
   @override
-  String get description => _description ?? super.description;
+  String? get description => _description ?? super.description;
 
   @override
   bool get showInNav => false;
@@ -830,9 +834,13 @@
       return;
     }
     var result = await driver.getResult2(filePath);
+    CompilationUnitElement? compilationUnitElement;
     if (result is ResolvedUnitResult) {
+      compilationUnitElement = result.unit?.declaredElement;
+    }
+    if (compilationUnitElement != null) {
       var writer = ElementWriter(buf);
-      result.unit.declaredElement.accept(writer);
+      compilationUnitElement.accept(writer);
     } else {
       p(
           'An element model could not be produced for the file '
@@ -929,11 +937,13 @@
     ], (line) => buf.writeln(line));
 
     var ideInfo = <String>[];
-    if (server.options.clientId != null) {
-      ideInfo.add(server.options.clientId);
+    var clientId = server.options.clientId;
+    if (clientId != null) {
+      ideInfo.add(clientId);
     }
-    if (server.options.clientVersion != null) {
-      ideInfo.add(server.options.clientVersion);
+    var clientVersion = server.options.clientVersion;
+    if (clientVersion != null) {
+      ideInfo.add(clientVersion);
     }
     var ideText = ideInfo.map((str) => '<code>$str</code>').join(', ');
 
@@ -962,19 +972,21 @@
 
     buf.writeln('<div class="column one-half">');
     h3('Client Capabilities');
-    if (server.clientCapabilities == null) {
+    var clientCapabilities = server.clientCapabilities;
+    if (clientCapabilities == null) {
       p('Client capabilities have not yet been received.');
     } else {
-      prettyJson(server.clientCapabilities.raw.toJson());
+      prettyJson(clientCapabilities.raw.toJson());
     }
     buf.writeln('</div>');
 
     buf.writeln('<div class="column one-half">');
     h3('Server Capabilities');
-    if (server.capabilities == null) {
+    var capabilities = server.capabilities;
+    if (capabilities == null) {
       p('Server capabilities have not yet been computed.');
     } else {
-      prettyJson(server.capabilities.toJson());
+      prettyJson(capabilities.toJson());
     }
     buf.writeln('</div>'); // half for server capabilities
     buf.writeln('</div>'); // columns
@@ -1108,7 +1120,7 @@
       for (var plugin in analysisPlugins) {
         var id = plugin.pluginId;
         var data = plugin.data;
-        var responseTimes = PluginManager.pluginResponseTimes[plugin];
+        var responseTimes = PluginManager.pluginResponseTimes[plugin] ?? {};
 
         var components = path.split(id);
         var length = components.length;
@@ -1148,10 +1160,11 @@
             });
           }
           p('Performance:');
-          var requestNames = responseTimes.keys.toList();
-          requestNames.sort();
-          for (var requestName in requestNames) {
-            var data = responseTimes[requestName];
+          var entries = responseTimes.entries.toList();
+          entries.sort((first, second) => first.key.compareTo(second.key));
+          for (var entry in entries) {
+            var requestName = entry.key;
+            var data = entry.value;
             // TODO(brianwilkerson) Consider displaying these times as a graph,
             //  similar to the one in AbstractCompletionPage.generateContent.
             var buffer = StringBuffer();
@@ -1199,7 +1212,8 @@
 
       buf.writeln('<div class="column one-half">');
       h3('Configuration Overrides');
-      buf.writeln('<pre><code>${sdkConfig.displayString}</code></pre><br>');
+      buf.writeln(
+          '<pre><code>${sdkConfig?.displayString ?? '<unknown overrides>'}</code></pre><br>');
       buf.writeln('</div>');
 
       buf.writeln('</div>');
@@ -1237,18 +1251,18 @@
     h3('Analysis domain subscriptions');
     for (var service in AnalysisService.VALUES) {
       buf.writeln('${service.name}<br>');
-      ul(server.analysisServices[service] ?? [], (item) {
+      ul(server.analysisServices[service] ?? {}, (item) {
         buf.write('$item');
       });
     }
 
     // completion domain
-    CompletionDomainHandler handler = server.handlers.firstWhere(
-        (handler) => handler is CompletionDomainHandler,
-        orElse: () => null);
+    var handler = server.handlers
+            .firstWhereOrNull((handler) => handler is CompletionDomainHandler)
+        as CompletionDomainHandler?;
     h3('Completion domain subscriptions');
     ul(CompletionService.VALUES, (service) {
-      if (handler.subscriptions.contains(service)) {
+      if (handler?.subscriptions.contains(service) ?? false) {
         buf.write('$service (has subscriptions)');
       } else {
         buf.write('$service (no subscriptions)');
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index a8d4451..78fb773 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.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.9
-
 import 'dart:isolate';
 
 import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
diff --git a/pkg/analysis_server/test/integration/test_all.dart b/pkg/analysis_server/test/integration/test_all.dart
index 5ed27bc1..9ef661b 100644
--- a/pkg/analysis_server/test/integration/test_all.dart
+++ b/pkg/analysis_server/test/integration/test_all.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.9
-
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'analysis/test_all.dart' as analysis;
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index a042a4f..eca22e0 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.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.9
-
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../tool/spec/check_all_test.dart' as check_spec;
diff --git a/tools/VERSION b/tools/VERSION
index 1a5a54c..0d084e3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 38
+PRERELEASE 39
 PRERELEASE_PATCH 0
\ No newline at end of file