Update to latest deps, fix remaining lints (#112)

diff --git a/analysis_options.yaml b/analysis_options.yaml
index a785408..a0ba68d 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -3,8 +3,3 @@
 # BSD-style license that can be found in the LICENSE file.
 
 include: package:pedantic/analysis_options.1.9.0.yaml
-analyzer:
-  errors:
-    annotate_overrides: ignore
-    prefer_single_quotes: ignore
-    use_function_type_syntax_for_parameters: ignore
diff --git a/lib/package_config.dart b/lib/package_config.dart
index 3dfd8ef..bd227e4 100644
--- a/lib/package_config.dart
+++ b/lib/package_config.dart
@@ -9,15 +9,15 @@
 /// configurations in the [specified format](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md).
 library package_config.package_config;
 
-import "dart:io" show File, Directory;
-import "dart:typed_data" show Uint8List;
+import 'dart:io' show File, Directory;
+import 'dart:typed_data' show Uint8List;
 
-import "src/discovery.dart" as discover;
-import "src/errors.dart" show throwError;
-import "src/package_config.dart";
-import "src/package_config_io.dart";
+import 'src/discovery.dart' as discover;
+import 'src/errors.dart' show throwError;
+import 'src/package_config.dart';
+import 'src/package_config_io.dart';
 
-export "package_config_types.dart";
+export 'package_config_types.dart';
 
 /// Reads a specific package configuration file.
 ///
@@ -42,7 +42,7 @@
 /// a valid configuration from the invalid configuration file.
 /// If no [onError] is provided, errors are thrown immediately.
 Future<PackageConfig> loadPackageConfig(File file,
-        {bool preferNewest = true, void onError(Object error)?}) =>
+        {bool preferNewest = true, void Function(Object error)? onError}) =>
     readAnyConfigFile(file, preferNewest, onError ?? throwError);
 
 /// Reads a specific package configuration URI.
@@ -87,9 +87,9 @@
 /// a valid configuration from the invalid configuration file.
 /// If no [onError] is provided, errors are thrown immediately.
 Future<PackageConfig> loadPackageConfigUri(Uri file,
-        {Future<Uint8List?> loader(Uri uri)?,
+        {Future<Uint8List?> Function(Uri uri)? loader,
         bool preferNewest = true,
-        void onError(Object error)?}) =>
+        void Function(Object error)? onError}) =>
     readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest);
 
 /// Finds a package configuration relative to [directory].
@@ -113,7 +113,7 @@
 ///
 /// Returns `null` if no configuration file is found.
 Future<PackageConfig?> findPackageConfig(Directory directory,
-        {bool recurse = true, void onError(Object error)?}) =>
+        {bool recurse = true, void Function(Object error)? onError}) =>
     discover.findPackageConfig(directory, recurse, onError ?? throwError);
 
 /// Finds a package configuration relative to [location].
@@ -158,8 +158,8 @@
 /// Returns `null` if no configuration file is found.
 Future<PackageConfig?> findPackageConfigUri(Uri location,
         {bool recurse = true,
-        Future<Uint8List?> loader(Uri uri)?,
-        void onError(Object error)?}) =>
+        Future<Uint8List?> Function(Uri uri)? loader,
+        void Function(Object error)? onError}) =>
     discover.findPackageConfigUri(
         location, loader, onError ?? throwError, recurse);
 
diff --git a/lib/package_config_types.dart b/lib/package_config_types.dart
index b3fca16..482f82a 100644
--- a/lib/package_config_types.dart
+++ b/lib/package_config_types.dart
@@ -6,6 +6,6 @@
 /// and vice-versa,
 library package_config.package_config_types;
 
-export "src/package_config.dart"
+export 'src/package_config.dart'
     show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion;
-export "src/errors.dart" show PackageConfigError;
+export 'src/errors.dart' show PackageConfigError;
diff --git a/lib/src/discovery.dart b/lib/src/discovery.dart
index a3e01d7..a6cc451 100644
--- a/lib/src/discovery.dart
+++ b/lib/src/discovery.dart
@@ -2,21 +2,21 @@
 // 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 "dart:io";
+import 'dart:io';
 import 'dart:typed_data';
 
 import 'package_config_io.dart';
 
-import "errors.dart";
-import "package_config_impl.dart";
-import "package_config_json.dart";
-import "packages_file.dart" as packages_file;
-import "util_io.dart" show defaultLoader, pathJoin;
+import 'errors.dart';
+import 'package_config_impl.dart';
+import 'package_config_json.dart';
+import 'packages_file.dart' as packages_file;
+import 'util_io.dart' show defaultLoader, pathJoin;
 
-final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json");
-final Uri dotPackagesPath = Uri(path: ".packages");
-final Uri currentPath = Uri(path: ".");
-final Uri parentPath = Uri(path: "..");
+final Uri packageConfigJsonPath = Uri(path: '.dart_tool/package_config.json');
+final Uri dotPackagesPath = Uri(path: '.packages');
+final Uri currentPath = Uri(path: '.');
+final Uri parentPath = Uri(path: '..');
 
 /// Discover the package configuration for a Dart script.
 ///
@@ -32,8 +32,8 @@
 /// If any of these tests succeed, a `PackageConfig` class is returned.
 /// Returns `null` if no configuration was found. If a configuration
 /// is needed, then the caller can supply [PackageConfig.empty].
-Future<PackageConfig?> findPackageConfig(
-    Directory baseDirectory, bool recursive, void onError(Object error)) async {
+Future<PackageConfig?> findPackageConfig(Directory baseDirectory,
+    bool recursive, void Function(Object error) onError) async {
   var directory = baseDirectory;
   if (!directory.isAbsolute) directory = directory.absolute;
   if (!await directory.exists()) {
@@ -55,16 +55,16 @@
 /// Similar to [findPackageConfig] but based on a URI.
 Future<PackageConfig?> findPackageConfigUri(
     Uri location,
-    Future<Uint8List?> loader(Uri uri)?,
-    void onError(Object error),
+    Future<Uint8List?> Function(Uri uri)? loader,
+    void Function(Object error) onError,
     bool recursive) async {
-  if (location.isScheme("package")) {
+  if (location.isScheme('package')) {
     onError(PackageConfigArgumentError(
-        location, "location", "Must not be a package: URI"));
+        location, 'location', 'Must not be a package: URI'));
     return null;
   }
   if (loader == null) {
-    if (location.isScheme("file")) {
+    if (location.isScheme('file')) {
       return findPackageConfig(
           Directory.fromUri(location.resolveUri(currentPath)),
           recursive,
@@ -72,7 +72,7 @@
     }
     loader = defaultLoader;
   }
-  if (!location.path.endsWith("/")) location = location.resolveUri(currentPath);
+  if (!location.path.endsWith('/')) location = location.resolveUri(currentPath);
   while (true) {
     var file = location.resolveUri(packageConfigJsonPath);
     var bytes = await loader(file);
@@ -103,7 +103,7 @@
 /// a best-effort attempt is made to return a package configuration.
 /// This may be the empty package configuration.
 Future<PackageConfig?> findPackagConfigInDirectory(
-    Directory directory, void onError(Object error)) async {
+    Directory directory, void Function(Object error) onError) async {
   var packageConfigFile = await checkForPackageConfigJsonFile(directory);
   if (packageConfigFile != null) {
     return await readPackageConfigJsonFile(packageConfigFile, onError);
@@ -118,13 +118,13 @@
 Future<File?> checkForPackageConfigJsonFile(Directory directory) async {
   assert(directory.isAbsolute);
   var file =
-      File(pathJoin(directory.path, ".dart_tool", "package_config.json"));
+      File(pathJoin(directory.path, '.dart_tool', 'package_config.json'));
   if (await file.exists()) return file;
   return null;
 }
 
 Future<File?> checkForDotPackagesFile(Directory directory) async {
-  var file = File(pathJoin(directory.path, ".packages"));
+  var file = File(pathJoin(directory.path, '.packages'));
   if (await file.exists()) return file;
   return null;
 }
diff --git a/lib/src/package_config.dart b/lib/src/package_config.dart
index 26aa396..8210132 100644
--- a/lib/src/package_config.dart
+++ b/lib/src/package_config.dart
@@ -5,7 +5,7 @@
 import 'dart:typed_data';
 
 import 'errors.dart';
-import "package_config_impl.dart";
+import 'package_config_impl.dart';
 import 'package_config_json.dart';
 
 /// A package configuration.
@@ -70,7 +70,7 @@
   /// The result may be [PackageConfig.empty] if there is no way to
   /// extract useful information from the bytes.
   static PackageConfig parseBytes(Uint8List bytes, Uri baseUri,
-          {void onError(Object error)?}) =>
+          {void Function(Object error)? onError}) =>
       parsePackageConfigBytes(bytes, baseUri, onError ?? throwError);
 
   /// Parses a package configuration file.
@@ -90,7 +90,7 @@
   /// The result may be [PackageConfig.empty] if there is no way to
   /// extract useful information from the bytes.
   static PackageConfig parseString(String configuration, Uri baseUri,
-          {void onError(Object error)?}) =>
+          {void Function(Object error)? onError}) =>
       parsePackageConfigString(configuration, baseUri, onError ?? throwError);
 
   /// Parses the JSON data of a package configuration file.
@@ -111,7 +111,7 @@
   /// The result may be [PackageConfig.empty] if there is no way to
   /// extract useful information from the bytes.
   static PackageConfig parseJson(Object? jsonData, Uri baseUri,
-          {void onError(Object error)?}) =>
+          {void Function(Object error)? onError}) =>
       parsePackageConfigJson(jsonData, baseUri, onError ?? throwError);
 
   /// Writes a configuration file for this configuration on [output].
@@ -302,8 +302,8 @@
   /// The maximal value allowed by [major] and [minor] values;
   static const int maxValue = 0x7FFFFFFF;
   factory LanguageVersion(int major, int minor) {
-    RangeError.checkValueInInterval(major, 0, maxValue, "major");
-    RangeError.checkValueInInterval(minor, 0, maxValue, "major");
+    RangeError.checkValueInInterval(major, 0, maxValue, 'major');
+    RangeError.checkValueInInterval(minor, 0, maxValue, 'major');
     return SimpleLanguageVersion(major, minor, null);
   }
 
@@ -324,7 +324,8 @@
   /// If [onError] is not supplied, it defaults to throwing the exception.
   /// If the call does not throw, then an [InvalidLanguageVersion] is returned
   /// containing the original [source].
-  static LanguageVersion parse(String source, {void onError(Object error)?}) =>
+  static LanguageVersion parse(String source,
+          {void Function(Object error)? onError}) =>
       parseLanguageVersion(source, onError ?? throwError);
 
   /// The major language version.
@@ -352,6 +353,7 @@
   /// is greater than the latter's major version, or if they have
   /// the same major version and the former's minor version is greater than
   /// the latter's.
+  @override
   int compareTo(LanguageVersion other);
 
   /// Valid language versions with the same [major] and [minor] values are
@@ -359,14 +361,17 @@
   ///
   /// Invalid language versions ([InvalidLanguageVersion]) are not equal to
   /// any other object.
+  @override
   bool operator ==(Object other);
 
+  @override
   int get hashCode;
 
   /// A string representation of the language version.
   ///
   /// A valid language version is represented as
   /// `"${version.major}.${version.minor}"`.
+  @override
   String toString();
 }
 
@@ -377,16 +382,21 @@
 /// which did not throw on an error.
 abstract class InvalidLanguageVersion implements LanguageVersion {
   /// The value -1 for an invalid language version.
+  @override
   int get major;
 
   /// The value -1 for an invalid language version.
+  @override
   int get minor;
 
   /// An invalid language version is only equal to itself.
+  @override
   bool operator ==(Object other);
 
+  @override
   int get hashCode;
 
   /// The original invalid version string.
+  @override
   String toString();
 }
diff --git a/lib/src/package_config_impl.dart b/lib/src/package_config_impl.dart
index 1229991..4167d35 100644
--- a/lib/src/package_config_impl.dart
+++ b/lib/src/package_config_impl.dart
@@ -3,21 +3,23 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'errors.dart';
-import "package_config.dart";
-import "util.dart";
+import 'package_config.dart';
+import 'util.dart';
 
-export "package_config.dart";
+export 'package_config.dart';
 
 // Implementations of the main data types exposed by the API of this package.
 
 class SimplePackageConfig implements PackageConfig {
+  @override
   final int version;
   final Map<String, Package> _packages;
   final PackageTree _packageTree;
+  @override
   final Object? extraData;
 
   factory SimplePackageConfig(int version, Iterable<Package> packages,
-      [Object? extraData, void onError(Object error)?]) {
+      [Object? extraData, void Function(Object error)? onError]) {
     onError ??= throwError;
     var validVersion = _validateVersion(version, onError);
     var sortedPackages = [...packages]..sort(_compareRoot);
@@ -39,17 +41,18 @@
         _packages = const <String, Package>{},
         extraData = null;
 
-  static int _validateVersion(int version, void onError(Object error)) {
+  static int _validateVersion(
+      int version, void Function(Object error) onError) {
     if (version < 0 || version > PackageConfig.maxVersion) {
-      onError(PackageConfigArgumentError(version, "version",
-          "Must be in the range 1 to ${PackageConfig.maxVersion}"));
+      onError(PackageConfigArgumentError(version, 'version',
+          'Must be in the range 1 to ${PackageConfig.maxVersion}'));
       return 2; // The minimal version supporting a SimplePackageConfig.
     }
     return version;
   }
 
   static PackageTree _validatePackages(Iterable<Package> originalPackages,
-      List<Package> packages, void onError(Object error)) {
+      List<Package> packages, void Function(Object error) onError) {
     var packageNames = <String>{};
     var tree = MutablePackageTree();
     for (var originalPackage in packages) {
@@ -64,8 +67,8 @@
             originalPackage.extraData,
             originalPackage.relativeRoot, (error) {
           if (error is PackageConfigArgumentError) {
-            onError(PackageConfigArgumentError(packages, "packages",
-                "Package ${package!.name}: ${error.message}"));
+            onError(PackageConfigArgumentError(packages, 'packages',
+                'Package ${package!.name}: ${error.message}'));
           } else {
             onError(error);
           }
@@ -77,7 +80,7 @@
       var name = package.name;
       if (packageNames.contains(name)) {
         onError(PackageConfigArgumentError(
-            name, "packages", "Duplicate package name '$name'"));
+            name, 'packages', "Duplicate package name '$name'"));
         continue;
       }
       packageNames.add(name);
@@ -88,20 +91,20 @@
           if (error.isRootConflict) {
             onError(PackageConfigArgumentError(
                 originalPackages,
-                "packages",
-                "Packages ${package!.name} and ${existingPackage.name} "
-                    "have the same root directory: ${package.root}.\n"));
+                'packages',
+                'Packages ${package!.name} and ${existingPackage.name} '
+                    'have the same root directory: ${package.root}.\n'));
           } else {
             assert(error.isPackageRootConflict);
             // Package is inside the package URI root of the existing package.
             onError(PackageConfigArgumentError(
                 originalPackages,
-                "packages",
-                "Package ${package!.name} is inside the package URI root of "
-                    "package ${existingPackage.name}.\n"
-                    "${existingPackage.name} URI root: "
-                    "${existingPackage.packageUriRoot}\n"
-                    "${package.name} root: ${package.root}\n"));
+                'packages',
+                'Package ${package!.name} is inside the package URI root of '
+                    'package ${existingPackage.name}.\n'
+                    '${existingPackage.name} URI root: '
+                    '${existingPackage.packageUriRoot}\n'
+                    '${package.name} root: ${package.root}\n'));
           }
         } else {
           // Any other error.
@@ -112,8 +115,10 @@
     return tree;
   }
 
+  @override
   Iterable<Package> get packages => _packages.values;
 
+  @override
   Package? operator [](String packageName) => _packages[packageName];
 
   /// Provides the associated package for a specific [file] (or directory).
@@ -122,22 +127,25 @@
   /// That is, the [Package.rootUri] directory is a parent directory
   /// of the [file]'s location.
   /// Returns `null` if the file does not belong to any package.
+  @override
   Package? packageOf(Uri file) => _packageTree.packageOf(file);
 
+  @override
   Uri? resolve(Uri packageUri) {
-    var packageName = checkValidPackageUri(packageUri, "packageUri");
+    var packageName = checkValidPackageUri(packageUri, 'packageUri');
     return _packages[packageName]?.packageUriRoot.resolveUri(
         Uri(path: packageUri.path.substring(packageName.length + 1)));
   }
 
+  @override
   Uri? toPackageUri(Uri nonPackageUri) {
-    if (nonPackageUri.isScheme("package")) {
+    if (nonPackageUri.isScheme('package')) {
       throw PackageConfigArgumentError(
-          nonPackageUri, "nonPackageUri", "Must not be a package URI");
+          nonPackageUri, 'nonPackageUri', 'Must not be a package URI');
     }
     if (nonPackageUri.hasQuery || nonPackageUri.hasFragment) {
-      throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri",
-          "Must not have query or fragment part");
+      throw PackageConfigArgumentError(nonPackageUri, 'nonPackageUri',
+          'Must not have query or fragment part');
     }
     // Find package that file belongs to.
     var package = _packageTree.packageOf(nonPackageUri);
@@ -147,7 +155,7 @@
     var root = package.packageUriRoot.toString();
     if (_beginsWith(package.root.toString().length, root, path)) {
       var rest = path.substring(root.length);
-      return Uri(scheme: "package", path: "${package.name}/$rest");
+      return Uri(scheme: 'package', path: '${package.name}/$rest');
     }
     return null;
   }
@@ -155,11 +163,17 @@
 
 /// Configuration data for a single package.
 class SimplePackage implements Package {
+  @override
   final String name;
+  @override
   final Uri root;
+  @override
   final Uri packageUriRoot;
+  @override
   final LanguageVersion? languageVersion;
+  @override
   final Object? extraData;
+  @override
   final bool relativeRoot;
 
   SimplePackage._(this.name, this.root, this.packageUriRoot,
@@ -187,30 +201,30 @@
       LanguageVersion? languageVersion,
       Object? extraData,
       bool relativeRoot,
-      void onError(Object error)) {
+      void Function(Object error) onError) {
     var fatalError = false;
     var invalidIndex = checkPackageName(name);
     if (invalidIndex >= 0) {
       onError(PackageConfigFormatException(
-          "Not a valid package name", name, invalidIndex));
+          'Not a valid package name', name, invalidIndex));
       fatalError = true;
     }
-    if (root.isScheme("package")) {
+    if (root.isScheme('package')) {
       onError(PackageConfigArgumentError(
-          "$root", "root", "Must not be a package URI"));
+          '$root', 'root', 'Must not be a package URI'));
       fatalError = true;
     } else if (!isAbsoluteDirectoryUri(root)) {
       onError(PackageConfigArgumentError(
-          "$root",
-          "root",
-          "In package $name: Not an absolute URI with no query or fragment "
-              "with a path ending in /"));
+          '$root',
+          'root',
+          'In package $name: Not an absolute URI with no query or fragment '
+              'with a path ending in /'));
       // Try to recover. If the URI has a scheme,
       // then ensure that the path ends with `/`.
       if (!root.hasScheme) {
         fatalError = true;
-      } else if (!root.path.endsWith("/")) {
-        root = root.replace(path: root.path + "/");
+      } else if (!root.path.endsWith('/')) {
+        root = root.replace(path: root.path + '/');
       }
     }
     if (packageUriRoot == null) {
@@ -220,13 +234,13 @@
       if (!isAbsoluteDirectoryUri(packageUriRoot)) {
         onError(PackageConfigArgumentError(
             packageUriRoot,
-            "packageUriRoot",
-            "In package $name: Not an absolute URI with no query or fragment "
-                "with a path ending in /"));
+            'packageUriRoot',
+            'In package $name: Not an absolute URI with no query or fragment '
+                'with a path ending in /'));
         packageUriRoot = root;
       } else if (!isUriPrefix(root, packageUriRoot)) {
-        onError(PackageConfigArgumentError(packageUriRoot, "packageUriRoot",
-            "The package URI root is not below the package root"));
+        onError(PackageConfigArgumentError(packageUriRoot, 'packageUriRoot',
+            'The package URI root is not below the package root'));
         packageUriRoot = root;
       }
     }
