Add Dart 3 class modifiers to dart:io.
Change-Id: Ia6eda18bb4ad6ae9f2705846e262f793f73d1e4f
Tested: class type changes
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291343
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Brian Quinlan <bquinlan@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8ff147..b264b28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -194,6 +194,7 @@
#### `dart:io`
+- Added `name` and `signalNumber` to the `ProcessSignal` class.
- Deprecate `NetworkInterface.listSupported`. Has always returned true since
Dart 2.3.
- Finalize `httpEnableTimelineLogging` parameter name transition from `enable`
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.aot.expect b/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.aot.expect
index 19346aa..8c02f3c 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.aot.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.aot.expect
@@ -43,5 +43,5 @@
constants {
#C1 = 2
#C2 = "SIGINT"
- #C3 = io::ProcessSignal {_signalNumber:#C1, _name:#C2}
+ #C3 = io::ProcessSignal {signalNumber:#C1, name:#C2}
}
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.expect
index 80ce934..db14eee 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_member.dart.expect
@@ -44,5 +44,5 @@
constants {
#C1 = 2
#C2 = "SIGINT"
- #C3 = io::ProcessSignal {_signalNumber:#C1, _name:#C2}
+ #C3 = io::ProcessSignal {signalNumber:#C1, name:#C2}
}
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index b559ea4..9f0dfb0 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -320,7 +320,7 @@
/// as the standard allows. In most cases a name holds only a single value,
/// The most common mode of operation is to use `set()` for setting a value,
/// and `value()` for retrieving a value.
-abstract class HttpHeaders {
+abstract interface class HttpHeaders {
static const acceptHeader = "accept";
static const acceptCharsetHeader = "accept-charset";
static const acceptEncodingHeader = "accept-encoding";
@@ -603,7 +603,7 @@
/// });
///
/// An instance of [HeaderValue] is immutable.
-abstract class HeaderValue {
+abstract interface class HeaderValue {
/// Creates a new header value object setting the value and parameters.
factory HeaderValue(
[String value = "", Map<String, String?> parameters = const {}]) {
@@ -638,7 +638,7 @@
}
/// The [session][HttpRequest.session] of an [HttpRequest].
-abstract class HttpSession implements Map {
+abstract interface class HttpSession implements Map {
/// The id of the current session.
String get id;
@@ -661,7 +661,7 @@
/// [HttpHeaders.contentTypeHeader] header.
///
/// A [ContentType] is immutable.
-abstract class ContentType implements HeaderValue {
+abstract interface class ContentType implements HeaderValue {
/// Content type for plain text using UTF-8 encoding.
///
/// text/plain; charset=utf-8
@@ -739,7 +739,7 @@
/// header values only [name] and [value] properties will be set. When building a
/// cookie for the 'set-cookie' header in the server and when receiving cookies
/// in the client as 'set-cookie' headers all fields can be used.
-abstract class Cookie {
+abstract interface class Cookie {
/// The name of the cookie.
///
/// Must be a `token` as specified in RFC 6265.
@@ -844,7 +844,7 @@
/// res.write('Received request ${req.method}: ${req.uri.path}');
/// res.close();
/// }
-abstract class HttpRequest implements Stream<Uint8List> {
+abstract interface class HttpRequest implements Stream<Uint8List> {
/// The content length of the request body.
///
/// If the size of the request body is not known in advance,
@@ -966,7 +966,7 @@
///
/// An exception is thrown if you use the `write()` method
/// while an unsupported content-type is set.
-abstract class HttpResponse implements IOSink {
+abstract interface class HttpResponse implements IOSink {
// TODO(ajohnsen): Add documentation of how to pipe a file to the response.
/// Gets and sets the content length of the response. If the size of
/// the response is not known in advance set the content length to
@@ -1149,7 +1149,7 @@
///
/// HttpClient client = HttpClient();
/// client.findProxy = null;
-abstract class HttpClient {
+abstract interface class HttpClient {
static const int defaultHttpPort = 80;
static const int defaultHttpsPort = 443;
@@ -1632,7 +1632,7 @@
///
/// An exception is thrown if you use an unsupported encoding and the
/// `write()` method being used takes a string parameter.
-abstract class HttpClientRequest implements IOSink {
+abstract interface class HttpClientRequest implements IOSink {
/// The requested persistent connection state.
///
/// The default value is `true`.
@@ -1789,7 +1789,7 @@
/// client.close();
/// }
/// ```
-abstract class HttpClientResponse implements Stream<List<int>> {
+abstract interface class HttpClientResponse implements Stream<List<int>> {
/// Returns the status code.
///
/// The status code must be set before the body is written
@@ -1924,10 +1924,11 @@
compressed,
}
-abstract class HttpClientCredentials {}
+abstract interface class HttpClientCredentials {}
/// Represents credentials for basic authentication.
-abstract class HttpClientBasicCredentials extends HttpClientCredentials {
+abstract final class HttpClientBasicCredentials
+ implements HttpClientCredentials {
factory HttpClientBasicCredentials(String username, String password) =>
_HttpClientBasicCredentials(username, password);
}
@@ -1936,21 +1937,22 @@
/// authentication is only supported for servers using the MD5
/// algorithm and quality of protection (qop) of either "none" or
/// "auth".
-abstract class HttpClientDigestCredentials extends HttpClientCredentials {
+abstract final class HttpClientDigestCredentials
+ implements HttpClientCredentials {
factory HttpClientDigestCredentials(String username, String password) =>
_HttpClientDigestCredentials(username, password);
}
/// Information about an [HttpRequest], [HttpResponse], [HttpClientRequest], or
/// [HttpClientResponse] connection.
-abstract class HttpConnectionInfo {
+abstract interface class HttpConnectionInfo {
InternetAddress get remoteAddress;
int get remotePort;
int get localPort;
}
/// Redirect information.
-abstract class RedirectInfo {
+abstract interface class RedirectInfo {
/// Returns the status code used for the redirect.
int get statusCode;
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 829d88f..2ed74d0 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -4,7 +4,7 @@
part of dart._http;
-abstract class HttpProfiler {
+final class HttpProfiler {
static const _kType = 'HttpProfile';
static final Map<String, _HttpProfileData> _profile = {};
@@ -3156,7 +3156,8 @@
// Common interface of [ServerSocket] and [SecureServerSocket] used by
// [_HttpServer].
-abstract class ServerSocketBase<T extends Socket> implements Stream<T> {
+abstract interface class ServerSocketBase<T extends Socket>
+ implements Stream<T> {
int get port;
InternetAddress get address;
Future<void> close();
@@ -3671,7 +3672,7 @@
void authorizeProxy(_ProxyCredentials credentials, HttpClientRequest request);
}
-class _HttpClientBasicCredentials extends _HttpClientCredentials
+final class _HttpClientBasicCredentials extends _HttpClientCredentials
implements HttpClientBasicCredentials {
String username;
String password;
@@ -3700,7 +3701,7 @@
}
}
-class _HttpClientDigestCredentials extends _HttpClientCredentials
+final class _HttpClientDigestCredentials extends _HttpClientCredentials
implements HttpClientDigestCredentials {
String username;
String password;
diff --git a/sdk/lib/_internal/vm/bin/process_patch.dart b/sdk/lib/_internal/vm/bin/process_patch.dart
index 196a44f..b8eac20 100644
--- a/sdk/lib/_internal/vm/bin/process_patch.dart
+++ b/sdk/lib/_internal/vm/bin/process_patch.dart
@@ -80,7 +80,7 @@
static bool killPid(int pid, [ProcessSignal signal = ProcessSignal.sigterm]) {
// TODO(40614): Remove once non-nullability is sound.
ArgumentError.checkNotNull(signal, "signal");
- return _ProcessUtils._killPid(pid, signal._signalNumber);
+ return _ProcessUtils._killPid(pid, signal.signalNumber);
}
}
@@ -101,7 +101,7 @@
Stream<ProcessSignal> get stream => _controller.stream;
void _listen() {
- var id = _setSignalHandler(signal._signalNumber);
+ var id = _setSignalHandler(signal.signalNumber);
if (id is! int) {
_controller
.addError(new SignalException("Failed to listen for $signal", id));
@@ -121,7 +121,7 @@
void _cancel() {
if (_id != null) {
- _clearSignalHandler(signal._signalNumber);
+ _clearSignalHandler(signal.signalNumber);
_id = null;
}
}
@@ -170,10 +170,10 @@
}
static Stream<ProcessSignal> _watchSignalInternal(ProcessSignal signal) {
- if (_signalControllers[signal._signalNumber] == null) {
- _signalControllers[signal._signalNumber] = new _SignalController(signal);
+ if (_signalControllers[signal.signalNumber] == null) {
+ _signalControllers[signal.signalNumber] = new _SignalController(signal);
}
- return _signalControllers[signal._signalNumber]!.stream;
+ return _signalControllers[signal.signalNumber]!.stream;
}
}
@@ -541,7 +541,7 @@
ArgumentError.checkNotNull(kill, "kill");
assert(_started);
if (_ended) return false;
- return _ProcessUtils._killPid(pid, signal._signalNumber);
+ return _ProcessUtils._killPid(pid, signal.signalNumber);
}
int get pid => _ProcessUtils._pid(this);
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 4af7273..360212ff 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -97,7 +97,7 @@
/// a tutorial about writing command-line apps, includes information about
/// files and directories.
@pragma("vm:entry-point")
-abstract class Directory implements FileSystemEntity {
+abstract interface class Directory implements FileSystemEntity {
/// Gets the path of this directory.
String get path;
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index cdce9e4..37ba78f 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -181,7 +181,7 @@
/// a tutorial about writing command-line apps, includes information about
/// files and directories.
@pragma("vm:entry-point")
-abstract class File implements FileSystemEntity {
+abstract interface class File implements FileSystemEntity {
/// Creates a [File] object.
///
/// If [path] is a relative path, it will be interpreted relative to the
@@ -593,7 +593,7 @@
///
/// If an asynchronous method is pending, it is also not possible to call any
/// synchronous methods. This will also throw a [FileSystemException].
-abstract class RandomAccessFile {
+abstract interface class RandomAccessFile {
/// Closes the file.
///
/// Returns a [Future] that completes when it has been closed.
@@ -1011,7 +1011,7 @@
/// print(data);
/// }, onDone: () => print('Done'));
/// ```
-abstract class ReadPipe implements Stream<List<int>> {}
+abstract interface class ReadPipe implements Stream<List<int>> {}
/// The "write" end of an [Pipe] created by [Pipe.create].
///
@@ -1020,7 +1020,7 @@
/// pipe.write.add("Hello World!".codeUnits);
/// pipe.write.close();
/// ```
-abstract class WritePipe implements IOSink {}
+abstract interface class WritePipe implements IOSink {}
/// An anonymous pipe that can be used to send data in a single direction i.e.
/// data written to [write] can be read using [read].
@@ -1040,7 +1040,7 @@
/// pipe.write.add('Hello over pipe!'.codeUnits);
/// pipe.write.close();
/// ```
-abstract class Pipe {
+abstract interface class Pipe {
/// The read end of the [Pipe].
ReadPipe get read;
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index c4887f4..8b7e977 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -15,7 +15,7 @@
/// to add or write to the [IOSink] will fail until the [addStream] completes.
///
/// It is an error to add data to the [IOSink] after the sink is closed.
-abstract class IOSink implements StreamSink<List<int>>, StringSink {
+abstract interface class IOSink implements StreamSink<List<int>>, StringSink {
/// Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes.
///
/// Text written to [StreamSink] methods is encoded to bytes using [encoding]
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 477a3de..203446c 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -6,7 +6,7 @@
/// References to filesystem links.
@pragma("vm:entry-point")
-abstract class Link implements FileSystemEntity {
+abstract interface class Link implements FileSystemEntity {
/// Creates a Link object.
@pragma("vm:entry-point")
factory Link(String path) {
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index fa86457..4639548 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -58,7 +58,7 @@
/// }
/// }
/// ```
-class Platform {
+abstract final class Platform {
static final _numberOfProcessors = _Platform.numberOfProcessors;
@pragma("vm:platform-const")
static final _pathSeparator = _Platform.pathSeparator;
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 7480c83..2f7f131 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -107,7 +107,7 @@
int get pid => _ProcessUtils._pid(null);
/// Methods for retrieving information about the current process.
-class ProcessInfo {
+abstract final class ProcessInfo {
/// The current resident set size of memory for the process.
///
/// Note that the meaning of this field is platform dependent. For example,
@@ -127,7 +127,7 @@
}
/// Modes for running a new process.
-class ProcessStartMode {
+final class ProcessStartMode {
/// Normal child process.
static const normal = const ProcessStartMode._internal(0);
@@ -254,7 +254,7 @@
/// print('exit code: $exitCode');
/// }
/// ```
-abstract class Process {
+abstract interface class Process {
/// A `Future` which completes with the exit code of the process
/// when the process completes.
///
@@ -511,7 +511,7 @@
/// The result of running a non-interactive
/// process started with [Process.run] or [Process.runSync].
-class ProcessResult {
+final class ProcessResult {
/// Exit code for the process.
///
/// See [Process.exitCode] for more information in the exit code
@@ -542,7 +542,7 @@
/// Some [ProcessSignal]s can also be watched, as a way to intercept the default
/// signal handler and implement another. See [ProcessSignal.watch] for more
/// information.
-class ProcessSignal {
+interface class ProcessSignal {
static const ProcessSignal sighup = const ProcessSignal._(1, "SIGHUP");
static const ProcessSignal sigint = const ProcessSignal._(2, "SIGINT");
static const ProcessSignal sigquit = const ProcessSignal._(3, "SIGQUIT");
@@ -573,12 +573,17 @@
static const ProcessSignal sigpoll = const ProcessSignal._(29, "SIGPOLL");
static const ProcessSignal sigsys = const ProcessSignal._(31, "SIGSYS");
- final int _signalNumber;
- final String _name;
+ /// The numeric constant for the signal e.g. [ProcessSignal.signalNumber]
+ /// will be 1 for [ProcessSignal.sighup] on most platforms.
+ final int signalNumber;
- const ProcessSignal._(this._signalNumber, this._name);
+ /// The POSIX-standardized name of the signal e.g. [ProcessSignal.name] will
+ /// be "SIGHUP" for [ProcessSignal.sighup].
+ final String name;
- String toString() => _name;
+ const ProcessSignal._(this.signalNumber, this.name);
+
+ String toString() => name;
/// Watch for process signals.
///
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 585c04b..11fae3b 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -7,7 +7,7 @@
/// A TCP socket using TLS and SSL.
///
/// A secure socket may be used as either a [Stream] or an [IOSink].
-abstract class SecureSocket implements Socket {
+abstract interface class SecureSocket implements Socket {
external factory SecureSocket._(RawSecureSocket rawSocket);
/// Constructs a new secure client socket and connects it to the given
@@ -227,7 +227,7 @@
/// using the trusted certificates set in the [SecurityContext] object.
/// The default [SecurityContext] object contains a built-in set of trusted
/// root certificates for well-known certificate authorities.
-abstract class RawSecureSocket implements RawSocket {
+abstract interface class RawSecureSocket implements RawSocket {
/// Constructs a new secure client socket and connect it to the given
/// host on the given port.
///
@@ -446,7 +446,7 @@
/// X509Certificate represents an SSL certificate, with accessors to
/// get the fields of the certificate.
@pragma("vm:entry-point")
-abstract class X509Certificate {
+abstract interface class X509Certificate {
@pragma("vm:entry-point")
external factory X509Certificate._();
@@ -480,7 +480,7 @@
// Interface used by [RawSecureServerSocket] and [_RawSecureSocket] that exposes
// members of [_NativeSocket].
-abstract class _RawSocketBase {
+abstract interface class _RawSocketBase {
bool get _closedReadEventSent;
void set _owner(owner);
}
diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart
index 5571aba..571b32c 100644
--- a/sdk/lib/io/security_context.dart
+++ b/sdk/lib/io/security_context.dart
@@ -17,7 +17,7 @@
/// iOS note: Some methods to add, remove, and inspect certificates are not yet
/// implemented. However, the platform's built-in trusted certificates can
/// be used, by way of [SecurityContext.defaultContext].
-abstract class SecurityContext {
+abstract interface class SecurityContext {
/// Creates a new [SecurityContext].
///
/// By default, the created [SecurityContext] contains no keys or certificates.
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 90387bb..d8fb990 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -9,7 +9,7 @@
/// Currently, IP version 4 (IPv4), IP version 6 (IPv6)
/// and Unix domain address are supported.
/// Unix domain sockets are available only on Linux, MacOS and Android.
-class InternetAddressType {
+final class InternetAddressType {
static const InternetAddressType IPv4 = const InternetAddressType._(0);
static const InternetAddressType IPv6 = const InternetAddressType._(1);
@Since("2.8")
@@ -41,7 +41,7 @@
/// An Internet address combined with a port number represents an
/// endpoint to which a socket can connect or a listening socket can
/// bind.
-abstract class InternetAddress {
+abstract interface class InternetAddress {
/// IP version 4 loopback address.
///
/// Use this address when listening on or connecting
@@ -165,7 +165,7 @@
/// A [NetworkInterface] represents an active network interface on the current
/// system. It contains a list of [InternetAddress]es that are bound to the
/// interface.
-abstract class NetworkInterface {
+abstract interface class NetworkInterface {
/// The name of the [NetworkInterface].
String get name;
@@ -206,7 +206,7 @@
/// one for each connection made to the listening socket.
///
/// See [RawSocket] for more info.
-abstract class RawServerSocket implements Stream<RawSocket> {
+abstract interface class RawServerSocket implements Stream<RawSocket> {
/// Listens on a given address and port.
///
/// When the returned future completes the server socket is bound
@@ -265,7 +265,7 @@
/// one for each connection made to the listening socket.
///
/// See [Socket] for more info.
-abstract class ServerSocket implements ServerSocketBase<Socket> {
+abstract interface class ServerSocket implements ServerSocketBase<Socket> {
/// Listens on a given address and port.
///
/// When the returned future completes the server socket is bound
@@ -331,7 +331,7 @@
/// The [SocketDirection] is used as a parameter to [Socket.close] and
/// [RawSocket.close] to close a socket in the specified direction(s).
-class SocketDirection {
+final class SocketDirection {
static const SocketDirection receive = const SocketDirection._(0);
static const SocketDirection send = const SocketDirection._(1);
static const SocketDirection both = const SocketDirection._(2);
@@ -346,7 +346,7 @@
/// The [SocketOption] is used as a parameter to [Socket.setOption] and
/// [RawSocket.setOption] to customize the behaviour of the underlying
/// socket.
-class SocketOption {
+final class SocketOption {
/// Enable or disable no-delay on the socket. If tcpNoDelay is enabled, the
/// socket will not buffer data internally, but instead write each data chunk
/// as an individual TCP packet.
@@ -383,7 +383,7 @@
/// will be passed to the underlying platform's implementation of setsockopt and
/// getsockopt.
@Since("2.2")
-class RawSocketOption {
+final class RawSocketOption {
/// Creates a [RawSocketOption] for [RawSocket.getRawOption]
/// and [RawSocket.setRawOption].
///
@@ -499,7 +499,7 @@
///
/// Returned by the `startConnect` methods on client-side socket types `S`,
/// `ConnectionTask<S>` allows cancelling an attempt to connect to a host.
-class ConnectionTask<S> {
+final class ConnectionTask<S> {
/// A `Future` that completes with value that `S.connect()` would return
/// unless [cancel] is called on this [ConnectionTask].
///
@@ -531,7 +531,7 @@
/// a certain change has happened, for example when data has become available
/// ([RawSocketEvent.read]) or when the remote end has stopped listening
/// ([RawSocketEvent.closed]).
-abstract class RawSocket implements Stream<RawSocketEvent> {
+abstract interface class RawSocket implements Stream<RawSocketEvent> {
/// Set or get, if the [RawSocket] should listen for [RawSocketEvent.read]
/// events. Default is `true`.
abstract bool readEventsEnabled;
@@ -719,7 +719,7 @@
/// Data, as [Uint8List]s, is received by the local socket, made available
/// by the [Stream] interface of this class, and can be sent to the remote
/// socket through the [IOSink] interface of this class.
-abstract class Socket implements Stream<Uint8List>, IOSink {
+abstract interface class Socket implements Stream<Uint8List>, IOSink {
/// Creates a new socket connection to the host and port and returns a [Future]
/// that will complete with either a [Socket] once connected or an error
/// if the host-lookup or connection failed.
@@ -843,7 +843,7 @@
}
/// A data packet received by a [RawDatagramSocket].
-class Datagram {
+final class Datagram {
/// The actual bytes of the message.
Uint8List data;
@@ -858,7 +858,7 @@
/// A wrapper around OS resource handle so it can be passed via Socket
/// as part of [SocketMessage].
-abstract class ResourceHandle {
+abstract interface class ResourceHandle {
/// Creates wrapper around opened file.
external factory ResourceHandle.fromFile(RandomAccessFile file);
@@ -960,7 +960,7 @@
/// Control messages could carry different information including
/// [ResourceHandle]. If [ResourceHandle]s are available as part of this message,
/// they can be extracted via [extractHandles].
-abstract class SocketControlMessage {
+abstract interface class SocketControlMessage {
/// Creates a control message containing the provided [handles].
///
/// This is used by the sender when it sends handles across the socket.
@@ -1008,7 +1008,7 @@
/// A socket message received by a [RawDatagramSocket].
///
/// A socket message consists of [data] bytes and [controlMessages].
-class SocketMessage {
+final class SocketMessage {
/// The actual bytes of the message.
final Uint8List data;
@@ -1066,7 +1066,7 @@
/// });
/// }
/// ```
-abstract class RawDatagramSocket extends Stream<RawSocketEvent> {
+abstract interface class RawDatagramSocket extends Stream<RawSocketEvent> {
/// Whether the [RawDatagramSocket] should listen for
/// [RawSocketEvent.read] events.
///
diff --git a/sdk/lib/io/sync_socket.dart b/sdk/lib/io/sync_socket.dart
index 8df113a..4914c34 100644
--- a/sdk/lib/io/sync_socket.dart
+++ b/sdk/lib/io/sync_socket.dart
@@ -13,7 +13,7 @@
/// suitable for applications that require high performance or asynchronous I/O
/// such as a server. Instead such applications should use the non-blocking
/// sockets and asynchronous operations in the [Socket] or [RawSocket] classes.
-abstract class RawSynchronousSocket {
+abstract interface class RawSynchronousSocket {
/// Creates a new socket connection and returns a [RawSynchronousSocket].
///
/// The [host] can either be a [String] or an [InternetAddress].