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].