@@ -243,7 +257,7 @@
 /// Reports a format exception on [onError] if not, or if the numbers
 /// are too large (at most 32-bit signed integers).
 LanguageVersion parseLanguageVersion(
-    String? source, void onError(Object error)) {
+    String? source, void Function(Object error) onError) {
   var index = 0;
   // Reads a positive decimal numeral. Returns the value of the numeral,
   // or a negative number in case of an error.
@@ -254,7 +268,7 @@
   int readNumeral() {
     const maxValue = 0x7FFFFFFF;
     if (index == source!.length) {
-      onError(PackageConfigFormatException("Missing number", source, index));
+      onError(PackageConfigFormatException('Missing number', source, index));
       return -1;
     }
     var start = index;
@@ -262,7 +276,7 @@
     var char = source.codeUnitAt(index);
     var digit = char ^ 0x30;
     if (digit > 9) {
-      onError(PackageConfigFormatException("Missing number", source, index));
+      onError(PackageConfigFormatException('Missing number', source, index));
       return -1;
     }
     var firstDigit = digit;
@@ -271,7 +285,7 @@
       value = value * 10 + digit;
       if (value > maxValue) {
         onError(
-            PackageConfigFormatException("Number too large", source, start));
+            PackageConfigFormatException('Number too large', source, start));
         return -1;
       }
       index++;
@@ -281,7 +295,7 @@
     } while (digit <= 9);
     if (firstDigit == 0 && index > start + 1) {
       onError(PackageConfigFormatException(
-          "Leading zero not allowed", source, start));
+          'Leading zero not allowed', source, start));
     }
     return value;
   }
