build static method

Future<BarrelImportCache> build({
  1. required Iterable<Reference> references,
  2. required PackageConfig? packageConfig,
  3. required AnalysisSession session,
})

Implementation

static Future<BarrelImportCache> build({
  required Iterable<Reference> references,
  required PackageConfig? packageConfig,
  required AnalysisSession session,
}) async {
  if (packageConfig == null) {
    return const BarrelImportCache.empty();
  }

  final lookup = <_LookupKey, String>{};
  final elements = <_LookupKey, Element>{};
  final exportChecks = <String, Future<LibraryElement?>>{};

  Future<LibraryElement?> libraryFor(String uri) {
    return exportChecks.putIfAbsent(uri, () async {
      final result = await session.getLibraryByUri(uri);
      return switch (result) {
        LibraryElementResult(:final element) => element,
        _ => null,
      };
    });
  }

  for (final ref in references) {
    if (ref.optional) {
      continue;
    }

    final packageUri = ref.lib.uri.toString();
    if (!packageUri.startsWith('package:')) {
      continue;
    }

    final element = ref.associatedElement;
    if (element case null) {
      continue;
    }

    final name = element.displayName;
    if (name.isEmpty || name.startsWith('_')) {
      continue;
    }

    final key = (packageUri, name);
    if (lookup.containsKey(key)) {
      continue;
    }

    for (final candidate in BarrelImport.candidates(packageUri, packageConfig)) {
      final barrel = await libraryFor(candidate);
      if (barrel != null && exportsElement(barrel, element, name)) {
        lookup[key] = candidate;
        elements[key] = element;
        break;
      }
    }
  }

  await _consolidatePackageBarrels(
    lookup: lookup,
    elements: elements,
    packageConfig: packageConfig,
    libraryFor: libraryFor,
  );

  await _preferCrossPackageBarrels(
    lookup: lookup,
    elements: elements,
    libraryFor: libraryFor,
  );

  return BarrelImportCache._(lookup);
}