Migrate to null safety (dart-lang/json_rpc_2#72)
diff --git a/pkgs/json_rpc_2/.github/workflows/test-package.yml b/pkgs/json_rpc_2/.github/workflows/test-package.yml
index 2792265..21a3c50 100644
--- a/pkgs/json_rpc_2/.github/workflows/test-package.yml
+++ b/pkgs/json_rpc_2/.github/workflows/test-package.yml
@@ -59,27 +59,3 @@
- name: Run VM tests
run: dart test --platform vm
if: always() && steps.install.outcome == 'success'
-
- # Run tests on a matrix consisting of two dimensions:
- # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
- # 2. release: 2.2.0
- test-legacy-sdk:
- needs: analyze
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- # Add macos-latest and/or windows-latest if relevant for this package.
- os: [ubuntu-latest]
- sdk: [2.2.0]
- steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v0.3
- with:
- sdk: ${{ matrix.sdk }}
- - id: install
- name: Install dependencies
- run: pub get
- - name: Run VM tests
- run: pub run test --platform vm
- if: always() && steps.install.outcome == 'success'
diff --git a/pkgs/json_rpc_2/CHANGELOG.md b/pkgs/json_rpc_2/CHANGELOG.md
index f27cacb..126ba00 100644
--- a/pkgs/json_rpc_2/CHANGELOG.md
+++ b/pkgs/json_rpc_2/CHANGELOG.md
@@ -1,5 +1,6 @@
-## 2.2.3-dev (unreleased)
+## 3.0.0-dev
+* Migrate to null safety.
* Accept responses even if the server converts the ID to a String.
## 2.2.2
diff --git a/pkgs/json_rpc_2/lib/error_code.dart b/pkgs/json_rpc_2/lib/error_code.dart
index 4bb0808..f4ca462 100644
--- a/pkgs/json_rpc_2/lib/error_code.dart
+++ b/pkgs/json_rpc_2/lib/error_code.dart
@@ -37,7 +37,7 @@
/// JSON-RPC 2.0 spec.
///
/// If [errorCode] isn't defined in the JSON-RPC 2.0 spec, returns null.
-String name(int errorCode) {
+String? name(int errorCode) {
switch (errorCode) {
case PARSE_ERROR:
return 'parse error';
diff --git a/pkgs/json_rpc_2/lib/src/client.dart b/pkgs/json_rpc_2/lib/src/client.dart
index ccc4c39..7e040cc 100644
--- a/pkgs/json_rpc_2/lib/src/client.dart
+++ b/pkgs/json_rpc_2/lib/src/client.dart
@@ -24,7 +24,7 @@
/// The current batch of requests to be sent together.
///
/// Each element is a JSON RPC spec compliant message.
- List<Map<String, dynamic>> _batch;
+ List<Map<String, dynamic>>? _batch;
/// The map of request ids to pending requests.
final _pendingRequests = <int, _Request>{};
@@ -141,7 +141,7 @@
///
/// Sends a request to invoke [method] with [parameters]. If [id] is given,
/// the request uses that id.
- void _send(String method, parameters, [int id]) {
+ void _send(String method, parameters, [int? id]) {
if (parameters is Iterable) parameters = parameters.toList();
if (parameters is! Map && parameters is! List && parameters != null) {
throw ArgumentError('Only maps and lists may be used as JSON-RPC '
@@ -154,7 +154,7 @@
if (parameters != null) message['params'] = parameters;
if (_batch != null) {
- _batch.add(message);
+ _batch!.add(message);
} else {
_channel.sink.add(message);
}
@@ -197,7 +197,7 @@
if (!_isResponseValid(response)) return;
var id = response['id'];
id = (id is String) ? int.parse(id) : id;
- var request = _pendingRequests.remove(id);
+ var request = _pendingRequests.remove(id)!;
if (response.containsKey('result')) {
request.completer.complete(response['result']);
} else {
diff --git a/pkgs/json_rpc_2/lib/src/peer.dart b/pkgs/json_rpc_2/lib/src/peer.dart
index 4cf6aae..a11cff2 100644
--- a/pkgs/json_rpc_2/lib/src/peer.dart
+++ b/pkgs/json_rpc_2/lib/src/peer.dart
@@ -21,11 +21,11 @@
/// The underlying client that handles request-sending and response-receiving
/// logic.
- Client _client;
+ late final Client _client;
/// The underlying server that handles request-receiving and response-sending
/// logic.
- Server _server;
+ late final Server _server;
/// A stream controller that forwards incoming messages to [_server] if
/// they're requests.
@@ -35,14 +35,14 @@
/// they're responses.
final _clientIncomingForwarder = StreamController(sync: true);
- Future<void> _done;
@override
- Future get done => _done ??= Future.wait([_client.done, _server.done]);
+ late final Future done = Future.wait([_client.done, _server.done]);
+
@override
bool get isClosed => _client.isClosed || _server.isClosed;
@override
- ErrorCallback get onUnhandledError => _server?.onUnhandledError;
+ ErrorCallback? get onUnhandledError => _server.onUnhandledError;
@override
bool get strictProtocolChecks => _server.strictProtocolChecks;
@@ -60,7 +60,7 @@
/// specification. In particular, requests missing the `jsonrpc` parameter
/// will be accepted.
Peer(StreamChannel<String> channel,
- {ErrorCallback onUnhandledError, bool strictProtocolChecks = true})
+ {ErrorCallback? onUnhandledError, bool strictProtocolChecks = true})
: this.withoutJson(
jsonDocument.bind(channel).transform(respondToFormatExceptions),
onUnhandledError: onUnhandledError,
@@ -82,7 +82,7 @@
/// specification. In particular, requests missing the `jsonrpc` parameter
/// will be accepted.
Peer.withoutJson(this._channel,
- {ErrorCallback onUnhandledError, bool strictProtocolChecks = true}) {
+ {ErrorCallback? onUnhandledError, bool strictProtocolChecks = true}) {
_server = Server.withoutJson(
StreamChannel(_serverIncomingForwarder.stream, _channel.sink),
onUnhandledError: onUnhandledError,
diff --git a/pkgs/json_rpc_2/lib/src/server.dart b/pkgs/json_rpc_2/lib/src/server.dart
index 553b67b..a2b4dc1 100644
--- a/pkgs/json_rpc_2/lib/src/server.dart
+++ b/pkgs/json_rpc_2/lib/src/server.dart
@@ -60,7 +60,7 @@
/// In the case where a user provided callback results in an exception that
/// cannot be properly routed back to the client, this handler will be
/// invoked. If it is not set, the exception will be swallowed.
- final ErrorCallback onUnhandledError;
+ final ErrorCallback? onUnhandledError;
/// Whether to strictly enforce the JSON-RPC 2.0 specification for received
/// messages.
@@ -82,7 +82,7 @@
/// requests which are not conformant with the JSON-RPC 2.0 specification. In
/// particular, requests missing the `jsonrpc` parameter will be accepted.
Server(StreamChannel<String> channel,
- {ErrorCallback onUnhandledError, bool strictProtocolChecks = true})
+ {ErrorCallback? onUnhandledError, bool strictProtocolChecks = true})
: this.withoutJson(
jsonDocument.bind(channel).transform(respondToFormatExceptions),
onUnhandledError: onUnhandledError,
diff --git a/pkgs/json_rpc_2/lib/src/utils.dart b/pkgs/json_rpc_2/lib/src/utils.dart
index 3f86f01..37523f0 100644
--- a/pkgs/json_rpc_2/lib/src/utils.dart
+++ b/pkgs/json_rpc_2/lib/src/utils.dart
@@ -40,25 +40,25 @@
whenComplete();
return result;
} else {
- return result.whenComplete(whenComplete);
+ result.whenComplete(whenComplete);
}
}
/// A transformer that silently drops [FormatException]s.
-final ignoreFormatExceptions = StreamTransformer<Object, Object>.fromHandlers(
+final ignoreFormatExceptions = StreamTransformer<Object?, Object?>.fromHandlers(
handleError: (error, stackTrace, sink) {
if (error is FormatException) return;
sink.addError(error, stackTrace);
});
/// A transformer that sends error responses on [FormatException]s.
-final StreamChannelTransformer<Object, Object> respondToFormatExceptions =
+final StreamChannelTransformer<Object?, Object?> respondToFormatExceptions =
_RespondToFormatExceptionsTransformer();
class _RespondToFormatExceptionsTransformer
- implements StreamChannelTransformer<Object, Object> {
+ implements StreamChannelTransformer<Object?, Object?> {
@override
- StreamChannel<Object> bind(StreamChannel<Object> channel) {
+ StreamChannel<Object?> bind(StreamChannel<Object?> channel) {
return channel.changeStream((stream) {
return stream.handleError((dynamic error) {
final formatException = error as FormatException;
diff --git a/pkgs/json_rpc_2/pubspec.yaml b/pkgs/json_rpc_2/pubspec.yaml
index c0c8008..e8d1b15 100644
--- a/pkgs/json_rpc_2/pubspec.yaml
+++ b/pkgs/json_rpc_2/pubspec.yaml
@@ -1,17 +1,17 @@
name: json_rpc_2
-version: 2.2.3-dev
+version: 3.0.0-dev
description: >-
Utilities to write a client or server using the JSON-RPC 2.0 spec.
homepage: https://github.com/dart-lang/json_rpc_2
environment:
- sdk: ">=2.2.0 <3.0.0"
+ sdk: ">=2.12.0 <3.0.0"
dependencies:
- stack_trace: ^1.0.0
+ stack_trace: ^1.10.0
stream_channel: ">=1.1.0 <3.0.0"
dev_dependencies:
- pedantic: ^1.8.0
- test: ^1.0.0
- web_socket_channel: ^1.1.0
+ pedantic: ^1.11.0
+ test: ^1.16.0
+ web_socket_channel: ^2.0.0
diff --git a/pkgs/json_rpc_2/test/client/client_test.dart b/pkgs/json_rpc_2/test/client/client_test.dart
index 334ddad..1c9ce10 100644
--- a/pkgs/json_rpc_2/test/client/client_test.dart
+++ b/pkgs/json_rpc_2/test/client/client_test.dart
@@ -174,14 +174,12 @@
};
});
- expect(controller.client.sendRequest('foo', {'param': 'value'}),
- throwsA(predicate((exception) {
- expect(exception, TypeMatcher<json_rpc.RpcException>());
- expect(exception.code, equals(error_code.SERVER_ERROR));
- expect(exception.message, equals('you are bad at requests'));
- expect(exception.data, equals('some junk'));
- return true;
- })));
+ expect(
+ controller.client.sendRequest('foo', {'param': 'value'}),
+ throwsA(TypeMatcher<json_rpc.RpcException>()
+ .having((e) => e.code, 'code', error_code.SERVER_ERROR)
+ .having((e) => e.message, 'message', 'you are bad at requests')
+ .having((e) => e.data, 'data', 'some junk')));
});
test('requests throw StateErrors if the client is closed', () {
diff --git a/pkgs/json_rpc_2/test/client/utils.dart b/pkgs/json_rpc_2/test/client/utils.dart
index 1684b37..398c558 100644
--- a/pkgs/json_rpc_2/test/client/utils.dart
+++ b/pkgs/json_rpc_2/test/client/utils.dart
@@ -19,13 +19,12 @@
final _requestController = StreamController<String>();
/// The client.
- json_rpc.Client get client => _client;
- json_rpc.Client _client;
+ late final json_rpc.Client client;
ClientController() {
- _client = json_rpc.Client(
+ client = json_rpc.Client(
StreamChannel(_responseController.stream, _requestController.sink));
- _client.listen();
+ client.listen();
}
/// Expects that the client will send a request.
diff --git a/pkgs/json_rpc_2/test/server/utils.dart b/pkgs/json_rpc_2/test/server/utils.dart
index 7ff491c..92f1d32 100644
--- a/pkgs/json_rpc_2/test/server/utils.dart
+++ b/pkgs/json_rpc_2/test/server/utils.dart
@@ -20,17 +20,16 @@
final _responseController = StreamController<String>();
/// The server.
- json_rpc.Server get server => _server;
- json_rpc.Server _server;
+ late final json_rpc.Server server;
ServerController(
- {json_rpc.ErrorCallback onUnhandledError,
+ {json_rpc.ErrorCallback? onUnhandledError,
bool strictProtocolChecks = true}) {
- _server = json_rpc.Server(
+ server = json_rpc.Server(
StreamChannel(_requestController.stream, _responseController.sink),
onUnhandledError: onUnhandledError,
strictProtocolChecks: strictProtocolChecks);
- _server.listen();
+ server.listen();
}
/// Passes [request], a decoded request, to [server] and returns its decoded
@@ -66,11 +65,7 @@
/// Returns a matcher that matches a [json_rpc.RpcException] with an
/// `invalid_params` error code.
-Matcher throwsInvalidParams(String message) {
- return throwsA(predicate((error) {
- expect(error, TypeMatcher<json_rpc.RpcException>());
- expect(error.code, equals(error_code.INVALID_PARAMS));
- expect(error.message, equals(message));
- return true;
- }));
-}
+Matcher throwsInvalidParams(String message) =>
+ throwsA(TypeMatcher<json_rpc.RpcException>()
+ .having((e) => e.code, 'code', error_code.INVALID_PARAMS)
+ .having((e) => e.message, 'message', message));