@@ -301,13 +315,14 @@
   }
   if (index != source.length) {
     onError(PackageConfigFormatException(
-        "Unexpected trailing character", source, index));
+        'Unexpected trailing character', source, index));
     return SimpleInvalidLanguageVersion(source);
   }
   return SimpleLanguageVersion(major, minor, source);
 }
 
 abstract class _SimpleLanguageVersionBase implements LanguageVersion {
+  @override
   int compareTo(LanguageVersion other) {
     var result = major.compareTo(other.major);
     if (result != 0) return result;
@@ -316,26 +331,34 @@
 }
 
 class SimpleLanguageVersion extends _SimpleLanguageVersionBase {
+  @override
   final int major;
+  @override
   final int minor;
   String? _source;
   SimpleLanguageVersion(this.major, this.minor, this._source);
 
+  @override
   bool operator ==(Object other) =>
       other is LanguageVersion && major == other.major && minor == other.minor;
 
+  @override
   int get hashCode => (major * 17 ^ minor * 37) & 0x3FFFFFFF;
 
-  String toString() => _source ??= "$major.$minor";
+  @override
+  String toString() => _source ??= '$major.$minor';
 }
 
 class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase
     implements InvalidLanguageVersion {
   final String? _source;
   SimpleInvalidLanguageVersion(this._source);
+  @override
   int get major => -1;
+  @override
   int get minor => -1;
 
+  @override
   String toString() => _source!;
 }
 
@@ -374,6 +397,7 @@
   /// there is no tree object associated with it.
   Map<String, MutablePackageTree>? _packageChildren;
 
+  @override
   Iterable<Package> get allPackages sync* {
     for (var package in packages) {
       yield package;
@@ -399,7 +423,8 @@
   ///
   /// The packages are added in order of their root path.
   /// It is never necessary to insert a node between two existing levels.
-  void add(int start, SimplePackage package, void onError(Object error)) {
+  void add(
+      int start, SimplePackage package, void Function(Object error) onError) {
     var path = package.root.toString();
     for (var treePackage in packages) {
       // Check is package is inside treePackage.
@@ -428,6 +453,7 @@
     packages.add(package);
   }
 
+  @override
   SimplePackage? packageOf(Uri file) {
     return findPackageOf(0, file.toString());
   }
@@ -471,8 +497,10 @@
 class EmptyPackageTree implements PackageTree {
   const EmptyPackageTree();
 
+  @override
   Iterable<Package> get allPackages => const Iterable<Package>.empty();
 
+  @override
   SimplePackage? packageOf(Uri file) => null;
 }
 
diff --git a/lib/src/package_config_io.dart b/lib/src/package_config_io.dart
index d3e59be..9aed621 100644
--- a/lib/src/package_config_io.dart
+++ b/lib/src/package_config_io.dart
@@ -4,31 +4,31 @@
 
 // dart:io dependent functionality for reading and writing configuration files.
 
-import "dart:convert";
-import "dart:io";
-import "dart:typed_data";
+import 'dart:convert';
+import 'dart:io';
+import 'dart:typed_data';
 
-import "errors.dart";
-import "package_config_impl.dart";
-import "package_config_json.dart";
-import "packages_file.dart" as packages_file;
-import "util.dart";
-import "util_io.dart";
+import 'errors.dart';
+import 'package_config_impl.dart';
+import 'package_config_json.dart';
+import 'packages_file.dart' as packages_file;
+import 'util.dart';
+import 'util_io.dart';
 
 /// Name of directory where Dart tools store their configuration.
 ///
 /// Directory is created in the package root directory.
-const dartToolDirName = ".dart_tool";
+const dartToolDirName = '.dart_tool';
 
 /// Name of file containing new package configuration data.
 ///
 /// File is stored in the dart tool directory.
-const packageConfigFileName = "package_config.json";
+const packageConfigFileName = 'package_config.json';
 
 /// Name of file containing legacy package configuration data.
 ///
 /// File is stored in the package root directory.
-const packagesFileName = ".packages";
+const packagesFileName = '.packages';
 
 /// Reads a package configuration file.
 ///
@@ -43,7 +43,7 @@
 ///
 /// The file must exist and be a normal file.
 Future<PackageConfig> readAnyConfigFile(
-    File file, bool preferNewest, void onError(Object error)) async {
+    File file, bool preferNewest, void Function(Object error) onError) async {
   if (preferNewest && fileName(file.path) == packagesFileName) {
     var alternateFile = File(
         pathJoin(dirName(file.path), dartToolDirName, packageConfigFileName));
@@ -64,21 +64,21 @@
 /// Like [readAnyConfigFile] but uses a URI and an optional loader.
 Future<PackageConfig> readAnyConfigFileUri(
     Uri file,
-    Future<Uint8List?> loader(Uri uri)?,
-    void onError(Object error),
+    Future<Uint8List?> Function(Uri uri)? loader,
+    void Function(Object error) onError,
     bool preferNewest) async {
-  if (file.isScheme("package")) {
+  if (file.isScheme('package')) {
     throw PackageConfigArgumentError(
-        file, "file", "Must not be a package: URI");
+        file, 'file', 'Must not be a package: URI');
   }
   if (loader == null) {
-    if (file.isScheme("file")) {
+    if (file.isScheme('file')) {
       return await readAnyConfigFile(File.fromUri(file), preferNewest, onError);
     }
     loader = defaultLoader;
   }
   if (preferNewest && file.pathSegments.last == packagesFileName) {
-    var alternateFile = file.resolve("$dartToolDirName/$packageConfigFileName");
+    var alternateFile = file.resolve('$dartToolDirName/$packageConfigFileName');
     Uint8List? bytes;
     try {
       bytes = await loader(alternateFile);
@@ -99,7 +99,7 @@
   }
   if (bytes == null) {
     onError(PackageConfigArgumentError(
-        file.toString(), "file", "File cannot be read"));
+        file.toString(), 'file', 'File cannot be read'));
     return const SimplePackageConfig.empty();
   }
   return parseAnyConfigFile(bytes, file, onError);
@@ -110,7 +110,7 @@
 /// Assumes it's a JSON file if the first non-whitespace character
 /// is `{`, otherwise assumes it's a `.packages` file.
 PackageConfig parseAnyConfigFile(
-    Uint8List bytes, Uri file, void onError(Object error)) {
+    Uint8List bytes, Uri file, void Function(Object error) onError) {
   var firstChar = firstNonWhitespaceChar(bytes);
   if (firstChar != $lbrace) {
     // Definitely not a JSON object, probably a .packages.
@@ -120,7 +120,7 @@
 }
 
 Future<PackageConfig> readPackageConfigJsonFile(
-    File file, void onError(Object error)) async {
+    File file, void Function(Object error) onError) async {
   Uint8List bytes;
   try {
     bytes = await file.readAsBytes();
@@ -132,7 +132,7 @@
 }
 
 Future<PackageConfig> readDotPackagesFile(
-    File file, void onError(Object error)) async {
+    File file, void Function(Object error) onError) async {
   Uint8List bytes;
   try {
     bytes = await file.readAsBytes();
diff --git a/lib/src/package_config_json.dart b/lib/src/package_config_json.dart
index 979c35e..1998b66 100644
--- a/lib/src/package_config_json.dart
+++ b/lib/src/package_config_json.dart
@@ -4,21 +4,21 @@
 
 // Parsing and serialization of package configurations.
 
-import "dart:convert";
-import "dart:typed_data";
+import 'dart:convert';
+import 'dart:typed_data';
 
-import "errors.dart";
-import "package_config_impl.dart";
-import "packages_file.dart" as packages_file;
-import "util.dart";
+import 'errors.dart';
+import 'package_config_impl.dart';
+import 'packages_file.dart' as packages_file;
+import 'util.dart';
 
-const String _configVersionKey = "configVersion";
-const String _packagesKey = "packages";
+const String _configVersionKey = 'configVersion';
+const String _packagesKey = 'packages';
 const List<String> _topNames = [_configVersionKey, _packagesKey];
-const String _nameKey = "name";
-const String _rootUriKey = "rootUri";
-const String _packageUriKey = "packageUri";
-const String _languageVersionKey = "languageVersion";
+const String _nameKey = 'name';
+const String _rootUriKey = 'rootUri';
+const String _packageUriKey = 'packageUri';
+const String _languageVersionKey = 'languageVersion';
 const List<String> _packageNames = [
   _nameKey,
   _rootUriKey,
@@ -26,14 +26,14 @@
   _languageVersionKey
 ];
 
-const String _generatedKey = "generated";
-const String _generatorKey = "generator";
-const String _generatorVersionKey = "generatorVersion";
+const String _generatedKey = 'generated';
+const String _generatorKey = 'generator';
+const String _generatorVersionKey = 'generatorVersion';
 
 final _jsonUtf8Decoder = json.fuse(utf8).decoder;
 
 PackageConfig parsePackageConfigBytes(
-    Uint8List bytes, Uri file, void onError(Object error)) {
+    Uint8List bytes, Uri file, void Function(Object error) onError) {
   // TODO(lrn): Make this simpler. Maybe parse directly from bytes.
   var jsonObject;
   try {
@@ -46,7 +46,7 @@
 }
 
 PackageConfig parsePackageConfigString(
-    String source, Uri file, void onError(Object error)) {
+    String source, Uri file, void Function(Object error) onError) {
   var jsonObject;
   try {
     jsonObject = jsonDecode(source);
@@ -80,21 +80,21 @@
 /// The [baseLocation] is used as base URI to resolve the "rootUri"
 /// URI referencestring.
 PackageConfig parsePackageConfigJson(
-    Object? json, Uri baseLocation, void onError(Object error)) {
-  if (!baseLocation.hasScheme || baseLocation.isScheme("package")) {
-    throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation",
-        "Must be an absolute non-package: URI");
+    Object? json, Uri baseLocation, void Function(Object error) onError) {
+  if (!baseLocation.hasScheme || baseLocation.isScheme('package')) {
+    throw PackageConfigArgumentError(baseLocation.toString(), 'baseLocation',
+        'Must be an absolute non-package: URI');
   }
 
-  if (!baseLocation.path.endsWith("/")) {
-    baseLocation = baseLocation.resolveUri(Uri(path: "."));
+  if (!baseLocation.path.endsWith('/')) {
+    baseLocation = baseLocation.resolveUri(Uri(path: '.'));
   }
 
   String typeName<T>() {
-    if (0 is T) return "int";
-    if ("" is T) return "string";
-    if (const [] is T) return "array";
-    return "object";
+    if (0 is T) return 'int';
+    if ('' is T) return 'string';
+    if (const [] is T) return 'array';
+    return 'object';
   }
 
   T? checkType<T>(Object? value, String name, [String? packageName]) {
@@ -103,7 +103,7 @@
     // and Map<String, Object?>. Recognize which to give a better error message.
     var message =
         "$name${packageName != null ? " of package $packageName" : ""}"
-        " is not a JSON ${typeName<T>()}";
+        ' is not a JSON ${typeName<T>()}';
     onError(PackageConfigFormatException(message, value));
     return null;
   }
@@ -140,27 +140,27 @@
       }
     });
     if (!hasName) {
-      onError(PackageConfigFormatException("Missing name entry", entry));
+      onError(PackageConfigFormatException('Missing name entry', entry));
     }
     if (!hasRoot) {
-      onError(PackageConfigFormatException("Missing rootUri entry", entry));
+      onError(PackageConfigFormatException('Missing rootUri entry', entry));
     }
     if (name == null || rootUri == null) return null;
     var parsedRootUri = Uri.parse(rootUri!);
     var relativeRoot = !hasAbsolutePath(parsedRootUri);
     var root = baseLocation.resolveUri(parsedRootUri);
-    if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/");
+    if (!root.path.endsWith('/')) root = root.replace(path: root.path + '/');
     var packageRoot = root;
     if (packageUri != null) packageRoot = root.resolve(packageUri!);
-    if (!packageRoot.path.endsWith("/")) {
-      packageRoot = packageRoot.replace(path: packageRoot.path + "/");
+    if (!packageRoot.path.endsWith('/')) {
+      packageRoot = packageRoot.replace(path: packageRoot.path + '/');
     }
 
     LanguageVersion? version;
     if (languageVersion != null) {
       version = parseLanguageVersion(languageVersion, onError);
     } else if (hasVersion) {
-      version = SimpleInvalidLanguageVersion("invalid");
+      version = SimpleInvalidLanguageVersion('invalid');
     }
 
     return SimplePackage.validate(
@@ -174,7 +174,7 @@
     });
   }
 
-  var map = checkType<Map<String, Object?>>(json, "value");
+  var map = checkType<Map<String, Object?>>(json, 'value');
   if (map == null) return const SimplePackageConfig.empty();
   Map<String, Object?>? extraData;
   List<Package>? packageList;
@@ -189,7 +189,7 @@
         var packages = <Package>[];
         for (var package in packageArray) {
           var packageMap =
-              checkType<Map<String, Object?>>(package, "package entry");
+              checkType<Map<String, Object?>>(package, 'package entry');
           if (packageMap != null) {
             var entry = parsePackage(packageMap);
             if (entry != null) {
@@ -205,11 +205,11 @@
     }
   });
   if (configVersion == null) {
-    onError(PackageConfigFormatException("Missing configVersion entry", json));
+    onError(PackageConfigFormatException('Missing configVersion entry', json));
     configVersion = 2;
   }
   if (packageList == null) {
-    onError(PackageConfigFormatException("Missing packages list", json));
+    onError(PackageConfigFormatException('Missing packages list', json));
     packageList = [];
   }
   return SimplePackageConfig(configVersion!, packageList!, extraData, (error) {
@@ -221,7 +221,7 @@
   });
 }
 
-final _jsonUtf8Encoder = JsonUtf8Encoder("  ");
+final _jsonUtf8Encoder = JsonUtf8Encoder('  ');
 
 void writePackageConfigJsonUtf8(
     PackageConfig config, Uri? baseUri, Sink<List<int>> output) {
@@ -234,7 +234,7 @@
     PackageConfig config, Uri? baseUri, StringSink output) {
   // Can be optimized.
   var data = packageConfigToJson(config, baseUri);
-  output.write(JsonEncoder.withIndent("  ").convert(data));
+  output.write(JsonEncoder.withIndent('  ').convert(data));
 }
 
 Map<String, Object?> packageConfigToJson(PackageConfig config, Uri? baseUri) =>
@@ -270,7 +270,7 @@
     if (generator is String) {
       var generated = extraData[_generatedKey];
       var generatorVersion = extraData[_generatorVersionKey];
-      comment = "Generated by $generator"
+      comment = 'Generated by $generator'
           "${generatorVersion is String ? " $generatorVersion" : ""}"
           "${generated is String ? " on $generated" : ""}.";
     }
diff --git a/lib/src/packages_file.dart b/lib/src/packages_file.dart
index ddcf856..2446633 100644
--- a/lib/src/packages_file.dart
+++ b/lib/src/packages_file.dart
@@ -2,10 +2,10 @@
 // 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 "package_config_impl.dart";
+import 'package_config_impl.dart';
 
-import "util.dart";
-import "errors.dart";
+import 'util.dart';
+import 'errors.dart';
 
 /// The language version prior to the release of language versioning.
 ///
@@ -31,10 +31,10 @@
 /// [Package.packageUriRoot] is the same as its [Package.root]
 /// and it has no [Package.languageVersion].
 PackageConfig parse(
-    List<int> source, Uri baseLocation, void onError(Object error)) {
-  if (baseLocation.isScheme("package")) {
+    List<int> source, Uri baseLocation, void Function(Object error) onError) {
+  if (baseLocation.isScheme('package')) {
     onError(PackageConfigArgumentError(
-        baseLocation, "baseLocation", "Must not be a package: URI"));
+        baseLocation, 'baseLocation', 'Must not be a package: URI'));
     return PackageConfig.empty;
   }
   var index = 0;
@@ -51,7 +51,7 @@
     }
     if (char == $colon) {
       onError(PackageConfigFormatException(
-          "Missing package name", source, index - 1));
+          'Missing package name', source, index - 1));
       ignoreLine = true; // Ignore if package name is invalid.
     } else {
       ignoreLine = char == $hash; // Ignore if comment.
@@ -81,16 +81,16 @@
     var invalidIndex = checkPackageName(packageName);
     if (invalidIndex >= 0) {
       onError(PackageConfigFormatException(
-          "Not a valid package name", source, start + invalidIndex));
+          'Not a valid package name', source, start + invalidIndex));
       continue;
     }
     if (queryStart >= 0) {
       onError(PackageConfigFormatException(
-          "Location URI must not have query", source, queryStart));
+          'Location URI must not have query', source, queryStart));
       end = queryStart;
     } else if (fragmentStart >= 0) {
       onError(PackageConfigFormatException(
-          "Location URI must not have fragment", source, fragmentStart));
+          'Location URI must not have fragment', source, fragmentStart));
       end = fragmentStart;
     }
     var packageValue = String.fromCharCodes(source, separatorIndex + 1, end);
@@ -103,23 +103,23 @@
     }
     var relativeRoot = !hasAbsolutePath(packageLocation);
     packageLocation = baseLocation.resolveUri(packageLocation);
-    if (packageLocation.isScheme("package")) {
+    if (packageLocation.isScheme('package')) {
       onError(PackageConfigFormatException(
-          "Package URI as location for package", source, separatorIndex + 1));
+          'Package URI as location for package', source, separatorIndex + 1));
       continue;
     }
     var path = packageLocation.path;
     if (!path.endsWith('/')) {
-      path += "/";
+      path += '/';
       packageLocation = packageLocation.replace(path: path);
     }
     if (packageNames.contains(packageName)) {
       onError(PackageConfigFormatException(
-          "Same package name occured more than once", source, start));
+          'Same package name occured more than once', source, start));
       continue;
     }
     var rootUri = packageLocation;
