Require Dart 3.0, update lints (#109)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d1efa92..ff8cc4d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,7 +20,7 @@
     strategy:
       fail-fast: false
       matrix:
-        sdk: [dev, 2.18.0]
+        sdk: [dev, 3.0.0]
     steps:
       - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
@@ -47,7 +47,7 @@
       matrix:
         # Add macos-latest and/or windows-latest if relevant for this package.
         os: [ubuntu-latest]
-        sdk: [dev, 2.18.0]
+        sdk: [dev, 3.0.0]
     steps:
       - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
       - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3d998e..e723cd6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.0.5-wip
+
+* Require Dart 3.0.
+
 ## 1.0.4
 
 * Updates to the readme.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index d978f81..fc4afe3 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1 +1,40 @@
+# https://dart.dev/guides/language/analysis-options
 include: package:dart_flutter_team_lints/analysis_options.yaml
+
+analyzer:
+  language:
+    strict-casts: true
+    strict-inference: true
+    strict-raw-types: true
+
+linter:
+  rules:
+    - avoid_bool_literals_in_conditional_expressions
+    - avoid_classes_with_only_static_members
+    - avoid_private_typedef_functions
+    - avoid_redundant_argument_values
+    - avoid_returning_null
+    - avoid_returning_null_for_future
+    - avoid_returning_this
+    - avoid_unused_constructor_parameters
+    - avoid_void_async
+    - cancel_subscriptions
+    - comment_references
+    - join_return_with_assignment
+    - literal_only_boolean_expressions
+    - missing_whitespace_between_adjacent_strings
+    - no_adjacent_strings_in_list
+    - no_runtimeType_toString
+    - package_api_docs
+    - prefer_const_constructors
+    - prefer_const_declarations
+    - prefer_expression_function_bodies
+    - prefer_final_locals
+    - prefer_relative_imports
+    - test_types_in_equals
+    - unnecessary_await_in_return
+    - unnecessary_breaks
+    - use_if_null_to_convert_nulls_to_bools
+    - use_raw_strings
+    - use_string_buffers
+    - use_super_parameters
diff --git a/lib/src/ansi_code.dart b/lib/src/ansi_code.dart
index 86a77a3..c023f53 100644
--- a/lib/src/ansi_code.dart
+++ b/lib/src/ansi_code.dart
@@ -6,7 +6,7 @@
 import 'dart:io' as io;
 
 const _ansiEscapeLiteral = '\x1B';
-const _ansiEscapeForScript = '\\033';
+const _ansiEscapeForScript = r'\033';
 
 /// Whether formatted ANSI output is enabled for [wrapWith] and [AnsiCode.wrap].
 ///
@@ -136,14 +136,12 @@
           throw ArgumentError.value(codes, 'codes',
               'Cannot contain more than one foreground color code.');
         }
-        break;
       case AnsiCodeType.background:
         background++;
         if (background > 1) {
           throw ArgumentError.value(codes, 'codes',
               'Cannot contain more than one foreground color code.');
         }
-        break;
       case AnsiCodeType.reset:
         throw ArgumentError.value(
             codes, 'codes', 'Cannot contain reset codes.');
diff --git a/lib/src/permissions.dart b/lib/src/permissions.dart
index b6774f8..9170749 100644
--- a/lib/src/permissions.dart
+++ b/lib/src/permissions.dart
@@ -34,18 +34,13 @@
   return (stat.mode & (1 << index)) != 0;
 }
 
-int _permissionBitIndex(_FilePermission permission, _FilePermissionRole role) {
-  switch (permission) {
-    case _FilePermission.setUid:
-      return 11;
-    case _FilePermission.setGid:
-      return 10;
-    case _FilePermission.sticky:
-      return 9;
-    default:
-      return (role.index * 3) + permission.index;
-  }
-}
+int _permissionBitIndex(_FilePermission permission, _FilePermissionRole role) =>
+    switch (permission) {
+      _FilePermission.setUid => 11,
+      _FilePermission.setGid => 10,
+      _FilePermission.sticky => 9,
+      _ => (role.index * 3) + permission.index
+    };
 
 /// Returns whether [path] is considered an executable file on this OS.
 ///
