blob: f754fb588cc95af7d99da09d1d8579969e8b641b [file] [log] [blame]
// 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;
}
}