bump lints dep and fix (#92)

diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index 25eb99f..daf8244 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -19,7 +19,7 @@
     strategy:
       fail-fast: false
       matrix:
-        sdk: [2.19.0, dev]
+        sdk: [3.1.0, dev]
     steps:
       - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b
       - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e0ad4b3..e092491 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.1.2-wip
+
+* Require Dart SDK `^3.1.0`.
+
 ## 1.1.1
 
 * Fix a bug where if spawnWorker threw an error, work requests would hang
diff --git a/lib/src/async_message_grouper.dart b/lib/src/async_message_grouper.dart
index 6488091..e1f0dea 100644
--- a/lib/src/async_message_grouper.dart
+++ b/lib/src/async_message_grouper.dart
@@ -23,7 +23,7 @@
   /// Position in the current input buffer.
   int _inputBufferPos = 0;
 
-  /// Completes after [cancel] is called or [inputStream] is closed.
+  /// Completes after [cancel] is called or `inputStream` is closed.
   Future<void> get done => _done.future;
   final _done = Completer<void>();
 
diff --git a/lib/src/driver/driver.dart b/lib/src/driver/driver.dart
index e0d57ae..4a78020 100644
--- a/lib/src/driver/driver.dart
+++ b/lib/src/driver/driver.dart
@@ -23,7 +23,7 @@
   /// The maximum number of idle workers at any given time.
   final int _maxIdleWorkers;
 
-  /// The maximum number of times to retry a [WorkAttempt] if there is an error.
+  /// The maximum number of times to retry a [_WorkAttempt] if there is an error.
   final int _maxRetries;
 
   /// The maximum number of concurrent workers to run at any given time.
@@ -57,7 +57,7 @@
   /// to determine when actual work is being done versus just waiting for an
   /// available worker.
   Future<WorkResponse> doWork(WorkRequest request,
-      {Function(Future<WorkResponse?>)? trackWork}) {
+      {void Function(Future<WorkResponse?>)? trackWork}) {
     var attempt = _WorkAttempt(request, trackWork: trackWork);
     _workQueue.add(attempt);
     _runWorkQueue();
@@ -130,7 +130,7 @@
     _runWorkQueue();
   }
 
-  /// Sends [request] to [worker].
+  /// Sends [attempt] to [worker].
   ///
   /// Once the worker responds then it will be added back to the pool of idle
   /// workers.
@@ -227,7 +227,7 @@
 class _WorkAttempt {
   final WorkRequest request;
   final responseCompleter = Completer<WorkResponse>();
-  final Function(Future<WorkResponse?>)? trackWork;
+  final void Function(Future<WorkResponse?>)? trackWork;
 
   Future<WorkResponse> get response => responseCompleter.future;
 
diff --git a/lib/src/driver/driver_connection.dart b/lib/src/driver/driver_connection.dart
index 35c72c9..b419deb 100644
--- a/lib/src/driver/driver_connection.dart
+++ b/lib/src/driver/driver_connection.dart
@@ -9,6 +9,7 @@
 
 import '../async_message_grouper.dart';
 import '../constants.dart';
+import '../message_grouper.dart';
 import '../utils.dart';
 import '../worker_protocol.pb.dart';
 
diff --git a/lib/src/message_grouper.dart b/lib/src/message_grouper.dart
index 635983e..31aa204 100644
--- a/lib/src/message_grouper.dart
+++ b/lib/src/message_grouper.dart
@@ -2,6 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'async_message_grouper.dart';
+import 'sync_message_grouper.dart';
+
 /// Interface for a [MessageGrouper], which groups bytes in  delimited proto
 /// format into the bytes for each message.
 ///
diff --git a/lib/src/message_grouper_state.dart b/lib/src/message_grouper_state.dart
index c8531d7..2656835 100644
--- a/lib/src/message_grouper_state.dart
+++ b/lib/src/message_grouper_state.dart
@@ -6,6 +6,8 @@
 
 import 'package:protobuf/protobuf.dart';
 
+import 'message_grouper.dart';
+
 /// State held by the [MessageGrouper] while waiting for additional data to
 /// arrive.
 class MessageGrouperState {
@@ -18,7 +20,7 @@
   /// Handle one byte at a time.
   ///
   /// Returns a [List<int>] of message bytes if [byte] was the last byte in a
-  /// message, otherwise returns [null].
+  /// message, otherwise returns `null`.
   List<int>? handleInput(int byte) {
     if (!_lengthReader.done) {
       _lengthReader.readByte(byte);
diff --git a/lib/src/worker/worker_connection.dart b/lib/src/worker/worker_connection.dart
index a718099..b395316 100644
--- a/lib/src/worker/worker_connection.dart
+++ b/lib/src/worker/worker_connection.dart
@@ -16,7 +16,7 @@
 /// program using `BazelWorkerDriver`, or any other process that speaks the
 /// protocol).
 abstract class WorkerConnection {
-  /// Reads a [WorkRequest] or returns [null] if there are none left.
+  /// Reads a [WorkRequest] or returns `null` if there are none left.
   ///
   /// See [AsyncWorkerConnection] and [SyncWorkerConnection] for more narrow
   /// interfaces.
diff --git a/lib/src/worker/worker_loop.dart b/lib/src/worker/worker_loop.dart
index 2e4a023..5723fd1 100644
--- a/lib/src/worker/worker_loop.dart
+++ b/lib/src/worker/worker_loop.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import '../worker_protocol.pb.dart';
+import 'async_worker_loop.dart';
+import 'sync_worker_loop.dart';
 
 /// Interface for a [WorkerLoop].
 ///
@@ -13,6 +15,6 @@
   /// a [Future<WorkResponse>].
   dynamic performRequest(WorkRequest request);
 
-  /// Run the worker loop. Should return either a [Future] or [null].
+  /// Run the worker loop. Should return either a [Future] or `null`.
   dynamic run();
 }
diff --git a/lib/testing.dart b/lib/testing.dart
index 6d4e07f..3ae4c1f 100644
--- a/lib/testing.dart
+++ b/lib/testing.dart
@@ -7,7 +7,7 @@
 import 'dart:io';
 import 'dart:typed_data';
 
-import 'package:bazel_worker/bazel_worker.dart';
+import 'bazel_worker.dart';
 
 export 'src/async_message_grouper.dart';
 export 'src/sync_message_grouper.dart';
@@ -150,7 +150,7 @@
   }
 
   /// Adds [response] to the queue. These will be returned from
-  /// [performResponse] in the order they are added, otherwise it will throw
+  /// [performRequest] in the order they are added, otherwise it will throw
   /// if the queue is empty.
   @override
   void enqueueResponse(WorkResponse response) {
@@ -194,7 +194,7 @@
   }
 
   /// Adds [response] to the queue. These will be returned from
-  /// [performResponse] in the order they are added, otherwise it will throw
+  /// [performRequest] in the order they are added, otherwise it will throw
   /// if the queue is empty.
   @override
   void enqueueResponse(WorkResponse response) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 425fd9b..accb400 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,16 +1,16 @@
 name: bazel_worker
-version: 1.1.1
+version: 1.1.2-wip
 description: >-
   Protocol and utilities to implement or invoke persistent bazel workers.
 repository: https://github.com/dart-lang/bazel_worker
 
 environment:
-  sdk: '>=2.19.0 <4.0.0'
+  sdk: ^3.1.0
 
 dependencies:
   async: ^2.5.0
   protobuf: ^3.0.0
 
 dev_dependencies:
-  dart_flutter_team_lints: ^1.0.0
+  dart_flutter_team_lints: ^3.0.0
   test: ^1.16.0
diff --git a/test/driver_test.dart b/test/driver_test.dart
index 980ae23..c397830 100644
--- a/test/driver_test.dart
+++ b/test/driver_test.dart
@@ -159,7 +159,7 @@
 Future _doRequests(
     {BazelWorkerDriver? driver,
     int count = 100,
-    Function(Future<WorkResponse?>)? trackWork}) async {
+    void Function(Future<WorkResponse?>)? trackWork}) async {
   // If we create a driver, we need to make sure and terminate it.
   var terminateDriver = driver == null;
   driver ??= BazelWorkerDriver(MockWorker.spawn);
@@ -178,8 +178,7 @@
 class MockWorkerLoop extends AsyncWorkerLoop {
   final Queue<WorkResponse> _responseQueue;
 
-  MockWorkerLoop(this._responseQueue, {AsyncWorkerConnection? connection})
-      : super(connection: connection);
+  MockWorkerLoop(this._responseQueue, {super.connection});
 
   @override
   Future<WorkResponse> performRequest(WorkRequest request) async {
diff --git a/test/worker_loop_test.dart b/test/worker_loop_test.dart
index 9a13fd2..50d2151 100644
--- a/test/worker_loop_test.dart
+++ b/test/worker_loop_test.dart
@@ -112,7 +112,7 @@
       (stdinStream as TestStdinSync).pendingBytes.clear();
       await workerLoop.run();
     } else if (stdinStream is TestStdinAsync) {
-      var done = Completer();
+      var done = Completer<void>();
       // ignore: avoid_dynamic_calls
       workerLoop.run().then((_) => done.complete(null));
       (stdinStream as TestStdinAsync).controller.addError('Error!!');