canonicalize method Null safety

Future<Tuple3<AsyncImporter, Uri, Uri>?> canonicalize(
  1. Uri url,
  2. {AsyncImporter? baseImporter,
  3. Uri? baseUrl,
  4. bool forImport = false}

Canonicalizes url according to one of this cache's importers.

Returns the importer that was used to canonicalize url, the canonical URL, and the URL that was passed to the importer (which may be resolved relative to baseUrl if it's passed).

If baseImporter is non-null, this first tries to use baseImporter to canonicalize url (resolved relative to baseUrl if it's passed).

If any importers understand url, returns that importer as well as the canonicalized URL and the original URL (resolved relative to baseUrl if applicable). Otherwise, returns null.


Future<Tuple3<AsyncImporter, Uri, Uri>?> canonicalize(Uri url,
    {AsyncImporter? baseImporter,
    Uri? baseUrl,
    bool forImport = false}) async {
  if (baseImporter != null) {
    var relativeResult = await putIfAbsentAsync(_relativeCanonicalizeCache,
        Tuple4(url, forImport, baseImporter, baseUrl), () async {
      var resolvedUrl = baseUrl?.resolveUri(url) ?? url;
      var canonicalUrl =
          await _canonicalize(baseImporter, resolvedUrl, forImport);
      if (canonicalUrl != null) {
        return Tuple3(baseImporter, canonicalUrl, resolvedUrl);
    if (relativeResult != null) return relativeResult;

  return await putIfAbsentAsync(_canonicalizeCache, Tuple2(url, forImport),
      () async {
    for (var importer in _importers) {
      var canonicalUrl = await _canonicalize(importer, url, forImport);
      if (canonicalUrl != null) {
        return Tuple3(importer, canonicalUrl, url);

    return null;