-    if (path.endsWith("/lib/")) {
+    if (path.endsWith('/lib/')) {
       // Assume default Pub package layout. Include package itself in root.
       rootUri =
           packageLocation.replace(path: path.substring(0, path.length - 4));
@@ -158,7 +158,7 @@
 void write(StringSink output, PackageConfig config,
     {Uri? baseUri, String? comment}) {
   if (baseUri != null && !baseUri.isAbsolute) {
-    throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute");
+    throw PackageConfigArgumentError(baseUri, 'baseUri', 'Must be absolute');
   }
 
   if (comment != null) {
@@ -169,7 +169,7 @@
       output.writeln(commentLine);
     }
   } else {
-    output.write("# generated by package:package_config at ");
+    output.write('# generated by package:package_config at ');
     output.write(DateTime.now());
     output.writeln();
   }
@@ -179,11 +179,11 @@
     // Validate packageName.
     if (!isValidPackageName(packageName)) {
       throw PackageConfigArgumentError(
-          config, "config", '"$packageName" is not a valid package name');
+          config, 'config', '"$packageName" is not a valid package name');
     }
-    if (uri.scheme == "package") {
+    if (uri.scheme == 'package') {
       throw PackageConfigArgumentError(
-          config, "config", "Package location must not be a package URI: $uri");
+          config, 'config', 'Package location must not be a package URI: $uri');
     }
     output.write(packageName);
     output.write(':');
diff --git a/lib/src/util.dart b/lib/src/util.dart
index f490cdc..61488ac 100644
--- a/lib/src/util.dart
+++ b/lib/src/util.dart
@@ -5,13 +5,13 @@
 /// Utility methods used by more than one library in the package.
 library package_config.util;
 
-import "errors.dart";
+import 'errors.dart';
 
 // All ASCII characters that are valid in a package name, with space
 // for all the invalid ones (including space).
 const String _validPackageNameCharacters =
     r"                                 !  $ &'()*+,-. 0123456789 ; =  "
-    r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ abcdefghijklmnopqrstuvwxyz   ~ ";
+    r'@ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ abcdefghijklmnopqrstuvwxyz   ~ ';
 
 /// Tests whether something is a valid Dart package name.
 bool isValidPackageName(String string) {
@@ -47,17 +47,17 @@
 /// Returns the package name extracted from the package URI,
 /// which is the path segment between `package:` and the first `/`.
 String checkValidPackageUri(Uri packageUri, String name) {
-  if (packageUri.scheme != "package") {
-    throw PackageConfigArgumentError(packageUri, name, "Not a package: URI");
+  if (packageUri.scheme != 'package') {
+    throw PackageConfigArgumentError(packageUri, name, 'Not a package: URI');
   }
   if (packageUri.hasAuthority) {
     throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a host part");
+        packageUri, name, 'Package URIs must not have a host part');
   }
   if (packageUri.hasQuery) {
     // A query makes no sense if resolved to a file: URI.
     throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a query part");
+        packageUri, name, 'Package URIs must not have a query part');
   }
   if (packageUri.hasFragment) {
     // We could leave the fragment after the URL when resolving,
@@ -65,7 +65,7 @@
     // "package:foo/foo.dart#2" were considered different libraries.
     // Keep the syntax open in case we ever get multiple libraries in one file.
     throw PackageConfigArgumentError(
-        packageUri, name, "Package URIs must not have a fragment part");
+        packageUri, name, 'Package URIs must not have a fragment part');
   }
   if (packageUri.path.startsWith('/')) {
     throw PackageConfigArgumentError(
@@ -81,7 +81,7 @@
   if (badIndex >= 0) {
     if (packageName.isEmpty) {
       throw PackageConfigArgumentError(
-          packageUri, name, "Package names mus be non-empty");
+          packageUri, name, 'Package names mus be non-empty');
     }
     if (badIndex == packageName.length) {
       throw PackageConfigArgumentError(packageUri, name,
@@ -89,13 +89,13 @@
     }
     assert(badIndex < packageName.length);
     var badCharCode = packageName.codeUnitAt(badIndex);
-    var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0');
+    var badChar = 'U+' + badCharCode.toRadixString(16).padLeft(4, '0');
     if (badCharCode >= 0x20 && badCharCode <= 0x7e) {
       // Printable character.
       badChar = "'${packageName[badIndex]}' ($badChar)";
     }
     throw PackageConfigArgumentError(
-        packageUri, name, "Package names must not contain $badChar");
+        packageUri, name, 'Package names must not contain $badChar');
   }
   return packageName;
 }
@@ -110,7 +110,7 @@
   if (uri.hasFragment) return false;
   if (!uri.hasScheme) return false;
   var path = uri.path;
-  if (!path.endsWith("/")) return false;
+  if (!path.endsWith('/')) return false;
   return true;
 }
 
@@ -139,8 +139,8 @@
 
 /// Appends a trailing `/` if the path doesn't end with one.
 String trailingSlash(String path) {
-  if (path.isEmpty || path.endsWith("/")) return path;
-  return path + "/";
+  if (path.isEmpty || path.endsWith('/')) return path;
+  return path + '/';
 }
 
 /// Whether a URI should not be considered relative to the base URI.
