Skip to content

Commit 6b4fc26

Browse files
DanTupbkonyi
authored andcommitted
[dds] Switch DAP server mode to directly using stdin/stdout
Change-Id: Id2a8d8c9274b96cf32788e11d4452954a4f9c091 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/205500 Reviewed-by: Ben Konyi <[email protected]>
1 parent 66bd92d commit 6b4fc26

13 files changed

+651
-816
lines changed

pkg/dds/lib/src/dap/adapters/dart_cli.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ class DartCliDebugAdapter extends DartDebugAdapter<DartLaunchRequestArguments> {
5353
enableDds: enableDds,
5454
enableAuthCodes: enableAuthCodes,
5555
logger: logger,
56-
);
56+
) {
57+
channel.closed.then((_) => shutdown());
58+
}
5759

5860
Future<void> debuggerConnected(vm.VM vmInfo) async {
5961
if (!isAttach) {

pkg/dds/lib/src/dap/protocol_stream_transformers.dart

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import 'dart:async';
66
import 'dart:convert';
7-
import 'dart:typed_data';
87

98
class InvalidEncodingError {
109
final String headers;
@@ -107,28 +106,3 @@ class ProtocolHeaders {
107106
final String? encoding;
108107
ProtocolHeaders(this.rawHeaders, this.contentLength, this.encoding);
109108
}
110-
111-
/// Transforms a stream of [Uint8List]s to [List<int>]s. Used because
112-
/// [ServerSocket] and [Socket] use [Uint8List] but stdin and stdout use
113-
/// [List<int>] and the LSP server needs to operate against both.
114-
class Uint8ListTransformer extends StreamTransformerBase<Uint8List, List<int>> {
115-
// TODO(dantup): Is there a built-in (or better) way to do this?
116-
@override
117-
Stream<List<int>> bind(Stream<Uint8List> stream) {
118-
late StreamSubscription<Uint8List> input;
119-
late StreamController<List<int>> _output;
120-
_output = StreamController<List<int>>(
121-
onListen: () {
122-
input = stream.listen(
123-
(uints) => _output.add(uints),
124-
onError: _output.addError,
125-
onDone: _output.close,
126-
);
127-
},
128-
onPause: () => input.pause(),
129-
onResume: () => input.resume(),
130-
onCancel: () => input.cancel(),
131-
);
132-
return _output.stream;
133-
}
134-
}

pkg/dds/lib/src/dap/server.dart

Lines changed: 15 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,92 +3,45 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'dart:async';
6-
import 'dart:io';
76

87
import 'package:dds/src/dap/adapters/dart.dart';
9-
import 'package:pedantic/pedantic.dart';
108

119
import 'adapters/dart_cli.dart';
1210
import 'logging.dart';
1311
import 'protocol_stream.dart';
14-
import 'protocol_stream_transformers.dart';
1512

16-
/// A DAP server that binds to a port and runs in multi-session mode.
13+
/// A DAP server that communicates over a [ByteStreamServerChannel], usually
14+
/// constructed from the processes stdin/stdout streams.
15+
///
16+
/// The server runs in single-user mode and services only a single client. For
17+
/// multiple debug sessions, there would be multiple servers (and the editor
18+
/// would have a client for each of them).
1719
class DapServer {
18-
final ServerSocket _socket;
20+
final ByteStreamServerChannel channel;
21+
late final DartDebugAdapter adapter;
1922
final bool ipv6;
2023
final bool enableDds;
2124
final bool enableAuthCodes;
2225
final Logger? logger;
23-
final _channels = <ByteStreamServerChannel>{};
24-
final _adapters = <DartDebugAdapter>{};
2526

26-
DapServer._(
27-
this._socket, {
27+
DapServer(
28+
Stream<List<int>> _input,
29+
StreamSink<List<int>> _output, {
2830
this.ipv6 = false,
2931
this.enableDds = true,
3032
this.enableAuthCodes = true,
3133
this.logger,
32-
}) {
33-
_socket.listen(_acceptConnection);
34-
}
35-
36-
String get host => _socket.address.host;
37-
int get port => _socket.port;
38-
39-
Future<void> stop() async {
40-
_channels.forEach((client) => client.close());
41-
await _socket.close();
42-
}
43-
44-
void _acceptConnection(Socket client) {
45-
final address = client.remoteAddress;
46-
logger?.call('Accepted connection from $address');
47-
client.done.then((_) {
48-
logger?.call('Connection from $address closed');
49-
});
50-
_createAdapter(client.transform(Uint8ListTransformer()), client);
51-
}
52-
53-
void _createAdapter(Stream<List<int>> _input, StreamSink<List<int>> _output) {
54-
// TODO(dantup): This is hard-coded to DartCliDebugAdapter but will
55-
// ultimately need to support having a factory passed in to support
56-
// tests and/or being used in flutter_tools.
57-
final channel = ByteStreamServerChannel(_input, _output, logger);
58-
final adapter = DartCliDebugAdapter(
34+
}) : channel = ByteStreamServerChannel(_input, _output, logger) {
35+
adapter = DartCliDebugAdapter(
5936
channel,
6037
ipv6: ipv6,
6138
enableDds: enableDds,
6239
enableAuthCodes: enableAuthCodes,
6340
logger: logger,
6441
);
65-
_channels.add(channel);
66-
_adapters.add(adapter);
67-
unawaited(channel.closed.then((_) {
68-
_channels.remove(channel);
69-
_adapters.remove(adapter);
70-
adapter.shutdown();
71-
}));
7242
}
7343

74-
/// Starts a DAP Server listening on [host]:[port].
75-
static Future<DapServer> create({
76-
String? host,
77-
int port = 0,
78-
bool ipv6 = false,
79-
bool enableDdds = true,
80-
bool enableAuthCodes = true,
81-
Logger? logger,
82-
}) async {
83-
final hostFallback =
84-
ipv6 ? InternetAddress.loopbackIPv6 : InternetAddress.loopbackIPv4;
85-
final _socket = await ServerSocket.bind(host ?? hostFallback, port);
86-
return DapServer._(
87-
_socket,
88-
ipv6: ipv6,
89-
enableDds: enableDdds,
90-
enableAuthCodes: enableAuthCodes,
91-
logger: logger,
92-
);
44+
void stop() {
45+
channel.close();
9346
}
9447
}

0 commit comments

Comments
 (0)