| Index: pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
|
| diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
|
| index bcb86ccb7c48ddc0cbddcd83f0842c8456e14f9e..a77e23e15deb5fcf7efdf0d11171a4f004bd4a8c 100644
|
| --- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
|
| +++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
|
| @@ -247,3 +247,107 @@ class ByteStreamServerChannel implements ServerCommunicationChannel {
|
| onRequest(request);
|
| }
|
| }
|
| +
|
| +/**
|
| + * Instances of the class [PrintServerChannel] implement a
|
| + * [ServerCommunicationChannel] that uses standard input and [print]
|
| + * to communicate with clients.
|
| + */
|
| +class PrintServerChannel implements ServerCommunicationChannel {
|
| + /**
|
| + * The instrumentation service that is to be used by this analysis server.
|
| + */
|
| + final InstrumentationService instrumentationService;
|
| +
|
| + /**
|
| + * Completer that will be signalled when the input stream is closed.
|
| + */
|
| + final Completer _closed = new Completer();
|
| +
|
| + /**
|
| + * True if [close] has been called.
|
| + */
|
| + bool _closeRequested = false;
|
| +
|
| + PrintServerChannel(this.instrumentationService);
|
| +
|
| + /**
|
| + * Future that will be completed when the input stream is closed.
|
| + */
|
| + Future get closed {
|
| + return _closed.future;
|
| + }
|
| +
|
| + @override
|
| + void close() {
|
| + if (!_closeRequested) {
|
| + _closeRequested = true;
|
| + assert(!_closed.isCompleted);
|
| + _closed.complete();
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void listen(void onRequest(Request request), {Function onError, void
|
| + onDone()}) {
|
| + stdin.transform(
|
| + (new Utf8Codec()).decoder).transform(
|
| + new LineSplitter()).listen(
|
| + (String data) => _readRequest(data, onRequest),
|
| + onError: onError,
|
| + onDone: () {
|
| + close();
|
| + onDone();
|
| + });
|
| + }
|
| +
|
| + @override
|
| + void sendNotification(Notification notification) {
|
| + // Don't send any further notifications after the communication channel is
|
| + // closed.
|
| + if (_closeRequested) {
|
| + return;
|
| + }
|
| + ServerCommunicationChannel.ToJson.start();
|
| + String jsonEncoding = JSON.encode(notification.toJson());
|
| + ServerCommunicationChannel.ToJson.stop();
|
| + print(jsonEncoding);
|
| + instrumentationService.logNotification(jsonEncoding);
|
| + }
|
| +
|
| + @override
|
| + void sendResponse(Response response) {
|
| + // Don't send any further responses after the communication channel is
|
| + // closed.
|
| + if (_closeRequested) {
|
| + return;
|
| + }
|
| + ServerCommunicationChannel.ToJson.start();
|
| + String jsonEncoding = JSON.encode(response.toJson());
|
| + ServerCommunicationChannel.ToJson.stop();
|
| + print(jsonEncoding);
|
| + instrumentationService.logResponse(jsonEncoding);
|
| + }
|
| +
|
| + /**
|
| + * Read a request from the given [data] and use the given function to handle
|
| + * the request.
|
| + */
|
| + void _readRequest(Object data, void onRequest(Request request)) {
|
| + // Ignore any further requests after the communication channel is closed.
|
| + if (_closed.isCompleted) {
|
| + return;
|
| + }
|
| + instrumentationService.logRequest(data);
|
| + // Parse the string as a JSON descriptor and process the resulting
|
| + // structure as a request.
|
| + ServerCommunicationChannel.FromJson.start();
|
| + Request request = new Request.fromString(data);
|
| + ServerCommunicationChannel.FromJson.stop();
|
| + if (request == null) {
|
| + sendResponse(new Response.invalidRequestFormat());
|
| + return;
|
| + }
|
| + onRequest(request);
|
| + }
|
| +}
|
|
|