diff --git a/lib/src/process_manager.dart b/lib/src/process_manager.dart
index 84af6df..504311f 100644
--- a/lib/src/process_manager.dart
+++ b/lib/src/process_manager.dart
@@ -215,13 +215,13 @@
   }
 
   _ForwardingSpawn._delegate(
-    io.Process delegate,
+    super.delegate,
     this._stdInSub,
     this._stdOutSub,
     this._stdErrSub,
     this._stdOut,
     this._stdErr,
-  ) : super._(delegate);
+  ) : super._();
 
   @override
   void _onClosed() {
@@ -240,24 +240,16 @@
 
 class _UnixProcessManager extends ProcessManager {
   const _UnixProcessManager(
-    Stream<List<int>> stdin,
-    io.IOSink stdout,
-    io.IOSink stderr,
-  ) : super._(
-          stdin,
-          stdout,
-          stderr,
-        );
+    super.stdin,
+    super.stdout,
+    super.stderr,
+  ) : super._();
 }
 
 class _WindowsProcessManager extends ProcessManager {
   const _WindowsProcessManager(
-    Stream<List<int>> stdin,
-    io.IOSink stdout,
-    io.IOSink stderr,
-  ) : super._(
-          stdin,
-          stdout,
-          stderr,
-        );
+    super.stdin,
+    super.stdout,
+    super.stderr,
+  ) : super._();
 }
diff --git a/lib/src/shell_words.dart b/lib/src/shell_words.dart
index bfba529..ea48aa9 100644
--- a/lib/src/shell_words.dart
+++ b/lib/src/shell_words.dart
@@ -47,7 +47,6 @@
 
         hasToken = true;
         token.writeCharCode(scanner.readChar());
-        break;
 
       case $singleQuote:
         hasToken = true;
@@ -59,7 +58,6 @@
           _checkUnmatchedQuote(scanner, firstQuote);
           token.writeCharCode(scanner.readChar());
         }
-        break;
 
       case $doubleQuote:
         hasToken = true;
@@ -99,7 +97,6 @@
             token.writeCharCode(scanner.readChar());
           }
         }
-        break;
 
       case $hash:
         // Section 2.3: If the current character is a '#' [and the previous
@@ -115,7 +112,6 @@
         while (!scanner.isDone && scanner.peekChar() != $lf) {
           scanner.readChar();
         }
-        break;
 
       case $space:
       case $tab:
@@ -124,7 +120,6 @@
         if (hasToken) results.add(token.toString());
         hasToken = false;
         token.clear();
-        break;
 
       default:
         hasToken = true;
diff --git a/pubspec.yaml b/pubspec.yaml
index 8ac6d57..6d72a35 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -2,11 +2,11 @@
 description: >-
   Utilities for the Dart VM Runtime including support for ANSI colors, file
   copying, and standard exit code values.
-version: 1.0.4
+version: 1.0.5-wip
 repository: https://github.com/dart-lang/io
 
 environment:
-  sdk: ">=2.12.0 <3.0.0"
+  sdk: ^3.0.0
 
 dependencies:
   meta: ^1.3.0
@@ -14,6 +14,6 @@
   string_scanner: ^1.1.0
 
 dev_dependencies:
-  dart_flutter_team_lints: ^0.1.0
+  dart_flutter_team_lints: ^1.0.0
   test: ^1.16.0
   test_descriptor: ^2.0.0
diff --git a/test/ansi_code_test.dart b/test/ansi_code_test.dart
index 82bf8e4..5b911d4 100644
--- a/test/ansi_code_test.dart
+++ b/test/ansi_code_test.dart
@@ -3,12 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 @TestOn('vm')
+library;
+
 import 'dart:io';
+
 import 'package:io/ansi.dart';
 import 'package:test/test.dart';
 
 const _ansiEscapeLiteral = '\x1B';
-const _ansiEscapeForScript = '\\033';
+const _ansiEscapeForScript = r'\033';
 const sampleInput = 'sample input';
 
 void main() {
diff --git a/test/copy_path_test.dart b/test/copy_path_test.dart
index 57150fe..bfbf2da 100644
--- a/test/copy_path_test.dart
+++ b/test/copy_path_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 @TestOn('vm')
+library;
+
 import 'package:io/io.dart';
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
diff --git a/test/permissions_test.dart b/test/permissions_test.dart
index f6fcd78..a313aaf 100644
--- a/test/permissions_test.dart
+++ b/test/permissions_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 @TestOn('vm')
+library;
+
 import 'package:io/io.dart';
 import 'package:test/test.dart';
 
diff --git a/test/shell_words_test.dart b/test/shell_words_test.dart
index 24f031c..d0cd89b 100644
--- a/test/shell_words_test.dart
+++ b/test/shell_words_test.dart
@@ -157,7 +157,7 @@
       });
 
       test('that contain escaped characters', () {
-        expect(shellSplit(r'"\$\`\"\\"'), equals(['\$`"\\']));
+        expect(shellSplit(r'"\$\`\"\\"'), equals([r'$`"\']));
       });
 
       test('that contain an escaped newline', () {
@@ -178,7 +178,7 @@
 
       test('without a closing quote', () {
         expect(() => shellSplit('"foo bar'), throwsFormatException);
-        expect(() => shellSplit('"foo bar\\'), throwsFormatException);
+        expect(() => shellSplit(r'"foo bar\'), throwsFormatException);
       });
     });
   });