Extract out AnalysisServersWrapper (#593)

diff --git a/lib/src/analysis_server.dart b/lib/src/analysis_server.dart
index d719e36..30020d8 100644
--- a/lib/src/analysis_server.dart
+++ b/lib/src/analysis_server.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server_lib/analysis_server_lib.dart';
 import 'package:logging/logging.dart';
 import 'package:path/path.dart' as path;
+import 'package:pedantic/pedantic.dart';
 
 import 'common.dart';
 import 'flutter_web.dart';
@@ -43,6 +44,97 @@
   String get _sourceDirPath => flutterWebManager.projectDirectory.path;
 }
 
+class AnalysisServersWrapper {
+  AnalysisServersWrapper(this._flutterWebManager);
+
+  final FlutterWebManager _flutterWebManager;
+  DartAnalysisServerWrapper _dartAnalysisServer;
+  FlutterAnalysisServerWrapper _flutterAnalysisServer;
+
+  bool get running =>
+      _dartAnalysisServer.analysisServer != null &&
+      _flutterAnalysisServer.analysisServer != null;
+
+  // If non-null, this value indicates that the server is starting/restarting
+  // and holds the time at which that process began. If null, the server is
+  // ready to handle requests.
+  DateTime _restartingSince = DateTime.now();
+
+  bool get isRestarting => (_restartingSince != null);
+
+  // If the server has been trying and failing to restart for more than a half
+  // hour, something is seriously wrong.
+  bool get isHealthy => (_restartingSince == null ||
+      DateTime.now().difference(_restartingSince).inMinutes < 30);
+
+  Future<void> init() async {
+    _logger.info('Beginning CommonServer init().');
+    _dartAnalysisServer = DartAnalysisServerWrapper();
+    _flutterAnalysisServer = FlutterAnalysisServerWrapper(_flutterWebManager);
+
+    await _dartAnalysisServer.init();
+    _logger.info('Dart analysis server initialized.');
+
+    await _flutterAnalysisServer.init();
+    _logger.info('Flutter analysis server initialized.');
+
+    unawaited(_dartAnalysisServer.onExit.then((int code) {
+      _logger.severe('dartAnalysisServer exited, code: $code');
+      if (code != 0) {
+        exit(code);
+      }
+    }));
+
+    unawaited(_flutterAnalysisServer.onExit.then((int code) {
+      _logger.severe('flutterAnalysisServer exited, code: $code');
+      if (code != 0) {
+        exit(code);
+      }
+    }));
+
+    _restartingSince = null;
+  }
+
+  Future warmup() => Future.wait(<Future<dynamic>>[
+        _flutterWebManager.warmup(),
+        _dartAnalysisServer.warmup(),
+      ]);
+
+  Future<dynamic> shutdown() {
+    _restartingSince = DateTime.now();
+
+    return Future.wait(<Future<dynamic>>[
+      _dartAnalysisServer.shutdown(),
+      _flutterAnalysisServer.shutdown(),
+    ]);
+  }
+
+  AnalysisServerWrapper _getCorrectAnalysisServer(String source) {
+    final imports = getAllImportsFor(source);
+    return _flutterWebManager.usesFlutterWeb(imports)
+        ? _flutterAnalysisServer
+        : _dartAnalysisServer;
+  }
+
+  Future<proto.AnalysisResults> analyze(String source) =>
+      _getCorrectAnalysisServer(source).analyze(source);
+
+  Future<proto.CompleteResponse> complete(String source, int offset) =>
+      _getCorrectAnalysisServer(source).complete(source, offset);
+
+  Future<proto.FixesResponse> getFixes(String source, int offset) =>
+      _getCorrectAnalysisServer(source).getFixes(source, offset);
+
+  Future<proto.AssistsResponse> getAssists(String source, int offset) =>
+      _getCorrectAnalysisServer(source).getAssists(source, offset);
+
+  Future<proto.FormatResponse> format(String source, int offset) =>
+      _getCorrectAnalysisServer(source).format(source, offset);
+
+  Future<Map<String, String>> dartdoc(String source, int offset) =>
+      _getCorrectAnalysisServer(source).dartdoc(source, offset);
+}
+
 class DartAnalysisServerWrapper extends AnalysisServerWrapper {
   Directory _tempProject;
   DartAnalysisServerWrapper() : super(SdkManager.sdk.sdkPath);
diff --git a/lib/src/common_server_impl.dart b/lib/src/common_server_impl.dart
index f9351fb..af2e5de 100644
--- a/lib/src/common_server_impl.dart
+++ b/lib/src/common_server_impl.dart
@@ -6,7 +6,6 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'dart:io';
 
 import 'package:crypto/crypto.dart';
 import 'package:logging/logging.dart';
@@ -41,24 +40,15 @@
 
   FlutterWebManager flutterWebManager;
   Compiler compiler;
-  AnalysisServerWrapper dartAnalysisServer;
-  AnalysisServerWrapper flutterAnalysisServer;
+  AnalysisServersWrapper analysisServers;
 
-  bool get analysisServersRunning =>
-      dartAnalysisServer.analysisServer != null &&
-      flutterAnalysisServer.analysisServer != null;
+  bool get analysisServersRunning => analysisServers.running;
 
-  // If non-null, this value indicates that the server is starting/restarting
-  // and holds the time at which that process began. If null, the server is
-  // ready to handle requests.
-  DateTime _restartingSince = DateTime.now();
-
-  bool get isRestarting => (_restartingSince != null);
+  bool get isRestarting => analysisServers.isRestarting;
 
   // If the server has been trying and failing to restart for more than a half
   // hour, something is seriously wrong.
-  bool get isHealthy => (_restartingSince == null ||
-      DateTime.now().difference(_restartingSince).inMinutes < 30);
+  bool get isHealthy => analysisServers.isHealthy;
 
   CommonServerImpl(
     this.container,
@@ -71,38 +61,17 @@
   Future<void> init() async {
     log.info('Beginning CommonServer init().');
     flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
-    dartAnalysisServer = DartAnalysisServerWrapper();
-    flutterAnalysisServer = FlutterAnalysisServerWrapper(flutterWebManager);
+    analysisServers = AnalysisServersWrapper(flutterWebManager);
 
     compiler =
         Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
 
-    await dartAnalysisServer.init();
-    log.info('Dart analysis server initialized.');
-
-    await flutterAnalysisServer.init();
-    log.info('Flutter analysis server initialized.');
-
-    unawaited(dartAnalysisServer.onExit.then((int code) {
-      log.severe('dartAnalysisServer exited, code: $code');
-      if (code != 0) {
-        exit(code);
-      }
-    }));
-
-    unawaited(flutterAnalysisServer.onExit.then((int code) {
-      log.severe('flutterAnalysisServer exited, code: $code');
-      if (code != 0) {
-        exit(code);
-      }
-    }));
-
-    _restartingSince = null;
+    await analysisServers.init();
+    log.info('Analysis servers initialized.');
 
     await flutterWebManager.warmup();
     await compiler.warmup();
-    await dartAnalysisServer.warmup();
-    await flutterAnalysisServer.warmup();
+    await analysisServers.warmup();
   }
 
   Future<void> restart() async {
@@ -115,11 +84,8 @@
   }
 
   Future<dynamic> shutdown() {
-    _restartingSince = DateTime.now();
-
     return Future.wait(<Future<dynamic>>[
-      dartAnalysisServer.shutdown(),
-      flutterAnalysisServer.shutdown(),
+      analysisServers.shutdown(),
       compiler.dispose(),
       flutterWebManager.dispose(),
       Future<dynamic>.sync(cache.shutdown)
@@ -212,7 +178,7 @@
     try {
       final watch = Stopwatch()..start();
 
-      final results = await getCorrectAnalysisServer(source).analyze(source);
+      final results = await analysisServers.analyze(source);
       final lineCount = source.split('\n').length;
       final ms = watch.elapsedMilliseconds;
       log.info('PERF: Analyzed $lineCount lines of Dart in ${ms}ms.');
@@ -341,8 +307,7 @@
 
     final watch = Stopwatch()..start();
     try {
-      var docInfo =
-          await getCorrectAnalysisServer(source).dartdoc(source, offset);
+      var docInfo = await analysisServers.dartdoc(source, offset);
       docInfo ??= <String, String>{};
       log.info('PERF: Computed dartdoc in ${watch.elapsedMilliseconds}ms.');
       return proto.DocumentResponse()..info.addAll(docInfo);
@@ -368,8 +333,7 @@
 
     final watch = Stopwatch()..start();
     try {
-      final response =
-          await getCorrectAnalysisServer(source).complete(source, offset);
+      final response = await analysisServers.complete(source, offset);
       log.info('PERF: Computed completions in ${watch.elapsedMilliseconds}ms.');
       return response;
     } catch (e, st) {
@@ -384,8 +348,7 @@
       await _checkPackageReferencesInitFlutterWeb(source);
 
       final watch = Stopwatch()..start();
-      final response =
-          await getCorrectAnalysisServer(source).getFixes(source, offset);
+      final response = await analysisServers.getFixes(source, offset);
       log.info('PERF: Computed fixes in ${watch.elapsedMilliseconds}ms.');
       return response;
     } catch (e, st) {
@@ -400,8 +363,7 @@
       await _checkPackageReferencesInitFlutterWeb(source);
 
       final watch = Stopwatch()..start();
-      final response =
-          await getCorrectAnalysisServer(source).getAssists(source, offset);
+      final response = await analysisServers.getAssists(source, offset);
       log.info('PERF: Computed assists in ${watch.elapsedMilliseconds}ms.');
       return response;
     } catch (e, st) {
@@ -415,8 +377,7 @@
     try {
       final watch = Stopwatch()..start();
 
-      final response =
-          await getCorrectAnalysisServer(source).format(source, offset);
+      final response = await analysisServers.format(source, offset);
       log.info('PERF: Computed format in ${watch.elapsedMilliseconds}ms.');
       return response;
     } catch (e, st) {
@@ -452,13 +413,6 @@
       }
     }
   }
-
-  AnalysisServerWrapper getCorrectAnalysisServer(String source) {
-    final imports = getAllImportsFor(source);
-    return flutterWebManager.usesFlutterWeb(imports)
-        ? flutterAnalysisServer
-        : dartAnalysisServer;
-  }
 }
 
 String _printCompileProblem(CompilationProblem problem) => problem.message;
diff --git a/test/flutter_analysis_server_test.dart b/test/flutter_analysis_server_test.dart
index 198cbc2..ece0438 100644
--- a/test/flutter_analysis_server_test.dart
+++ b/test/flutter_analysis_server_test.dart
@@ -5,7 +5,6 @@
 library services.flutter_analyzer_server_test;
 
 import 'package:dart_services/src/common.dart';
-import 'package:dart_services/src/compiler.dart';
 import 'package:dart_services/src/analysis_server.dart';
 import 'package:dart_services/src/common_server_impl.dart';
 import 'package:dart_services/src/common_server_api.dart';
@@ -232,45 +231,8 @@
     });
   });
 
-  group('Flutter SDK analysis_server with compiler', () {
-    AnalysisServerWrapper analysisServer;
-    FlutterWebManager flutterWebManager;
-    Compiler compiler;
-
-    setUp(() async {
-      await SdkManager.flutterSdk.init();
-      flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
-      await flutterWebManager.warmup();
-
-      compiler =
-          Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
-      await compiler.warmup();
-
-      analysisServer = FlutterAnalysisServerWrapper(flutterWebManager);
-      await analysisServer.init();
-      await analysisServer.warmup();
-    });
-
-    tearDown(() async {
-      await compiler.dispose();
-      await analysisServer.shutdown();
-      await flutterWebManager.dispose();
-    });
-
-    test('analyze counter app', () async {
-      final results = await analysisServer.analyze(counterApp);
-      expect(results.issues, isEmpty);
-    });
-
-    test('analyze Draggable Physics sample', () async {
-      final results = await analysisServer.analyze(draggableAndPhysicsApp);
-      expect(results.issues, isEmpty);
-    });
-  });
-
-  group('Flutter SDK analysis_server with dart analysis_server', () {
-    AnalysisServerWrapper flutterAnalysisServer;
-    AnalysisServerWrapper dartAnalysisServer;
+  group('Flutter SDK analysis_server with analysis servers', () {
+    AnalysisServersWrapper analysisServersWrapper;
     FlutterWebManager flutterWebManager;
 
     setUp(() async {
@@ -278,29 +240,24 @@
       flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
       await flutterWebManager.warmup();
 
-      flutterAnalysisServer = FlutterAnalysisServerWrapper(flutterWebManager);
-      await flutterAnalysisServer.init();
-      await flutterAnalysisServer.warmup();
-
-      dartAnalysisServer = DartAnalysisServerWrapper();
-      await dartAnalysisServer.init();
-      await dartAnalysisServer.warmup();
+      analysisServersWrapper = AnalysisServersWrapper(flutterWebManager);
+      await analysisServersWrapper.init();
+      await analysisServersWrapper.warmup();
     });
 
     tearDown(() async {
-      await flutterAnalysisServer.shutdown();
-      await dartAnalysisServer.shutdown();
+      await analysisServersWrapper.shutdown();
       await flutterWebManager.dispose();
     });
 
     test('analyze counter app', () async {
-      final results = await flutterAnalysisServer.analyze(counterApp);
+      final results = await analysisServersWrapper.analyze(counterApp);
       expect(results.issues, isEmpty);
     });
 
     test('analyze Draggable Physics sample', () async {
       final results =
-          await flutterAnalysisServer.analyze(draggableAndPhysicsApp);
+          await analysisServersWrapper.analyze(draggableAndPhysicsApp);
       expect(results.issues, isEmpty);
     });
   });