| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file |
| // 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. |
| |
| import 'dart:async'; |
| |
| import 'package:analysis_server_client/handler/notification_handler.dart'; |
| import 'package:analysis_server_client/protocol.dart'; |
| import 'package:analysis_server_client/server.dart'; |
| import 'package:pub_semver/pub_semver.dart'; |
| |
| /// [ConnectionHandler] listens to analysis server notifications |
| /// and detects when a connection has been established with the server. |
| /// |
| /// Clients may override [onFailedToConnect], [onProtocolNotSupported], |
| /// and [onServerError] to display connection failure information. |
| /// |
| /// Clients may mix-in this class, but may not extend or implement it. |
| mixin ConnectionHandler implements NotificationHandler { |
| final Completer<bool> _connected = Completer(); |
| |
| /// Clients should implement this method to return the server being managed. |
| /// This mixin will stop the server process if a connection cannot be |
| /// established or if a server error occurs after connecting. |
| Server get server; |
| |
| /// Return `true` if the server's protocol is compatible. |
| bool checkServerProtocolVersion(Version version) { |
| final minVersion = Version.parse(PROTOCOL_VERSION); |
| final maxVersion = minVersion.nextBreaking; |
| return minVersion <= version && version < maxVersion; |
| } |
| |
| void onFailedToConnect() {} |
| |
| void onProtocolNotSupported(Version version) {} |
| |
| @override |
| void onServerConnected(ServerConnectedParams params) { |
| var version = Version.parse(params.version); |
| if (checkServerProtocolVersion(version)) { |
| _connected.complete(true); |
| } else { |
| onProtocolNotSupported(version); |
| _connected.complete(false); |
| server.stop(); |
| } |
| } |
| |
| @override |
| void onServerError(ServerErrorParams params) { |
| server.stop(); |
| } |
| |
| /// Return a future that completes with a `bool` indicating whether |
| /// a connection was successfully established with the server. |
| Future<bool> serverConnected({Duration? timeLimit}) { |
| var future = _connected.future; |
| if (timeLimit != null) { |
| future = future.timeout(timeLimit, onTimeout: () { |
| onFailedToConnect(); |
| server.stop(); |
| return false; |
| }); |
| } |
| return future; |
| } |
| } |