void nullSafetyTags()

in lib/src/tag/tagger.dart [358:445]


  void nullSafetyTags(List<String> tags, List<Explanation> explanations) {
    const _nullSafeTag = 'is:null-safe';

    try {
      var foundIssues = false;

      final sdkConstraintFinder = PathFinder<String>(_packageGraph, (
        String packageDir,
      ) {
        final pubspec = _pubspecCache.pubspecOfPackage(packageDir);

        return pubspec.sdkConstraintStatus.hasOptedIntoNullSafety
            ? null
            : (path) => Explanation(
                  'Package is not null safe',
                  'Because:\n${PackageGraph.formatPath(path)} '
                      'that doesn\'t opt in to null safety',
                  tag: _nullSafeTag,
                );
      });

      final sdkConstraintResult =
          sdkConstraintFinder.findViolation(packageName);
      if (sdkConstraintResult != null) {
        explanations.add(sdkConstraintResult);
        foundIssues = true;
      } else {
        for (final runtime in Runtime.recognizedRuntimes) {
          final optOutViolationFinder = PathFinder<Uri>(
            LibraryGraph(_session, runtime.declaredVariables),
            (library) {
              if (library.scheme == 'dart-ext') return null;
              final resolvedPath = _session.uriConverter.uriToPath(library);
              if (resolvedPath == null) {
                return (path) => Explanation(
                      'Unable to access import.',
                      'Because:\n${LibraryGraph.formatPath(path)} where $library is inaccessible.',
                      tag: _nullSafeTag,
                    );
              }
              final unit = parsedUnitFromUri(_session, library);
              if (unit == null) return null;
              final languageVersionToken = unit.languageVersionToken;
              if (languageVersionToken == null) return null;
              // dart:ui has no package name. So we cannot trivially look it up in
              // the allowed experiments. We just assume it is opted in.
              if (!library.isScheme('package')) return null;
              if (!isNullSafety(Version(
                  languageVersionToken.major, languageVersionToken.minor, 0))) {
                return (path) => Explanation(
                      'Package is not null safe',
                      'Because:\n${LibraryGraph.formatPath(path)} where $library '
                          'is opting out from null safety.',
                      tag: _nullSafeTag,
                    );
              }
              return null;
            },
          );

          for (final library in _publicLibraries) {
            final nullSafetyResult =
                optOutViolationFinder.findViolation(library);
            if (nullSafetyResult != null) {
              explanations.add(nullSafetyResult);
              foundIssues = true;
            }
          }
          // If we have a problem one runtime, there is no need to explore the
          // other runtimes... Also if we do, we are likely to just duplicate
          // explanations.
          if (foundIssues) {
            break;
          }
        }
      }

      if (!foundIssues) {
        tags.add(_nullSafeTag);
      }
    } on TagException catch (e) {
      explanations.add(Explanation(
        'Tag detection failed.',
        e.message,
        tag: _nullSafeTag,
      ));
    }
  }