@@ -212,15 +212,15 @@
   }
   if (index == base.length) {
     if (index == target.length) {
-      return Uri(path: "./");
+      return Uri(path: './');
     }
     return Uri(path: target.skip(index).join('/'));
   } else if (index > 0) {
     var buffer = StringBuffer();
     for (var n = base.length - index; n > 0; --n) {
-      buffer.write("../");
+      buffer.write('../');
     }
-    buffer.writeAll(target.skip(index), "/");
+    buffer.writeAll(target.skip(index), '/');
     return Uri(path: buffer.toString());
   } else {
     return uri;
diff --git a/lib/src/util_io.dart b/lib/src/util_io.dart
index 9c48f04..914ea38 100644
--- a/lib/src/util_io.dart
+++ b/lib/src/util_io.dart
@@ -10,7 +10,7 @@
 import 'dart:typed_data';
 
 Future<Uint8List?> defaultLoader(Uri uri) async {
-  if (uri.isScheme("file")) {
+  if (uri.isScheme('file')) {
     var file = File.fromUri(uri);
     try {
       return await file.readAsBytes();
@@ -18,14 +18,14 @@
       return null;
     }
   }
-  if (uri.isScheme("http") || uri.isScheme("https")) {
+  if (uri.isScheme('http') || uri.isScheme('https')) {
     return _httpGet(uri);
   }
-  throw UnsupportedError("Default URI unsupported scheme: $uri");
+  throw UnsupportedError('Default URI unsupported scheme: $uri');
 }
 
 Future<Uint8List?> _httpGet(Uri uri) async {
-  assert(uri.isScheme("http") || uri.isScheme("https"));
+  assert(uri.isScheme('http') || uri.isScheme('https'));
   var client = HttpClient();
   var request = await client.getUrl(uri);
   var response = await request.close();
@@ -72,7 +72,7 @@
 String dirName(String path) {
   var separator = Platform.pathSeparator;
   var lastSeparator = path.lastIndexOf(separator);
-  if (lastSeparator < 0) return "";
+  if (lastSeparator < 0) return '';
   return path.substring(0, lastSeparator);
 }
 
@@ -82,12 +82,12 @@
 /// inserted.
 String pathJoin(String part1, String part2, [String? part3]) {
   var separator = Platform.pathSeparator;
-  var separator1 = part1.endsWith(separator) ? "" : separator;
+  var separator1 = part1.endsWith(separator) ? '' : separator;
   if (part3 == null) {
-    return "$part1$separator1$part2";
+    return '$part1$separator1$part2';
   }
-  var separator2 = part2.endsWith(separator) ? "" : separator;
-  return "$part1$separator1$part2$separator2$part3";
+  var separator2 = part2.endsWith(separator) ? '' : separator;
+  return '$part1$separator1$part2$separator2$part3';
 }
 
 /// Join an unknown number of path parts with [Platform.pathSeparator].
@@ -96,13 +96,13 @@
 /// inserted.
 String pathJoinAll(Iterable<String> parts) {
   var buffer = StringBuffer();
-  var separator = "";
+  var separator = '';
   for (var part in parts) {
     buffer
       ..write(separator)
       ..write(part);
     separator =
-        part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator;
+        part.endsWith(Platform.pathSeparator) ? '' : Platform.pathSeparator;
   }
   return buffer.toString();
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 1ee7250..687c3d3 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -10,8 +10,8 @@
   path: ^1.8.0
 
 dev_dependencies:
-  build_runner: ^1.10.0
-  build_test: ^1.3.0
-  build_web_compilers: ^2.12.2
+  build_runner: ^2.0.0
+  build_test: ^2.1.2
+  build_web_compilers: ^3.0.0
   pedantic: ^1.10.0
   test: ^1.16.0
diff --git a/test/discovery_test.dart b/test/discovery_test.dart
index df2374d..d2c3d83 100644
--- a/test/discovery_test.dart
+++ b/test/discovery_test.dart
@@ -5,21 +5,21 @@
 @TestOn('vm')
 library package_config.discovery_test;
 
-import "dart:io";
-import "package:test/test.dart";
-import "package:package_config/package_config.dart";
+import 'dart:io';
+import 'package:test/test.dart';
+import 'package:package_config/package_config.dart';
 
-import "src/util.dart";
-import "src/util_io.dart";
+import 'src/util.dart';
+import 'src/util_io.dart';
 
-const packagesFile = """
+const packagesFile = '''
 # A comment
 foo:file:///dart/packages/foo/
 bar:/dart/packages/bar/
 baz:packages/baz/
-""";
+''';
 
-const packageConfigFile = """
+const packageConfigFile = '''
 {
   "configVersion": 2,
   "packages": [
@@ -38,29 +38,29 @@
   ],
   "extra": [42]
 }
-""";
+''';
 
 void validatePackagesFile(PackageConfig resolver, Directory directory) {
   expect(resolver, isNotNull);
-  expect(resolver.resolve(pkg("foo", "bar/baz")),
-      equals(Uri.parse("file:///dart/packages/foo/bar/baz")));
-  expect(resolver.resolve(pkg("bar", "baz/qux")),
-      equals(Uri.parse("file:///dart/packages/bar/baz/qux")));
-  expect(resolver.resolve(pkg("baz", "qux/foo")),
-      equals(Uri.directory(directory.path).resolve("packages/baz/qux/foo")));
+  expect(resolver.resolve(pkg('foo', 'bar/baz')),
+      equals(Uri.parse('file:///dart/packages/foo/bar/baz')));
+  expect(resolver.resolve(pkg('bar', 'baz/qux')),
+      equals(Uri.parse('file:///dart/packages/bar/baz/qux')));
+  expect(resolver.resolve(pkg('baz', 'qux/foo')),
+      equals(Uri.directory(directory.path).resolve('packages/baz/qux/foo')));
   expect([for (var p in resolver.packages) p.name],
-      unorderedEquals(["foo", "bar", "baz"]));
+      unorderedEquals(['foo', 'bar', 'baz']));
 }
 
 void main() {
-  group("findPackages", () {
+  group('findPackages', () {
     // Finds package_config.json if there.
-    fileTest("package_config.json", {
-      ".packages": "invalid .packages file",
-      "script.dart": "main(){}",
-      "packages": {"shouldNotBeFound": {}},
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    fileTest('package_config.json', {
+      '.packages': 'invalid .packages file',
+      'script.dart': 'main(){}',
+      'packages': {'shouldNotBeFound': {}},
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       }
     }, (Directory directory) async {
       var config = (await findPackageConfig(directory))!;
@@ -69,10 +69,10 @@
     });
 
     // Finds .packages if no package_config.json.
-    fileTest(".packages", {
-      ".packages": packagesFile,
-      "script.dart": "main(){}",
-      "packages": {"shouldNotBeFound": {}}
+    fileTest('.packages', {
+      '.packages': packagesFile,
+      'script.dart': 'main(){}',
+      'packages': {'shouldNotBeFound': {}}
     }, (Directory directory) async {
       var config = (await findPackageConfig(directory))!;
       expect(config.version, 1); // Found .packages file.
@@ -80,68 +80,68 @@
     });
 
     // Finds package_config.json in super-directory.
-    fileTest("package_config.json recursive", {
-      ".packages": packagesFile,
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    fileTest('package_config.json recursive', {
+      '.packages': packagesFile,
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       },
-      "subdir": {
-        "script.dart": "main(){}",
+      'subdir': {
+        'script.dart': 'main(){}',
       }
     }, (Directory directory) async {
-      var config = (await findPackageConfig(subdir(directory, "subdir/")))!;
+      var config = (await findPackageConfig(subdir(directory, 'subdir/')))!;
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
     // Finds .packages in super-directory.
-    fileTest(".packages recursive", {
-      ".packages": packagesFile,
-      "subdir": {"script.dart": "main(){}"}
+    fileTest('.packages recursive', {
+      '.packages': packagesFile,
+      'subdir': {'script.dart': 'main(){}'}
     }, (Directory directory) async {
       var config;
-      config = await findPackageConfig(subdir(directory, "subdir/"));
+      config = await findPackageConfig(subdir(directory, 'subdir/'));
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
     // Does not find a packages/ directory, and returns null if nothing found.
-    fileTest("package directory packages not supported", {
-      "packages": {
-        "foo": {},
+    fileTest('package directory packages not supported', {
+      'packages': {
+        'foo': {},
       }
     }, (Directory directory) async {
       var config = await findPackageConfig(directory);
       expect(config, null);
     });
 
-    group("throws", () {
-      fileTest("invalid .packages", {
-        ".packages": "not a .packages file",
+    group('throws', () {
+      fileTest('invalid .packages', {
+        '.packages': 'not a .packages file',
       }, (Directory directory) {
         expect(findPackageConfig(directory),
             throwsA(TypeMatcher<FormatException>()));
       });
 
-      fileTest("invalid .packages as JSON", {
-        ".packages": packageConfigFile,
+      fileTest('invalid .packages as JSON', {
+        '.packages': packageConfigFile,
       }, (Directory directory) {
         expect(findPackageConfig(directory),
             throwsA(TypeMatcher<FormatException>()));
       });
 
-      fileTest("invalid .packages", {
-        ".dart_tool": {
-          "package_config.json": "not a JSON file",
+      fileTest('invalid .packages', {
+        '.dart_tool': {
+          'package_config.json': 'not a JSON file',
         }
       }, (Directory directory) {
         expect(findPackageConfig(directory),
             throwsA(TypeMatcher<FormatException>()));
       });
 
-      fileTest("invalid .packages as INI", {
-        ".dart_tool": {
-          "package_config.json": packagesFile,
+      fileTest('invalid .packages as INI', {
+        '.dart_tool': {
+          'package_config.json': packagesFile,
         }
       }, (Directory directory) {
         expect(findPackageConfig(directory),
@@ -149,9 +149,9 @@
       });
     });
 
-    group("handles error", () {
-      fileTest("invalid .packages", {
-        ".packages": "not a .packages file",
+    group('handles error', () {
+      fileTest('invalid .packages', {
+        '.packages': 'not a .packages file',
       }, (Directory directory) async {
         var hadError = false;
         await findPackageConfig(directory,
@@ -162,8 +162,8 @@
         expect(hadError, true);
       });
 
-      fileTest("invalid .packages as JSON", {
-        ".packages": packageConfigFile,
+      fileTest('invalid .packages as JSON', {
+        '.packages': packageConfigFile,
       }, (Directory directory) async {
         var hadError = false;
         await findPackageConfig(directory,
@@ -174,9 +174,9 @@
         expect(hadError, true);
       });
 
-      fileTest("invalid package_config not JSON", {
-        ".dart_tool": {
-          "package_config.json": "not a JSON file",
+      fileTest('invalid package_config not JSON', {
+        '.dart_tool': {
+          'package_config.json': 'not a JSON file',
         }
       }, (Directory directory) async {
         var hadError = false;
@@ -188,9 +188,9 @@
         expect(hadError, true);
       });
 
-      fileTest("invalid package config as INI", {
-        ".dart_tool": {
-          "package_config.json": packagesFile,
+      fileTest('invalid package config as INI', {
+        '.dart_tool': {
+          'package_config.json': packagesFile,
         }
       }, (Directory directory) async {
         var hadError = false;
@@ -204,86 +204,86 @@
     });
   });
 
-  group("loadPackageConfig", () {
+  group('loadPackageConfig', () {
     // Load a specific files
-    group("package_config.json", () {
+    group('package_config.json', () {
       var files = {
-        ".packages": packagesFile,
-        ".dart_tool": {
-          "package_config.json": packageConfigFile,
+        '.packages': packagesFile,
+        '.dart_tool': {
+          'package_config.json': packageConfigFile,
         },
       };
-      fileTest("directly", files, (Directory directory) async {
+      fileTest('directly', files, (Directory directory) async {
         var file =
-            dirFile(subdir(directory, ".dart_tool"), "package_config.json");
+            dirFile(subdir(directory, '.dart_tool'), 'package_config.json');
         var config = await loadPackageConfig(file);
         expect(config.version, 2);
         validatePackagesFile(config, directory);
       });
-      fileTest("indirectly through .packages", files,
+      fileTest('indirectly through .packages', files,
           (Directory directory) async {
-        var file = dirFile(directory, ".packages");
+        var file = dirFile(directory, '.packages');
         var config = await loadPackageConfig(file);
         expect(config.version, 2);
         validatePackagesFile(config, directory);
       });
-      fileTest("prefer .packages", files, (Directory directory) async {
-        var file = dirFile(directory, ".packages");
+      fileTest('prefer .packages', files, (Directory directory) async {
+        var file = dirFile(directory, '.packages');
         var config = await loadPackageConfig(file, preferNewest: false);
         expect(config.version, 1);
         validatePackagesFile(config, directory);
       });
     });
 
-    fileTest("package_config.json non-default name", {
-      ".packages": packagesFile,
-      "subdir": {
-        "pheldagriff": packageConfigFile,
+    fileTest('package_config.json non-default name', {
+      '.packages': packagesFile,
+      'subdir': {
+        'pheldagriff': packageConfigFile,
       },
     }, (Directory directory) async {
-      var file = dirFile(directory, "subdir/pheldagriff");
+      var file = dirFile(directory, 'subdir/pheldagriff');
       var config = await loadPackageConfig(file);
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
-    fileTest("package_config.json named .packages", {
-      "subdir": {
-        ".packages": packageConfigFile,
+    fileTest('package_config.json named .packages', {
+      'subdir': {
+        '.packages': packageConfigFile,
       },
     }, (Directory directory) async {
-      var file = dirFile(directory, "subdir/.packages");
+      var file = dirFile(directory, 'subdir/.packages');
       var config = await loadPackageConfig(file);
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
-    fileTest(".packages", {
-      ".packages": packagesFile,
+    fileTest('.packages', {
+      '.packages': packagesFile,
     }, (Directory directory) async {
-      var file = dirFile(directory, ".packages");
+      var file = dirFile(directory, '.packages');
       var config = await loadPackageConfig(file);
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
-    fileTest(".packages non-default name", {
-      "pheldagriff": packagesFile,
+    fileTest('.packages non-default name', {
+      'pheldagriff': packagesFile,
     }, (Directory directory) async {
-      var file = dirFile(directory, "pheldagriff");
+      var file = dirFile(directory, 'pheldagriff');
       var config = await loadPackageConfig(file);
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
-    fileTest("no config found", {}, (Directory directory) {
-      var file = dirFile(directory, "anyname");
+    fileTest('no config found', {}, (Directory directory) {
+      var file = dirFile(directory, 'anyname');
       expect(() => loadPackageConfig(file),
           throwsA(TypeMatcher<FileSystemException>()));
     });
 
-    fileTest("no config found, handled", {}, (Directory directory) async {
-      var file = dirFile(directory, "anyname");
+    fileTest('no config found, handled', {}, (Directory directory) async {
+      var file = dirFile(directory, 'anyname');
       var hadError = false;
       await loadPackageConfig(file,
           onError: expectAsync1((error) {
@@ -293,31 +293,31 @@
       expect(hadError, true);
     });
 
-    fileTest("specified file syntax error", {
-      "anyname": "syntax error",
+    fileTest('specified file syntax error', {
+      'anyname': 'syntax error',
     }, (Directory directory) {
-      var file = dirFile(directory, "anyname");
+      var file = dirFile(directory, 'anyname');
       expect(() => loadPackageConfig(file), throwsFormatException);
     });
 
     // Find package_config.json in subdir even if initial file syntax error.
-    fileTest("specified file syntax onError", {
-      ".packages": "syntax error",
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    fileTest('specified file syntax onError', {
+      '.packages': 'syntax error',
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       },
     }, (Directory directory) async {
-      var file = dirFile(directory, ".packages");
+      var file = dirFile(directory, '.packages');
       var config = await loadPackageConfig(file);
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
     // A file starting with `{` is a package_config.json file.
-    fileTest("file syntax error with {", {
-      ".packages": "{syntax error",
+    fileTest('file syntax error with {', {
+      '.packages': '{syntax error',
     }, (Directory directory) {
-      var file = dirFile(directory, ".packages");
+      var file = dirFile(directory, '.packages');
       expect(() => loadPackageConfig(file), throwsFormatException);
     });
   });
diff --git a/test/discovery_uri_test.dart b/test/discovery_uri_test.dart
index a895279..0a9b917 100644
--- a/test/discovery_uri_test.dart
+++ b/test/discovery_uri_test.dart
@@ -5,19 +5,19 @@
 @TestOn('vm')
 library package_config.discovery_test;
 
-import "package:test/test.dart";
-import "package:package_config/package_config.dart";
+import 'package:test/test.dart';
+import 'package:package_config/package_config.dart';
 
-import "src/util.dart";
+import 'src/util.dart';
 
-const packagesFile = """
+const packagesFile = '''
 # A comment
 foo:file:///dart/packages/foo/
 bar:/dart/packages/bar/
 baz:packages/baz/
-""";
+''';
 
-const packageConfigFile = """
+const packageConfigFile = '''
 {
   "configVersion": 2,
   "packages": [
@@ -36,29 +36,29 @@
   ],
   "extra": [42]
 }
-""";
+''';
 
 void validatePackagesFile(PackageConfig resolver, Uri directory) {
   expect(resolver, isNotNull);
-  expect(resolver.resolve(pkg("foo", "bar/baz")),
-      equals(Uri.parse("file:///dart/packages/foo/bar/baz")));
-  expect(resolver.resolve(pkg("bar", "baz/qux")),
-      equals(directory.resolve("/dart/packages/bar/baz/qux")));
-  expect(resolver.resolve(pkg("baz", "qux/foo")),
-      equals(directory.resolve("packages/baz/qux/foo")));
+  expect(resolver.resolve(pkg('foo', 'bar/baz')),
+      equals(Uri.parse('file:///dart/packages/foo/bar/baz')));
+  expect(resolver.resolve(pkg('bar', 'baz/qux')),
+      equals(directory.resolve('/dart/packages/bar/baz/qux')));
+  expect(resolver.resolve(pkg('baz', 'qux/foo')),
+      equals(directory.resolve('packages/baz/qux/foo')));
   expect([for (var p in resolver.packages) p.name],
-      unorderedEquals(["foo", "bar", "baz"]));
+      unorderedEquals(['foo', 'bar', 'baz']));
 }
 
 void main() {
-  group("findPackages", () {
+  group('findPackages', () {
     // Finds package_config.json if there.
-    loaderTest("package_config.json", {
-      ".packages": "invalid .packages file",
-      "script.dart": "main(){}",
-      "packages": {"shouldNotBeFound": {}},
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    loaderTest('package_config.json', {
+      '.packages': 'invalid .packages file',
+      'script.dart': 'main(){}',
+      'packages': {'shouldNotBeFound': {}},
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       }
     }, (directory, loader) async {
       var config = (await findPackageConfigUri(directory, loader: loader))!;
@@ -67,10 +67,10 @@
     });
 
     // Finds .packages if no package_config.json.
-    loaderTest(".packages", {
-      ".packages": packagesFile,
-      "script.dart": "main(){}",
-      "packages": {"shouldNotBeFound": {}}
+    loaderTest('.packages', {
+      '.packages': packagesFile,
+      'script.dart': 'main(){}',
+      'packages': {'shouldNotBeFound': {}}
     }, (directory, loader) async {
       var config = (await findPackageConfigUri(directory, loader: loader))!;
       expect(config.version, 1); // Found .packages file.
@@ -78,69 +78,69 @@
     });
 
     // Finds package_config.json in super-directory.
-    loaderTest("package_config.json recursive", {
-      ".packages": packagesFile,
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    loaderTest('package_config.json recursive', {
+      '.packages': packagesFile,
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       },
-      "subdir": {
-        "script.dart": "main(){}",
+      'subdir': {
+        'script.dart': 'main(){}',
       }
     }, (directory, loader) async {
-      var config = (await findPackageConfigUri(directory.resolve("subdir/"),
+      var config = (await findPackageConfigUri(directory.resolve('subdir/'),
           loader: loader))!;
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
     // Finds .packages in super-directory.
-    loaderTest(".packages recursive", {
-      ".packages": packagesFile,
-      "subdir": {"script.dart": "main(){}"}
+    loaderTest('.packages recursive', {
+      '.packages': packagesFile,
+      'subdir': {'script.dart': 'main(){}'}
     }, (directory, loader) async {
       var config;
-      config = await findPackageConfigUri(directory.resolve("subdir/"),
+      config = await findPackageConfigUri(directory.resolve('subdir/'),
           loader: loader);
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
     // Does not find a packages/ directory, and returns null if nothing found.
-    loaderTest("package directory packages not supported", {
-      "packages": {
-        "foo": {},
+    loaderTest('package directory packages not supported', {
+      'packages': {
+        'foo': {},
       }
     }, (Uri directory, loader) async {
       var config = await findPackageConfigUri(directory, loader: loader);
       expect(config, null);
     });
 
-    loaderTest("invalid .packages", {
-      ".packages": "not a .packages file",
+    loaderTest('invalid .packages', {
+      '.packages': 'not a .packages file',
     }, (Uri directory, loader) {
       expect(() => findPackageConfigUri(directory, loader: loader),
           throwsA(TypeMatcher<FormatException>()));
     });
 
-    loaderTest("invalid .packages as JSON", {
-      ".packages": packageConfigFile,
+    loaderTest('invalid .packages as JSON', {
+      '.packages': packageConfigFile,
     }, (Uri directory, loader) {
       expect(() => findPackageConfigUri(directory, loader: loader),
           throwsA(TypeMatcher<FormatException>()));
     });
 
-    loaderTest("invalid .packages", {
-      ".dart_tool": {
-        "package_config.json": "not a JSON file",
+    loaderTest('invalid .packages', {
+      '.dart_tool': {
+        'package_config.json': 'not a JSON file',
       }
     }, (Uri directory, loader) {
       expect(() => findPackageConfigUri(directory, loader: loader),
           throwsA(TypeMatcher<FormatException>()));
     });
 
-    loaderTest("invalid .packages as INI", {
-      ".dart_tool": {
-        "package_config.json": packagesFile,
+    loaderTest('invalid .packages as INI', {
+      '.dart_tool': {
+        'package_config.json': packagesFile,
       }
     }, (Uri directory, loader) {
       expect(() => findPackageConfigUri(directory, loader: loader),
@@ -148,80 +148,80 @@
     });
   });
 
-  group("loadPackageConfig", () {
+  group('loadPackageConfig', () {
     // Load a specific files
-    group("package_config.json", () {
+    group('package_config.json', () {
       var files = {
-        ".packages": packagesFile,
-        ".dart_tool": {
-          "package_config.json": packageConfigFile,
+        '.packages': packagesFile,
+        '.dart_tool': {
+          'package_config.json': packageConfigFile,
         },
       };
-      loaderTest("directly", files, (Uri directory, loader) async {
-        var file = directory.resolve(".dart_tool/package_config.json");
+      loaderTest('directly', files, (Uri directory, loader) async {
+        var file = directory.resolve('.dart_tool/package_config.json');
         var config = await loadPackageConfigUri(file, loader: loader);
         expect(config.version, 2);
         validatePackagesFile(config, directory);
       });
-      loaderTest("indirectly through .packages", files,
+      loaderTest('indirectly through .packages', files,
           (Uri directory, loader) async {
-        var file = directory.resolve(".packages");
+        var file = directory.resolve('.packages');
         var config = await loadPackageConfigUri(file, loader: loader);
         expect(config.version, 2);
         validatePackagesFile(config, directory);
       });
     });
 
-    loaderTest("package_config.json non-default name", {
-      ".packages": packagesFile,
-      "subdir": {
-        "pheldagriff": packageConfigFile,
+    loaderTest('package_config.json non-default name', {
+      '.packages': packagesFile,
+      'subdir': {
+        'pheldagriff': packageConfigFile,
       },
     }, (Uri directory, loader) async {
-      var file = directory.resolve("subdir/pheldagriff");
+      var file = directory.resolve('subdir/pheldagriff');
       var config = await loadPackageConfigUri(file, loader: loader);
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
-    loaderTest("package_config.json named .packages", {
-      "subdir": {
-        ".packages": packageConfigFile,
+    loaderTest('package_config.json named .packages', {
+      'subdir': {
+        '.packages': packageConfigFile,
       },
     }, (Uri directory, loader) async {
-      var file = directory.resolve("subdir/.packages");
+      var file = directory.resolve('subdir/.packages');
       var config = await loadPackageConfigUri(file, loader: loader);
       expect(config.version, 2);
       validatePackagesFile(config, directory);
     });
 
-    loaderTest(".packages", {
-      ".packages": packagesFile,
+    loaderTest('.packages', {
+      '.packages': packagesFile,
     }, (Uri directory, loader) async {
-      var file = directory.resolve(".packages");
+      var file = directory.resolve('.packages');
       var config = await loadPackageConfigUri(file, loader: loader);
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
-    loaderTest(".packages non-default name", {
-      "pheldagriff": packagesFile,
+    loaderTest('.packages non-default name', {
+      'pheldagriff': packagesFile,
     }, (Uri directory, loader) async {
-      var file = directory.resolve("pheldagriff");
+      var file = directory.resolve('pheldagriff');
       var config = await loadPackageConfigUri(file, loader: loader);
       expect(config.version, 1);
       validatePackagesFile(config, directory);
     });
 
-    loaderTest("no config found", {}, (Uri directory, loader) {
-      var file = directory.resolve("anyname");
+    loaderTest('no config found', {}, (Uri directory, loader) {
+      var file = directory.resolve('anyname');
       expect(() => loadPackageConfigUri(file, loader: loader),
           throwsA(isA<ArgumentError>()));
     });
 
-    loaderTest("no config found, handle error", {},
+    loaderTest('no config found, handle error', {},
         (Uri directory, loader) async {
-      var file = directory.resolve("anyname");
+      var file = directory.resolve('anyname');
       var hadError = false;
       await loadPackageConfigUri(file,
           loader: loader,
@@ -232,18 +232,18 @@
       expect(hadError, true);
     });
 
-    loaderTest("specified file syntax error", {
-      "anyname": "syntax error",
+    loaderTest('specified file syntax error', {
+      'anyname': 'syntax error',
     }, (Uri directory, loader) {
-      var file = directory.resolve("anyname");
+      var file = directory.resolve('anyname');
       expect(() => loadPackageConfigUri(file, loader: loader),
           throwsFormatException);
     });
 
-    loaderTest("specified file syntax onError", {
-      "anyname": "syntax error",
+    loaderTest('specified file syntax onError', {
+      'anyname': 'syntax error',
     }, (directory, loader) async {
-      var file = directory.resolve("anyname");
+      var file = directory.resolve('anyname');
       var hadError = false;
       await loadPackageConfigUri(file,
           loader: loader,
@@ -255,22 +255,22 @@
     });
 
     // Don't look for package_config.json if original file not named .packages.
-    loaderTest("specified file syntax error with alternative", {
-      "anyname": "syntax error",
-      ".dart_tool": {
-        "package_config.json": packageConfigFile,
+    loaderTest('specified file syntax error with alternative', {
+      'anyname': 'syntax error',
+      '.dart_tool': {
+        'package_config.json': packageConfigFile,
       },
     }, (directory, loader) async {
-      var file = directory.resolve("anyname");
+      var file = directory.resolve('anyname');
       expect(() => loadPackageConfigUri(file, loader: loader),
           throwsFormatException);
     });
 
     // A file starting with `{` is a package_config.json file.
-    loaderTest("file syntax error with {", {
-      ".packages": "{syntax error",
+    loaderTest('file syntax error with {', {
+      '.packages': '{syntax error',
     }, (directory, loader) async {
-      var file = directory.resolve(".packages");
+      var file = directory.resolve('.packages');
       var hadError = false;
       await loadPackageConfigUri(file,
           loader: loader,
diff --git a/test/package_config_impl_test.dart b/test/package_config_impl_test.dart
index bb00d12..cef1217 100644
--- a/test/package_config_impl_test.dart
+++ b/test/package_config_impl_test.dart
@@ -2,39 +2,39 @@
 // 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 "dart:convert" show jsonDecode;
+import 'dart:convert' show jsonDecode;
 
-import "package:package_config/package_config_types.dart";
-import "package:test/test.dart";
-import "src/util.dart";
+import 'package:package_config/package_config_types.dart';
+import 'package:test/test.dart';
+import 'src/util.dart';
 
 void main() {
   var unique = Object();
-  var root = Uri.file("/tmp/root/");
+  var root = Uri.file('/tmp/root/');
 
-  group("LanguageVersion", () {
-    test("minimal", () {
+  group('LanguageVersion', () {
+    test('minimal', () {
       var version = LanguageVersion(3, 5);
       expect(version.major, 3);
       expect(version.minor, 5);
     });
 
-    test("negative major", () {
+    test('negative major', () {
       expect(() => LanguageVersion(-1, 1), throwsArgumentError);
     });
 
-    test("negative minor", () {
+    test('negative minor', () {
       expect(() => LanguageVersion(1, -1), throwsArgumentError);
     });
 
-    test("minimal parse", () {
-      var version = LanguageVersion.parse("3.5");
+    test('minimal parse', () {
+      var version = LanguageVersion.parse('3.5');
       expect(version.major, 3);
       expect(version.minor, 5);
     });
 
     void failParse(String name, String input) {
-      test("$name - error", () {
+      test('$name - error', () {
         expect(() => LanguageVersion.parse(input),
             throwsA(TypeMatcher<PackageConfigError>()));
         expect(() => LanguageVersion.parse(input), throwsFormatException);
@@ -47,37 +47,37 @@
       });
     }
 
-    failParse("Leading zero major", "01.1");
-    failParse("Leading zero minor", "1.01");
-    failParse("Sign+ major", "+1.1");
-    failParse("Sign- major", "-1.1");
-    failParse("Sign+ minor", "1.+1");
-    failParse("Sign- minor", "1.-1");
-    failParse("WhiteSpace 1", " 1.1");
-    failParse("WhiteSpace 2", "1 .1");
-    failParse("WhiteSpace 3", "1. 1");
-    failParse("WhiteSpace 4", "1.1 ");
+    failParse('Leading zero major', '01.1');
+    failParse('Leading zero minor', '1.01');
+    failParse('Sign+ major', '+1.1');
+    failParse('Sign- major', '-1.1');
+    failParse('Sign+ minor', '1.+1');
+    failParse('Sign- minor', '1.-1');
+    failParse('WhiteSpace 1', ' 1.1');
+    failParse('WhiteSpace 2', '1 .1');
+    failParse('WhiteSpace 3', '1. 1');
+    failParse('WhiteSpace 4', '1.1 ');
   });
 
-  group("Package", () {
-    test("minimal", () {
-      var package = Package("name", root, extraData: unique);
-      expect(package.name, "name");
+  group('Package', () {
+    test('minimal', () {
+      var package = Package('name', root, extraData: unique);
+      expect(package.name, 'name');
       expect(package.root, root);
       expect(package.packageUriRoot, root);
       expect(package.languageVersion, null);
       expect(package.extraData, same(unique));
     });
 
-    test("absolute package root", () {
+    test('absolute package root', () {
       var version = LanguageVersion(1, 1);
-      var absolute = root.resolve("foo/bar/");
-      var package = Package("name", root,
+      var absolute = root.resolve('foo/bar/');
+      var package = Package('name', root,
           packageUriRoot: absolute,
           relativeRoot: false,
           languageVersion: version,
           extraData: unique);
-      expect(package.name, "name");
+      expect(package.name, 'name');
       expect(package.root, root);
       expect(package.packageUriRoot, absolute);
       expect(package.languageVersion, version);
@@ -85,12 +85,12 @@
       expect(package.relativeRoot, false);
     });
 
-    test("relative package root", () {
-      var relative = Uri.parse("foo/bar/");
+    test('relative package root', () {
+      var relative = Uri.parse('foo/bar/');
       var absolute = root.resolveUri(relative);
-      var package = Package("name", root,
+      var package = Package('name', root,
           packageUriRoot: relative, relativeRoot: true, extraData: unique);
-      expect(package.name, "name");
+      expect(package.name, 'name');
       expect(package.root, root);
       expect(package.packageUriRoot, absolute);
       expect(package.relativeRoot, true);
@@ -98,89 +98,89 @@
       expect(package.extraData, same(unique));
     });
 
-    for (var badName in ["a/z", "a:z", "", "..."]) {
+    for (var badName in ['a/z', 'a:z', '', '...']) {
       test("Invalid name '$badName'", () {
         expect(() => Package(badName, root), throwsPackageConfigError);
       });
     }
 
-    test("Invalid root, not absolute", () {
+    test('Invalid root, not absolute', () {
       expect(
-          () => Package("name", Uri.parse("/foo/")), throwsPackageConfigError);
+          () => Package('name', Uri.parse('/foo/')), throwsPackageConfigError);
     });
 
-    test("Invalid root, not ending in slash", () {
-      expect(() => Package("name", Uri.parse("file:///foo")),
+    test('Invalid root, not ending in slash', () {
+      expect(() => Package('name', Uri.parse('file:///foo')),
           throwsPackageConfigError);
     });
 
-    test("invalid package root, not ending in slash", () {
-      expect(() => Package("name", root, packageUriRoot: Uri.parse("foo")),
+    test('invalid package root, not ending in slash', () {
+      expect(() => Package('name', root, packageUriRoot: Uri.parse('foo')),
           throwsPackageConfigError);
     });
 
-    test("invalid package root, not inside root", () {
-      expect(() => Package("name", root, packageUriRoot: Uri.parse("../baz/")),
+    test('invalid package root, not inside root', () {
+      expect(() => Package('name', root, packageUriRoot: Uri.parse('../baz/')),
           throwsPackageConfigError);
     });
   });
 
-  group("package config", () {
-    test("emtpy", () {
+  group('package config', () {
+    test('emtpy', () {
       var empty = PackageConfig([], extraData: unique);
       expect(empty.version, 2);
       expect(empty.packages, isEmpty);
       expect(empty.extraData, same(unique));
-      expect(empty.resolve(pkg("a", "b")), isNull);
+      expect(empty.resolve(pkg('a', 'b')), isNull);
     });
 
-    test("single", () {
-      var package = Package("name", root);
+    test('single', () {
+      var package = Package('name', root);
       var single = PackageConfig([package], extraData: unique);
       expect(single.version, 2);
       expect(single.packages, hasLength(1));
       expect(single.extraData, same(unique));
-      expect(single.resolve(pkg("a", "b")), isNull);
-      var resolved = single.resolve(pkg("name", "a/b"));
-      expect(resolved, root.resolve("a/b"));
+      expect(single.resolve(pkg('a', 'b')), isNull);
+      var resolved = single.resolve(pkg('name', 'a/b'));
+      expect(resolved, root.resolve('a/b'));
     });
   });
-  test("writeString", () {
+  test('writeString', () {
     var config = PackageConfig([
-      Package("foo", Uri.parse("file:///pkg/foo/"),
-          packageUriRoot: Uri.parse("file:///pkg/foo/lib/"),
+      Package('foo', Uri.parse('file:///pkg/foo/'),
+          packageUriRoot: Uri.parse('file:///pkg/foo/lib/'),
           relativeRoot: false,
           languageVersion: LanguageVersion(2, 4),
-          extraData: {"foo": "foo!"}),
-      Package("bar", Uri.parse("file:///pkg/bar/"),
-          packageUriRoot: Uri.parse("file:///pkg/bar/lib/"),
+          extraData: {'foo': 'foo!'}),
+      Package('bar', Uri.parse('file:///pkg/bar/'),
+          packageUriRoot: Uri.parse('file:///pkg/bar/lib/'),
           relativeRoot: true,
-          extraData: {"bar": "bar!"}),
+          extraData: {'bar': 'bar!'}),
     ], extraData: {
-      "extra": "data"
+      'extra': 'data'
     });
     var buffer = StringBuffer();
-    PackageConfig.writeString(config, buffer, Uri.parse("file:///pkg/"));
+    PackageConfig.writeString(config, buffer, Uri.parse('file:///pkg/'));
     var text = buffer.toString();
     var json = jsonDecode(text); // Is valid JSON.
     expect(json, {
-      "configVersion": 2,
-      "packages": unorderedEquals([
+      'configVersion': 2,
+      'packages': unorderedEquals([
         {
-          "name": "foo",
-          "rootUri": "file:///pkg/foo/",
-          "packageUri": "lib/",
-          "languageVersion": "2.4",
-          "foo": "foo!",
+          'name': 'foo',
+          'rootUri': 'file:///pkg/foo/',
+          'packageUri': 'lib/',
+          'languageVersion': '2.4',
+          'foo': 'foo!',
         },
         {
-          "name": "bar",
-          "rootUri": "bar/",
-          "packageUri": "lib/",
-          "bar": "bar!",
+          'name': 'bar',
+          'rootUri': 'bar/',
+          'packageUri': 'lib/',
+          'bar': 'bar!',
         },
       ]),
-      "extra": "data",
+      'extra': 'data',
     });
   });
 }
diff --git a/test/parse_test.dart b/test/parse_test.dart
index ef73c2e..a163e12 100644
--- a/test/parse_test.dart
+++ b/test/parse_test.dart
@@ -2,61 +2,61 @@
 // 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 "dart:convert";
+import 'dart:convert';
 import 'dart:typed_data';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
-import "package:package_config/package_config_types.dart";
-import "package:package_config/src/packages_file.dart" as packages;
-import "package:package_config/src/package_config_json.dart";
-import "src/util.dart";
+import 'package:package_config/package_config_types.dart';
+import 'package:package_config/src/packages_file.dart' as packages;
+import 'package:package_config/src/package_config_json.dart';
+import 'src/util.dart';
 
 void throwError(Object error) => throw error;
 
 void main() {
-  group(".packages", () {
-    test("valid", () {
-      var packagesFile = "# Generated by pub yadda yadda\n"
-          "foo:file:///foo/lib/\n"
-          "bar:/bar/lib/\n"
-          "baz:lib/\n";
+  group('.packages', () {
+    test('valid', () {
+      var packagesFile = '# Generated by pub yadda yadda\n'
+          'foo:file:///foo/lib/\n'
+          'bar:/bar/lib/\n'
+          'baz:lib/\n';
       var result = packages.parse(utf8.encode(packagesFile),
-          Uri.parse("file:///tmp/file.dart"), throwError);
+          Uri.parse('file:///tmp/file.dart'), throwError);
       expect(result.version, 1);
-      expect({for (var p in result.packages) p.name}, {"foo", "bar", "baz"});
-      expect(result.resolve(pkg("foo", "foo.dart")),
-          Uri.parse("file:///foo/lib/foo.dart"));
-      expect(result.resolve(pkg("bar", "bar.dart")),
-          Uri.parse("file:///bar/lib/bar.dart"));
-      expect(result.resolve(pkg("baz", "baz.dart")),
-          Uri.parse("file:///tmp/lib/baz.dart"));
+      expect({for (var p in result.packages) p.name}, {'foo', 'bar', 'baz'});
+      expect(result.resolve(pkg('foo', 'foo.dart')),
+          Uri.parse('file:///foo/lib/foo.dart'));
+      expect(result.resolve(pkg('bar', 'bar.dart')),
+          Uri.parse('file:///bar/lib/bar.dart'));
+      expect(result.resolve(pkg('baz', 'baz.dart')),
+          Uri.parse('file:///tmp/lib/baz.dart'));
 
-      var foo = result["foo"]!;
+      var foo = result['foo']!;
       expect(foo, isNotNull);
-      expect(foo.root, Uri.parse("file:///foo/"));
-      expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/"));
+      expect(foo.root, Uri.parse('file:///foo/'));
+      expect(foo.packageUriRoot, Uri.parse('file:///foo/lib/'));
       expect(foo.languageVersion, LanguageVersion(2, 7));
       expect(foo.relativeRoot, false);
     });
 
-    test("valid empty", () {
-      var packagesFile = "# Generated by pub yadda yadda\n";
+    test('valid empty', () {
+      var packagesFile = '# Generated by pub yadda yadda\n';
       var result = packages.parse(
-          utf8.encode(packagesFile), Uri.file("/tmp/file.dart"), throwError);
+          utf8.encode(packagesFile), Uri.file('/tmp/file.dart'), throwError);
       expect(result.version, 1);
       expect({for (var p in result.packages) p.name}, <String>{});
     });
 
-    group("invalid", () {
-      var baseFile = Uri.file("/tmp/file.dart");
+    group('invalid', () {
+      var baseFile = Uri.file('/tmp/file.dart');
       void testThrows(String name, String content) {
         test(name, () {
           expect(
               () => packages.parse(utf8.encode(content), baseFile, throwError),
               throwsA(TypeMatcher<FormatException>()));
         });
-        test(name + ", handle error", () {
+        test(name + ', handle error', () {
           var hadError = false;
           packages.parse(utf8.encode(content), baseFile, (error) {
             hadError = true;
@@ -66,21 +66,21 @@
         });
       }
 
-      testThrows("repeated package name", "foo:lib/\nfoo:lib\n");
-      testThrows("no colon", "foo\n");
-      testThrows("empty package name", ":lib/\n");
-      testThrows("dot only package name", ".:lib/\n");
-      testThrows("dot only package name", "..:lib/\n");
-      testThrows("invalid package name character", "f\\o:lib/\n");
-      testThrows("package URI", "foo:package:bar/lib/");
-      testThrows("location with query", "f\\o:lib/?\n");
-      testThrows("location with fragment", "f\\o:lib/#\n");
+      testThrows('repeated package name', 'foo:lib/\nfoo:lib\n');
+      testThrows('no colon', 'foo\n');
+      testThrows('empty package name', ':lib/\n');
+      testThrows('dot only package name', '.:lib/\n');
+      testThrows('dot only package name', '..:lib/\n');
+      testThrows('invalid package name character', 'f\\o:lib/\n');
+      testThrows('package URI', 'foo:package:bar/lib/');
+      testThrows('location with query', 'f\\o:lib/?\n');
+      testThrows('location with fragment', 'f\\o:lib/#\n');
     });
   });
 
-  group("package_config.json", () {
-    test("valid", () {
-      var packageConfigFile = """
+  group('package_config.json', () {
+    test('valid', () {
+      var packageConfigFile = '''
         {
           "configVersion": 2,
           "packages": [
@@ -111,62 +111,62 @@
           "generator": "pub",
           "other": [42]
         }
-        """;
+        ''';
       var config = parsePackageConfigBytes(
           utf8.encode(packageConfigFile) as Uint8List,
-          Uri.parse("file:///tmp/.dart_tool/file.dart"),
+          Uri.parse('file:///tmp/.dart_tool/file.dart'),
           throwError);
       expect(config.version, 2);
       expect({for (var p in config.packages) p.name},
-          {"foo", "bar", "baz", "noslash"});
+          {'foo', 'bar', 'baz', 'noslash'});
 
-      expect(config.resolve(pkg("foo", "foo.dart")),
-          Uri.parse("file:///foo/lib/foo.dart"));
-      expect(config.resolve(pkg("bar", "bar.dart")),
-          Uri.parse("file:///bar/lib/bar.dart"));
-      expect(config.resolve(pkg("baz", "baz.dart")),
-          Uri.parse("file:///tmp/lib/baz.dart"));
+      expect(config.resolve(pkg('foo', 'foo.dart')),
+          Uri.parse('file:///foo/lib/foo.dart'));
+      expect(config.resolve(pkg('bar', 'bar.dart')),
+          Uri.parse('file:///bar/lib/bar.dart'));
+      expect(config.resolve(pkg('baz', 'baz.dart')),
+          Uri.parse('file:///tmp/lib/baz.dart'));
 
-      var foo = config["foo"]!;
+      var foo = config['foo']!;
       expect(foo, isNotNull);
-      expect(foo.root, Uri.parse("file:///foo/"));
-      expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/"));
+      expect(foo.root, Uri.parse('file:///foo/'));
+      expect(foo.packageUriRoot, Uri.parse('file:///foo/lib/'));
       expect(foo.languageVersion, LanguageVersion(2, 5));
-      expect(foo.extraData, {"nonstandard": true});
+      expect(foo.extraData, {'nonstandard': true});
       expect(foo.relativeRoot, false);
 
-      var bar = config["bar"]!;
+      var bar = config['bar']!;
       expect(bar, isNotNull);
-      expect(bar.root, Uri.parse("file:///bar/"));
-      expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/"));
+      expect(bar.root, Uri.parse('file:///bar/'));
+      expect(bar.packageUriRoot, Uri.parse('file:///bar/lib/'));
       expect(bar.languageVersion, LanguageVersion(9999, 9999));
       expect(bar.extraData, null);
       expect(bar.relativeRoot, false);
 
-      var baz = config["baz"]!;
+      var baz = config['baz']!;
       expect(baz, isNotNull);
-      expect(baz.root, Uri.parse("file:///tmp/"));
-      expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/"));
+      expect(baz.root, Uri.parse('file:///tmp/'));
+      expect(baz.packageUriRoot, Uri.parse('file:///tmp/lib/'));
       expect(baz.languageVersion, null);
       expect(baz.relativeRoot, true);
 
       // No slash after root or package root. One is inserted.
-      var noslash = config["noslash"]!;
+      var noslash = config['noslash']!;
       expect(noslash, isNotNull);
-      expect(noslash.root, Uri.parse("file:///tmp/noslash/"));
-      expect(noslash.packageUriRoot, Uri.parse("file:///tmp/noslash/lib/"));
+      expect(noslash.root, Uri.parse('file:///tmp/noslash/'));
+      expect(noslash.packageUriRoot, Uri.parse('file:///tmp/noslash/lib/'));
       expect(noslash.languageVersion, null);
       expect(noslash.relativeRoot, true);
 
       expect(config.extraData, {
-        "generator": "pub",
-        "other": [42]
+        'generator': 'pub',
+        'other': [42]
       });
     });
 
-    test("valid other order", () {
+    test('valid other order', () {
       // The ordering in the file is not important.
-      var packageConfigFile = """
+      var packageConfigFile = '''
         {
           "generator": "pub",
           "other": [42],
@@ -191,23 +191,23 @@
           ],
           "configVersion": 2
         }
-        """;
+        ''';
       var config = parsePackageConfigBytes(
           utf8.encode(packageConfigFile) as Uint8List,
-          Uri.parse("file:///tmp/.dart_tool/file.dart"),
+          Uri.parse('file:///tmp/.dart_tool/file.dart'),
           throwError);
       expect(config.version, 2);
-      expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"});
+      expect({for (var p in config.packages) p.name}, {'foo', 'bar', 'baz'});
 
-      expect(config.resolve(pkg("foo", "foo.dart")),
-          Uri.parse("file:///foo/lib/foo.dart"));
-      expect(config.resolve(pkg("bar", "bar.dart")),
-          Uri.parse("file:///bar/lib/bar.dart"));
-      expect(config.resolve(pkg("baz", "baz.dart")),
-          Uri.parse("file:///tmp/lib/baz.dart"));
+      expect(config.resolve(pkg('foo', 'foo.dart')),
+          Uri.parse('file:///foo/lib/foo.dart'));
+      expect(config.resolve(pkg('bar', 'bar.dart')),
+          Uri.parse('file:///bar/lib/bar.dart'));
+      expect(config.resolve(pkg('baz', 'baz.dart')),
+          Uri.parse('file:///tmp/lib/baz.dart'));
       expect(config.extraData, {
-        "generator": "pub",
-        "other": [42]
+        'generator': 'pub',
+        'other': [42]
       });
     });
 
@@ -217,94 +217,94 @@
     var pkgs = '"packages":[]';
     var name = '"name":"foo"';
     var root = '"rootUri":"/foo/"';
-    test("minimal", () {
+    test('minimal', () {
       var config = parsePackageConfigBytes(
-          utf8.encode("{$cfg,$pkgs}") as Uint8List,
-          Uri.parse("file:///tmp/.dart_tool/file.dart"),
+          utf8.encode('{$cfg,$pkgs}') as Uint8List,
+          Uri.parse('file:///tmp/.dart_tool/file.dart'),
           throwError);
       expect(config.version, 2);
       expect(config.packages, isEmpty);
     });
-    test("minimal package", () {
+    test('minimal package', () {
       // A package must have a name and a rootUri, the remaining properties
       // are optional.
       var config = parsePackageConfigBytes(
           utf8.encode('{$cfg,"packages":[{$name,$root}]}') as Uint8List,
-          Uri.parse("file:///tmp/.dart_tool/file.dart"),
+          Uri.parse('file:///tmp/.dart_tool/file.dart'),
           throwError);
       expect(config.version, 2);
-      expect(config.packages.first.name, "foo");
+      expect(config.packages.first.name, 'foo');
     });
 
-    test("nested packages", () {
+    test('nested packages', () {
       var configBytes = utf8.encode(json.encode({
-        "configVersion": 2,
-        "packages": [
-          {"name": "foo", "rootUri": "/foo/", "packageUri": "lib/"},
-          {"name": "bar", "rootUri": "/foo/bar/", "packageUri": "lib/"},
-          {"name": "baz", "rootUri": "/foo/bar/baz/", "packageUri": "lib/"},
-          {"name": "qux", "rootUri": "/foo/qux/", "packageUri": "lib/"},
+        'configVersion': 2,
+        'packages': [
+          {'name': 'foo', 'rootUri': '/foo/', 'packageUri': 'lib/'},
+          {'name': 'bar', 'rootUri': '/foo/bar/', 'packageUri': 'lib/'},
+          {'name': 'baz', 'rootUri': '/foo/bar/baz/', 'packageUri': 'lib/'},
+          {'name': 'qux', 'rootUri': '/foo/qux/', 'packageUri': 'lib/'},
         ]
       }));
       var config = parsePackageConfigBytes(configBytes as Uint8List,
-          Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError);
+          Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError);
       expect(config.version, 2);
-      expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart"))!.name,
-          "foo");
-      expect(config.packageOf(Uri.parse("file:///foo/bar/lala.dart"))!.name,
-          "bar");
-      expect(config.packageOf(Uri.parse("file:///foo/bar/baz/lala.dart"))!.name,
-          "baz");
-      expect(config.packageOf(Uri.parse("file:///foo/qux/lala.dart"))!.name,
-          "qux");
-      expect(config.toPackageUri(Uri.parse("file:///foo/lib/diz")),
-          Uri.parse("package:foo/diz"));
-      expect(config.toPackageUri(Uri.parse("file:///foo/bar/lib/diz")),
-          Uri.parse("package:bar/diz"));
-      expect(config.toPackageUri(Uri.parse("file:///foo/bar/baz/lib/diz")),
-          Uri.parse("package:baz/diz"));
-      expect(config.toPackageUri(Uri.parse("file:///foo/qux/lib/diz")),
-          Uri.parse("package:qux/diz"));
+      expect(config.packageOf(Uri.parse('file:///foo/lala/lala.dart'))!.name,
+          'foo');
+      expect(config.packageOf(Uri.parse('file:///foo/bar/lala.dart'))!.name,
+          'bar');
+      expect(config.packageOf(Uri.parse('file:///foo/bar/baz/lala.dart'))!.name,
+          'baz');
+      expect(config.packageOf(Uri.parse('file:///foo/qux/lala.dart'))!.name,
+          'qux');
+      expect(config.toPackageUri(Uri.parse('file:///foo/lib/diz')),
+          Uri.parse('package:foo/diz'));
+      expect(config.toPackageUri(Uri.parse('file:///foo/bar/lib/diz')),
+          Uri.parse('package:bar/diz'));
+      expect(config.toPackageUri(Uri.parse('file:///foo/bar/baz/lib/diz')),
+          Uri.parse('package:baz/diz'));
+      expect(config.toPackageUri(Uri.parse('file:///foo/qux/lib/diz')),
+          Uri.parse('package:qux/diz'));
     });
 
-    group("invalid", () {
+    group('invalid', () {
       void testThrows(String name, String source) {
         test(name, () {
           expect(
               () => parsePackageConfigBytes(utf8.encode(source) as Uint8List,
-                  Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError),
+                  Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError),
               throwsA(TypeMatcher<FormatException>()));
         });
       }
 
-      testThrows("comment", '# comment\n {$cfg,$pkgs}');
-      testThrows(".packages file", 'foo:/foo\n');
-      testThrows("no configVersion", '{$pkgs}');
-      testThrows("no packages", '{$cfg}');
-      group("config version:", () {
-        testThrows("null", '{"configVersion":null,$pkgs}');
-        testThrows("string", '{"configVersion":"2",$pkgs}');
-        testThrows("array", '{"configVersion":[2],$pkgs}');
+      testThrows('comment', '# comment\n {$cfg,$pkgs}');
+      testThrows('.packages file', 'foo:/foo\n');
+      testThrows('no configVersion', '{$pkgs}');
+      testThrows('no packages', '{$cfg}');
+      group('config version:', () {
+        testThrows('null', '{"configVersion":null,$pkgs}');
+        testThrows('string', '{"configVersion":"2",$pkgs}');
+        testThrows('array', '{"configVersion":[2],$pkgs}');
       });
-      group("packages:", () {
-        testThrows("null", '{$cfg,"packages":null}');
-        testThrows("string", '{$cfg,"packages":"foo"}');
-        testThrows("object", '{$cfg,"packages":{}}');
+      group('packages:', () {
+        testThrows('null', '{$cfg,"packages":null}');
+        testThrows('string', '{$cfg,"packages":"foo"}');
+        testThrows('object', '{$cfg,"packages":{}}');
       });
-      group("packages entry:", () {
-        testThrows("null", '{$cfg,"packages":[null]}');
-        testThrows("string", '{$cfg,"packages":["foo"]}');
-        testThrows("array", '{$cfg,"packages":[[]]}');
+      group('packages entry:', () {
+        testThrows('null', '{$cfg,"packages":[null]}');
+        testThrows('string', '{$cfg,"packages":["foo"]}');
+        testThrows('array', '{$cfg,"packages":[[]]}');
       });
-      group("package", () {
-        testThrows("no name", '{$cfg,"packages":[{$root}]}');
-        group("name:", () {
-          testThrows("null", '{$cfg,"packages":[{"name":null,$root}]}');
-          testThrows("num", '{$cfg,"packages":[{"name":1,$root}]}');
-          testThrows("object", '{$cfg,"packages":[{"name":{},$root}]}');
-          testThrows("empty", '{$cfg,"packages":[{"name":"",$root}]}');
-          testThrows("one-dot", '{$cfg,"packages":[{"name":".",$root}]}');
-          testThrows("two-dot", '{$cfg,"packages":[{"name":"..",$root}]}');
+      group('package', () {
+        testThrows('no name', '{$cfg,"packages":[{$root}]}');
+        group('name:', () {
+          testThrows('null', '{$cfg,"packages":[{"name":null,$root}]}');
+          testThrows('num', '{$cfg,"packages":[{"name":1,$root}]}');
+          testThrows('object', '{$cfg,"packages":[{"name":{},$root}]}');
+          testThrows('empty', '{$cfg,"packages":[{"name":"",$root}]}');
+          testThrows('one-dot', '{$cfg,"packages":[{"name":".",$root}]}');
+          testThrows('two-dot', '{$cfg,"packages":[{"name":"..",$root}]}');
           testThrows(
               "invalid char '\\'", '{$cfg,"packages":[{"name":"\\",$root}]}');
           testThrows(
@@ -313,82 +313,82 @@
               "invalid char ' '", '{$cfg,"packages":[{"name":" ",$root}]}');
         });
 
-        testThrows("no root", '{$cfg,"packages":[{$name}]}');
-        group("root:", () {
-          testThrows("null", '{$cfg,"packages":[{$name,"rootUri":null}]}');
-          testThrows("num", '{$cfg,"packages":[{$name,"rootUri":1}]}');
-          testThrows("object", '{$cfg,"packages":[{$name,"rootUri":{}}]}');
-          testThrows("fragment", '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}');
-          testThrows("query", '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}');
-          testThrows("package-URI",
+        testThrows('no root', '{$cfg,"packages":[{$name}]}');
+        group('root:', () {
+          testThrows('null', '{$cfg,"packages":[{$name,"rootUri":null}]}');
+          testThrows('num', '{$cfg,"packages":[{$name,"rootUri":1}]}');
+          testThrows('object', '{$cfg,"packages":[{$name,"rootUri":{}}]}');
+          testThrows('fragment', '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}');
+          testThrows('query', '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}');
+          testThrows('package-URI',
               '{$cfg,"packages":[{$name,"rootUri":"package:x/x/"}]}');
         });
-        group("package-URI root:", () {
+        group('package-URI root:', () {
           testThrows(
-              "null", '{$cfg,"packages":[{$name,$root,"packageUri":null}]}');
-          testThrows("num", '{$cfg,"packages":[{$name,$root,"packageUri":1}]}');
+              'null', '{$cfg,"packages":[{$name,$root,"packageUri":null}]}');
+          testThrows('num', '{$cfg,"packages":[{$name,$root,"packageUri":1}]}');
           testThrows(
-              "object", '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}');
-          testThrows("fragment",
+              'object', '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}');
+          testThrows('fragment',
               '{$cfg,"packages":[{$name,$root,"packageUri":"x/#"}]}');
           testThrows(
-              "query", '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}');
-          testThrows("package: URI",
+              'query', '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}');
+          testThrows('package: URI',
               '{$cfg,"packages":[{$name,$root,"packageUri":"package:x/x/"}]}');
-          testThrows("not inside root",
+          testThrows('not inside root',
               '{$cfg,"packages":[{$name,$root,"packageUri":"../other/"}]}');
         });
-        group("language version", () {
-          testThrows("null",
+        group('language version', () {
+          testThrows('null',
               '{$cfg,"packages":[{$name,$root,"languageVersion":null}]}');
           testThrows(
-              "num", '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}');
-          testThrows("object",
+              'num', '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}');
+          testThrows('object',
               '{$cfg,"packages":[{$name,$root,"languageVersion":{}}]}');
-          testThrows("empty",
+          testThrows('empty',
               '{$cfg,"packages":[{$name,$root,"languageVersion":""}]}');
-          testThrows("non number.number",
+          testThrows('non number.number',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"x.1"}]}');
-          testThrows("number.non number",
+          testThrows('number.non number',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1.x"}]}');
-          testThrows("non number",
+          testThrows('non number',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"x"}]}');
-          testThrows("one number",
+          testThrows('one number',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1"}]}');
-          testThrows("three numbers",
+          testThrows('three numbers',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1.2.3"}]}');
-          testThrows("leading zero first",
+          testThrows('leading zero first',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"01.1"}]}');
-          testThrows("leading zero second",
+          testThrows('leading zero second',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1.01"}]}');
-          testThrows("trailing-",
+          testThrows('trailing-',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1-1"}]}');
-          testThrows("trailing+",
+          testThrows('trailing+',
               '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1+1"}]}');
         });
       });
-      testThrows("duplicate package name",
+      testThrows('duplicate package name',
           '{$cfg,"packages":[{$name,$root},{$name,"rootUri":"/other/"}]}');
-      testThrows("same roots",
+      testThrows('same roots',
           '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}');
       testThrows(
           // The roots of foo and bar are the same.
-          "same roots",
+          'same roots',
           '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}');
       testThrows(
           // The root of bar is inside the root of foo,
           // but the package root of foo is inside the root of bar.
-          "between root and lib",
+          'between root and lib',
           '{$cfg,"packages":['
               '{"name":"foo","rootUri":"/foo/","packageUri":"bar/lib/"},'
               '{"name":"bar","rootUri":"/foo/bar/"},"packageUri":"baz/lib"]}');
     });
   });
 
-  group("factories", () {
+  group('factories', () {
     void testConfig(String name, PackageConfig config, PackageConfig expected) {
       group(name, () {
-        test("structure", () {
+        test('structure', () {
           expect(config.version, expected.version);
           var expectedPackages = {for (var p in expected.packages) p.name};
           var actualPackages = {for (var p in config.packages) p.name};
@@ -396,20 +396,20 @@
         });
         for (var package in config.packages) {
           var name = package.name;
-          test("package $name", () {
+          test('package $name', () {
             var expectedPackage = expected[name]!;
             expect(expectedPackage, isNotNull);
-            expect(package.root, expectedPackage.root, reason: "root");
+            expect(package.root, expectedPackage.root, reason: 'root');
             expect(package.packageUriRoot, expectedPackage.packageUriRoot,
-                reason: "package root");
+                reason: 'package root');
             expect(package.languageVersion, expectedPackage.languageVersion,
-                reason: "languageVersion");
+                reason: 'languageVersion');
           });
         }
       });
     }
 
-    var configText = """
+    var configText = '''
      {"configVersion": 2, "packages": [
        {
          "name": "foo",
@@ -418,37 +418,37 @@
          "languageVersion": "1.2"
        }
      ]}
-    """;
-    var baseUri = Uri.parse("file:///start/");
+    ''';
+    var baseUri = Uri.parse('file:///start/');
     var config = PackageConfig([
-      Package("foo", Uri.parse("file:///start/foo/"),
-          packageUriRoot: Uri.parse("file:///start/foo/bar/"),
+      Package('foo', Uri.parse('file:///start/foo/'),
+          packageUriRoot: Uri.parse('file:///start/foo/bar/'),
           languageVersion: LanguageVersion(1, 2))
     ]);
     testConfig(
-        "string", PackageConfig.parseString(configText, baseUri), config);
+        'string', PackageConfig.parseString(configText, baseUri), config);
     testConfig(
-        "bytes",
+        'bytes',
         PackageConfig.parseBytes(
             Uint8List.fromList(configText.codeUnits), baseUri),
         config);
-    testConfig("json", PackageConfig.parseJson(jsonDecode(configText), baseUri),
+    testConfig('json', PackageConfig.parseJson(jsonDecode(configText), baseUri),
         config);
 
-    baseUri = Uri.parse("file:///start2/");
+    baseUri = Uri.parse('file:///start2/');
     config = PackageConfig([
-      Package("foo", Uri.parse("file:///start2/foo/"),
-          packageUriRoot: Uri.parse("file:///start2/foo/bar/"),
+      Package('foo', Uri.parse('file:///start2/foo/'),
+          packageUriRoot: Uri.parse('file:///start2/foo/bar/'),
           languageVersion: LanguageVersion(1, 2))
     ]);
     testConfig(
-        "string2", PackageConfig.parseString(configText, baseUri), config);
+        'string2', PackageConfig.parseString(configText, baseUri), config);
     testConfig(
-        "bytes2",
+        'bytes2',
         PackageConfig.parseBytes(
             Uint8List.fromList(configText.codeUnits), baseUri),
         config);
-    testConfig("json2",
+    testConfig('json2',
         PackageConfig.parseJson(jsonDecode(configText), baseUri), config);
   });
 }
diff --git a/test/src/util.dart b/test/src/util.dart
index 2b262e1..32e9217 100644
--- a/test/src/util.dart
+++ b/test/src/util.dart
@@ -5,13 +5,13 @@
 import 'dart:convert';
 import 'dart:typed_data';
 
-import "package:test/test.dart";
+import 'package:test/test.dart';
 
 /// Creates a package: URI.
 Uri pkg(String packageName, String packagePath) {
   var path =
       "$packageName${packagePath.startsWith('/') ? "" : "/"}$packagePath";
-  return Uri(scheme: "package", path: path);
+  return Uri(scheme: 'package', path: path);
 }
 
 // Remove if not used.
@@ -33,13 +33,16 @@
 /// Description is a map, each key is a file entry. If the value is a map,
 /// it's a subdirectory, otherwise it's a file and the value is the content
 /// as a string.
-void loaderTest(String name, Map<String, Object> description,
-    void loaderTest(Uri root, Future<Uint8List?> loader(Uri uri))) {
-  var root = Uri(scheme: "test", path: "/");
+void loaderTest(
+  String name,
+  Map<String, Object> description,
+  void Function(Uri root, Future<Uint8List?> Function(Uri) loader) loaderTest,
+) {
+  var root = Uri(scheme: 'test', path: '/');
   Future<Uint8List?> loader(Uri uri) async {
     var path = uri.path;
-    if (!uri.isScheme("test") || !path.startsWith("/")) return null;
-    var parts = path.split("/");
+    if (!uri.isScheme('test') || !path.startsWith('/')) return null;
+    var parts = path.split('/');
     Object? value = description;
     for (var i = 1; i < parts.length; i++) {
       if (value is! Map<String, Object?>) return null;
diff --git a/test/src/util_io.dart b/test/src/util_io.dart
index 37deee9..109dff1 100644
--- a/test/src/util_io.dart
+++ b/test/src/util_io.dart
@@ -2,10 +2,10 @@
 // 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 "dart:io";
+import 'dart:io';
 
-import "package:test/test.dart";
-import "package:package_config/src/util_io.dart";
+import 'package:test/test.dart';
+import 'package:package_config/src/util_io.dart';
 
 /// Creates a directory structure from [description] and runs [fileTest].
 ///
@@ -14,9 +14,9 @@
 /// as a string.
 /// Introduces a group to hold the [setUp]/[tearDown] logic.
 void fileTest(String name, Map<String, Object> description,
-    void fileTest(Directory directory)) {
-  group("file-test", () {
-    var tempDir = Directory.systemTemp.createTempSync("pkgcfgtest");
+    void Function(Directory directory) fileTest) {
+  group('file-test', () {
+    var tempDir = Directory.systemTemp.createTempSync('pkgcfgtest');
     setUp(() {
       _createFiles(tempDir, description);
     });
@@ -44,7 +44,7 @@
 // Creates temporary files in the target directory.
 void _createFiles(Directory target, Map<Object?, Object?> description) {
   description.forEach((name, content) {
-    var entryName = pathJoin(target.path, "$name");
+    var entryName = pathJoin(target.path, '$name');
     if (content is Map<Object?, Object?>) {
       _createFiles(Directory(entryName)..createSync(), content);
     } else {
@@ -55,7 +55,7 @@
 
 /// Creates a [Directory] for a subdirectory of [parent].
 Directory subdir(Directory parent, String dirName) =>
-    Directory(pathJoinAll([parent.path, ...dirName.split("/")]));
+    Directory(pathJoinAll([parent.path, ...dirName.split('/')]));
 
 /// Creates a [File] for an entry in the [directory] directory.
 File dirFile(Directory directory, String fileName) =>