// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// 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:typed_data';

import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/sdk/build_sdk_summary.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart'
    show AnalysisOptions, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/either.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer_utilities/check/check.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../resolution/context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(FileSystemStateTest);
    defineReflectiveTests(FileSystemState_BazelWorkspaceTest);
    defineReflectiveTests(FileSystemState_PubPackageTest);
  });
}

@reflectiveTest
class FileSystemState_BazelWorkspaceTest extends BazelWorkspaceResolutionTest {
  void test_getFileForUri_hasGenerated_askGeneratedFirst() async {
    var relPath = 'dart/my/test/a.dart';
    var writablePath = convertPath('$workspaceRootPath/$relPath');
    var generatedPath = convertPath('$workspaceRootPath/bazel-bin/$relPath');

    // This generated file should be used instead of the writable.
    newFile(generatedPath, '');

    var analysisDriver = driverFor(convertPath(testFilePath));

    var fsState = analysisDriver.fsState;

    // Prepare URI(s).
    var generatedUri = toUri(generatedPath);
    var writableUri = toUri(writablePath);

    // The file is the generated file.
    var generatedFile = fsState.getFileForUri(generatedUri).t1!;
    expect(generatedFile.uri, writableUri);
    expect(generatedFile.path, generatedPath);

    // The file is cached under the requested URI.
    var writableFile1 = fsState.getFileForUri(writableUri).t1!;
    var writableFile2 = fsState.getFileForUri(writableUri).t1!;
    expect(writableFile1, same(generatedFile));
    expect(writableFile2, same(generatedFile));
  }

  void test_getFileForUri_hasGenerated_askWritableFirst() async {
    var relPath = 'dart/my/test/a.dart';
    var writablePath = convertPath('$workspaceRootPath/$relPath');
    var generatedPath = convertPath('$workspaceRootPath/bazel-bin/$relPath');

    // This generated file should be used instead of the writable.
    newFile(generatedPath, '');

    var analysisDriver = driverFor(convertPath(testFilePath));

    var fsState = analysisDriver.fsState;

    // Prepare URI(s).
    var generatedUri = toUri(generatedPath);
    var writableUri = toUri(writablePath);

    // The file is cached under the requested URI.
    var writableFile1 = fsState.getFileForUri(writableUri).t1!;
    var writableFile2 = fsState.getFileForUri(writableUri).t1!;
    expect(writableFile2, same(writableFile1));

    // The file is the generated file.
    var generatedFile = fsState.getFileForUri(generatedUri).t1!;
    expect(generatedFile.uri, writableUri);
    expect(generatedFile.path, generatedPath);
    expect(writableFile2, same(generatedFile));
  }

  void test_getFileForUri_nestedLib_notCanonicalUri() async {
    var outerPath = convertPath('$workspaceRootPath/my/outer/lib/a.dart');
    var outerUri = Uri.parse('package:my.outer/a.dart');

    var innerPath = convertPath('/workspace/my/outer/lib/inner/lib/b.dart');
    var innerUri = Uri.parse('package:my.outer.lib.inner/b.dart');

    var analysisDriver = driverFor(outerPath);
    var fsState = analysisDriver.fsState;

    // User code might use such relative URI.
    var innerUri2 = outerUri.resolve('inner/lib/b.dart');
    expect(innerUri2, Uri.parse('package:my.outer/inner/lib/b.dart'));

    // However the returned file must use the canonical URI.
    var innerFile = fsState.getFileForUri(innerUri2).t1!;
    expect(innerFile.path, innerPath);
    expect(innerFile.uri, innerUri);
  }
}

@reflectiveTest
class FileSystemState_PubPackageTest extends PubPackageResolutionTest {
  FileState get _dartAsyncState {
    return fileStateForUriStr('dart:async');
  }

  FileState get _dartCoreState {
    return fileStateForUriStr('dart:core');
  }

  FileState get _dartMathState {
    return fileStateForUriStr('dart:math');
  }

  FileState fileStateFor(File file) {
    return fsStateFor(file).getFileForPath(file.path);
  }

  FileState fileStateForUri(Uri uri) {
    return fsStateFor(testFile).getFileForUri(uri).t1!;
  }

  FileState fileStateForUriStr(String uriStr) {
    final uri = Uri.parse(uriStr);
    return fileStateForUri(uri);
  }

  FileSystemState fsStateFor(File file) {
    return driverFor(file.path).fsState;
  }

  test_newFile_augmentation_augmentationExists_hasImport() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
import augment 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library augment 'b.dart';
''');

    final cState = fileStateFor(c);
    // We have not asked for `b.dart` yet, but it was found using URI.
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, b.path);
      expect(kind.augmented?.file.path, b.path);
    });

    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, [c]);
    // We have not asked for `a.dart` yet, but it was found using URI.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      expect(kind.augmented?.file.path, a.path);
    });

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    // Check `c.dart` again, now using the `b.dart` state.
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(bState);
      kind.assertLibrary(aState);
    });

    // Check `b.dart` again, now using the `a.dart` state.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });
  }

  test_newFile_augmentation_augmentationExists_hasImport_disconnected() async {
    final a = getFile('$testPackageLibPath/a.dart');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
import augment 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library augment 'b.dart';
''');

    final cState = fileStateFor(c);
    // We have not asked for `b.dart` yet, but it was found using URI.
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, b.path);
      expect(kind.augmented?.file.path, b.path);
    });

    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, [c]);
    // We have not asked for `a.dart` yet, but it was found using URI.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      // The file `a.dart` does not exist, so no import, so `null`.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });
    // Check `c.dart` again, now using the `b.dart` state.
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(bState);
      expect(kind.library, isNull);
    });

    // The file `a.dart` does not exist.
    final aState = fileStateFor(a);
    expect(aState.exists, isFalse);
    _assertAugmentationFiles(aState, []);
    // Check `b.dart` again, now using the `a.dart` state.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      // The URI can be resolved, it points at `a.dart` file.
      expect(kind.uriFile, same(aState));
      // The file `a.dart` does not exist, so no import, so `null`.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });
  }

  test_newFile_augmentation_augmentationExists_noImport() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library augment 'b.dart';
''');

    // We found `b.dart` from the augmentation file `c.dart`.
    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, b.path);
      // `b.dart` does not import `c.dart` as an augmentation.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // Reading `a.dart` does not change anything.
    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // `b.dart` does not import `c.dart` as an augmentation.
    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, []);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Check `c.dart` again, now using the `b.dart` state.
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(bState));
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });
  }

  test_newFile_augmentation_cycle1_augmentSelf() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'b.dart';
import augment 'b.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    // We can construct a cycle using augmentations.
    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, [b]);
    bState.assertKind((bKind) {
      bKind as AugmentationKnownFileStateKind;
      bKind.assertAugmented(bState);
      expect(bKind.library, isNull);
    });

    // The cycle does not prevent building of the library cycle.
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
      // TODO(scheglov) ask for the cycle signature
    });
  }

  test_newFile_augmentation_cycle2() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
import augment 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library augment 'b.dart';
import augment 'b.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, [c]);

    final cState = fileStateFor(c);
    _assertAugmentationFiles(cState, [b]);

    // We can construct a cycle using augmentations.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(bState);
      kind.assertLibrary(aState);
    });

    // The cycle does not prevent building of the library cycle.
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
      // TODO(scheglov) ask for the cycle signature
    });
  }

  test_newFile_augmentation_invalid() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library augment 'da:';
''');

    // The URI is invalid, so there is no way to discover the target.
    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as AugmentationUnknownFileStateKind;
      expect(kind.directive.uri, 'da:');
      expect(kind.library, isNull);
    });
  }

  test_newFile_augmentation_libraryExists_hasImport() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final bState = fileStateFor(b);
    // We have not asked for `a.dart` yet, but it was found using URI.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      expect(kind.augmented?.file.path, a.path);
    });

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);
    // Check `b.dart` again, now using the `a.dart` state.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });
  }

  test_newFile_augmentation_libraryExists_noImport() async {
    final a = newFile('$testPackageLibPath/a.dart', '');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, []);

    final bState = fileStateFor(b);
    // We can find `a.dart` using the URI.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      // But `a.dart` does not import `b.dart`.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // Refreshing `a.dart` does not change anything.
    aState.refresh();
    _assertAugmentationFiles(aState, []);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });
  }

  test_newFile_augmentation_targetNotExists() async {
    final a = getFile('$testPackageLibPath/a.dart');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final bState = fileStateFor(b);
    // We can find `a.dart` from `b.dart` using the URI.
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      // The file `a.dart` does not exist, so no import.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // We can get `a.dart`, but it does not exist.
    final aState = fileStateFor(a);
    expect(aState.exists, isFalse);
    _assertAugmentationFiles(aState, []);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      // The file `a.dart` does not exist, so no import.
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });
  }

  test_newFile_augmentation_twoLibraries() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'c.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
import augment 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library augment 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [c]);

    // We use the URI from `library augment` to find the augmentation target.
    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Reading `b.dart` does not update the augmentation.
    final bState = fileStateFor(b);
    _assertAugmentationFiles(bState, [c]);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Refreshing `a.dart` does not update the augmentation.
    aState.refresh();
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Refreshing `b.dart` does not update the augmentation.
    bState.refresh();
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Exclude from `a.dart`, the URI still points at `a.dart`.
    // But `c.dart` is not a valid augmentation anymore.
    newFile(a.path, '');
    aState.refresh();
    _assertAugmentationFiles(aState, []);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // Exclude from `b.dart`, still point at `a.dart`, still not valid.
    newFile(b.path, '');
    bState.refresh();
    _assertAugmentationFiles(bState, []);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // Include into `b.dart`, still point at `a.dart`, still not valid.
    newFile(b.path, r'''
import augment 'c.dart';
''');
    bState.refresh();
    _assertAugmentationFiles(bState, [c]);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.augmented, isNull);
      expect(kind.library, isNull);
    });

    // Include into `a.dart`, restore to `a.dart` as the target.
    newFile(a.path, r'''
import augment 'c.dart';
''');
    aState.refresh();
    _assertAugmentationFiles(aState, [c]);
    cState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });
  }

  test_newFile_doesNotExist() {
    final a = getFile('$testPackageLibPath/a.dart');

    final file = fileStateFor(a);
    expect(file.path, a.path);
    expect(file.uri, Uri.parse('package:test/a.dart'));
    expect(file.content, '');
    expect(file.exists, isFalse);

    file.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
      kind.assertLibrary(file);
      check(kind.imports).matches([
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isTrue,
      ]);
      check(kind.exports).isEmpty;
    });

    expect(file.exportedFiles, isEmpty);
    expect(file.partedFiles, isEmpty);
    expect(file.libraryFiles, [file]);
    expect(file.isPart, isFalse);
  }

  test_newFile_library_exports_dart() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
export 'dart:async';
export 'dart:math';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (export) => export.isLibrary(_dartAsyncState),
        (export) => export.isLibrary(_dartMathState),
      ]);
    });
  }

  test_newFile_library_exports_inSummary_library() async {
    // Prepare a bundle where `package:foo/foo.dart` is a library.
    final librarySummaryFiles = <File>[];
    {
      final fooRoot = getFolder('$workspaceRootPath/foo');

      newFile('${fooRoot.path}/lib/foo.dart', 'class F {}');

      final fooPackageConfigFile = getFile(
        '${fooRoot.path}/.dart_tool/package_config.json',
      );

      writePackageConfig(
        fooPackageConfigFile.path,
        PackageConfigFileBuilder()..add(name: 'foo', rootPath: fooRoot.path),
      );

      final analysisDriver = driverFor(fooRoot.path);
      final bundleBytes = await analysisDriver.buildPackageBundle(
        uriList: [
          Uri.parse('package:foo/foo.dart'),
        ],
      );

      final bundleFile = getFile('/home/summaries/packages.sum');
      bundleFile.writeAsBytesSync(bundleBytes);

      librarySummaryFiles.add(bundleFile);

      // Delete, so it is not available as a file.
      // We don't have a package config for it anyway, but just to be sure.
      fooRoot.delete();
    }

    // Prepare for recreating the collection, with summaries.
    sdkSummaryFile = await _writeSdkSummary();
    this.librarySummaryFiles = librarySummaryFiles;

    disposeAnalysisContextCollection();

    final a = newFile('$testPackageLibPath/a.dart', r'''
export 'dart:async';
export 'package:foo/foo.dart';
export 'b.dart';
''');

    final b = getFile('$testPackageLibPath/b.dart');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (import) {
          final expected = Uri.parse('dart:async');
          import.withInSummaryLibrary(expected);
        },
        (import) {
          final expected = Uri.parse('package:foo/foo.dart');
          import.withInSummaryLibrary(expected);
        },
        (import) => import.isLibrary(bState),
      ]);
    });
  }

  test_newFile_library_exports_inSummary_part() async {
    // Prepare a bundle where `package:foo/foo2.dart` is a part.
    final librarySummaryFiles = <File>[];
    {
      final fooRoot = getFolder('$workspaceRootPath/foo');

      newFile('${fooRoot.path}/lib/foo.dart', r'''
part 'foo2.dart';
''');

      newFile('${fooRoot.path}/lib/foo2.dart', r'''
part of 'foo.dart';
''');

      final fooPackageConfigFile = getFile(
        '${fooRoot.path}/.dart_tool/package_config.json',
      );

      writePackageConfig(
        fooPackageConfigFile.path,
        PackageConfigFileBuilder()..add(name: 'foo', rootPath: fooRoot.path),
      );

      final analysisDriver = driverFor(fooRoot.path);
      final bundleBytes = await analysisDriver.buildPackageBundle(
        uriList: [
          Uri.parse('package:foo/foo.dart'),
        ],
      );

      final bundleFile = getFile('/home/summaries/packages.sum');
      bundleFile.writeAsBytesSync(bundleBytes);

      librarySummaryFiles.add(bundleFile);

      // Delete, so it is not available as a file.
      // We don't have a package config for it anyway, but just to be sure.
      fooRoot.delete();
    }

    // Prepare for recreating the collection, with summaries.
    sdkSummaryFile = await _writeSdkSummary();
    this.librarySummaryFiles = librarySummaryFiles;

    disposeAnalysisContextCollection();

    final a = newFile('$testPackageLibPath/a.dart', r'''
export 'package:foo/foo2.dart';
export 'b.dart';
''');

    final b = getFile('$testPackageLibPath/b.dart');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (export) {
          final expected = Uri.parse('package:foo/foo2.dart');
          export.withInSummaryNotLibrary(expected);
        },
        (export) => export.isLibrary(bState),
      ]);
    });
  }

  test_newFile_library_exports_invalidRelativeUri() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
export '::net';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (export) => export.isNotFile(),
      ]);
    });
  }

  test_newFile_library_exports_package() async {
    final a = newFile('$testPackageLibPath/a.dart', '');
    final b = newFile('$testPackageLibPath/b.dart', '');

    final c = newFile('$testPackageLibPath/c.dart', r'''
export 'a.dart';
export 'package:test/b.dart';
''');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);
    final cState = fileStateFor(c);

    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (export) => export.isLibrary(aState),
        (export) => export.isLibrary(bState),
      ]);
    });
  }

  test_newFile_library_exports_part() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of my.lib;
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
export 'a.dart';
''');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.exports).matches([
        (export) => export.isFile(aState),
      ]);
    });
  }

  test_newFile_library_imports_library_augmentation() async {
    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
import 'b.dart';
''');

    final bState = fileStateFor(b);
    final cState = fileStateFor(c);

    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import.isFile(bState),
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isTrue,
      ]);
    });
  }

  test_newFile_library_imports_library_dart() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import 'dart:async';
import 'dart:math';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import.isLibrary(_dartAsyncState),
        (import) => import.isLibrary(_dartMathState),
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isTrue,
      ]);
    });
  }

  test_newFile_library_imports_library_dart_explicitDartCore() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import 'dart:core';
import 'dart:math';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isFalse,
        (import) => import.isLibrary(_dartMathState),
      ]);
    });
  }

  test_newFile_library_imports_library_inSummary_library() async {
    // Prepare a bundle where `package:foo/foo.dart` is a library.
    final librarySummaryFiles = <File>[];
    {
      final fooRoot = getFolder('$workspaceRootPath/foo');

      newFile('${fooRoot.path}/lib/foo.dart', 'class F {}');

      final fooPackageConfigFile = getFile(
        '${fooRoot.path}/.dart_tool/package_config.json',
      );

      writePackageConfig(
        fooPackageConfigFile.path,
        PackageConfigFileBuilder()..add(name: 'foo', rootPath: fooRoot.path),
      );

      final analysisDriver = driverFor(fooRoot.path);
      final bundleBytes = await analysisDriver.buildPackageBundle(
        uriList: [
          Uri.parse('package:foo/foo.dart'),
        ],
      );

      final bundleFile = getFile('/home/summaries/packages.sum');
      bundleFile.writeAsBytesSync(bundleBytes);

      librarySummaryFiles.add(bundleFile);

      // Delete, so it is not available as a file.
      // We don't have a package config for it anyway, but just to be sure.
      fooRoot.delete();
    }

    // Prepare for recreating the collection, with summaries.
    sdkSummaryFile = await _writeSdkSummary();
    this.librarySummaryFiles = librarySummaryFiles;

    disposeAnalysisContextCollection();

    final a = newFile('$testPackageLibPath/a.dart', r'''
import 'dart:async';
import 'package:foo/foo.dart';
import 'b.dart';
''');

    final b = getFile('$testPackageLibPath/b.dart');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) {
          final expected = Uri.parse('dart:async');
          import.withInSummaryLibrary(expected);
        },
        (import) {
          final expected = Uri.parse('package:foo/foo.dart');
          import.withInSummaryLibrary(expected);
        },
        (import) => import.isLibrary(bState),
        (import) {
          final expected = Uri.parse('dart:core');
          import
            ..withInSummaryLibrary(expected)
            ..isSyntheticDartCoreImport.isTrue;
        },
      ]);
    });
  }

  test_newFile_library_imports_library_inSummary_part() async {
    // Prepare a bundle where `package:foo/foo2.dart` is a part.
    final librarySummaryFiles = <File>[];
    {
      final fooRoot = getFolder('$workspaceRootPath/foo');

      newFile('${fooRoot.path}/lib/foo.dart', r'''
part 'foo2.dart';
''');

      newFile('${fooRoot.path}/lib/foo2.dart', r'''
part of 'foo.dart';
''');

      final fooPackageConfigFile = getFile(
        '${fooRoot.path}/.dart_tool/package_config.json',
      );

      writePackageConfig(
        fooPackageConfigFile.path,
        PackageConfigFileBuilder()..add(name: 'foo', rootPath: fooRoot.path),
      );

      final analysisDriver = driverFor(fooRoot.path);
      final bundleBytes = await analysisDriver.buildPackageBundle(
        uriList: [
          Uri.parse('package:foo/foo.dart'),
        ],
      );

      final bundleFile = getFile('/home/summaries/packages.sum');
      bundleFile.writeAsBytesSync(bundleBytes);

      librarySummaryFiles.add(bundleFile);

      // Delete, so it is not available as a file.
      // We don't have a package config for it anyway, but just to be sure.
      fooRoot.delete();
    }

    // Prepare for recreating the collection, with summaries.
    sdkSummaryFile = await _writeSdkSummary();
    this.librarySummaryFiles = librarySummaryFiles;

    disposeAnalysisContextCollection();

    final a = newFile('$testPackageLibPath/a.dart', r'''
import 'package:foo/foo2.dart';
import 'b.dart';
''');

    final b = getFile('$testPackageLibPath/b.dart');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (export) {
          final expected = Uri.parse('package:foo/foo2.dart');
          export.withInSummaryNotLibrary(expected);
        },
        (export) => export.isLibrary(bState),
        (export) {
          final expected = Uri.parse('dart:core');
          export
            ..withInSummaryLibrary(expected)
            ..isSyntheticDartCoreImport.isTrue;
        },
      ]);
    });
  }

  test_newFile_library_imports_library_invalidRelativeUri() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import '::net';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import.isNotFile(),
        (import) => import.isLibrary(_dartCoreState),
      ]);
    });
  }

  test_newFile_library_imports_library_package() async {
    final a = newFile('$testPackageLibPath/a.dart', '');
    final b = newFile('$testPackageLibPath/b.dart', '');

    final c = newFile('$testPackageLibPath/c.dart', r'''
import 'a.dart';
import 'package:test/b.dart';
''');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);
    final cState = fileStateFor(c);

    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import.isLibrary(aState),
        (import) => import.isLibrary(bState),
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isTrue,
      ]);
    });
  }

  test_newFile_library_imports_library_part() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of my.lib;
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
import 'a.dart';
''');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      check(kind.imports).matches([
        (import) => import.isFile(aState),
        (import) => import
          ..isLibrary(_dartCoreState)
          ..isSyntheticDartCoreImport.isTrue,
      ]);
    });
  }

  test_newFile_library_includePart_withoutPartOf() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
// no part of
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // Library `a.dart` includes `b.dart` as a part.
    _assertPartedFiles(aState, [b]);

    // But `b.dart` thinks that it is a library itself.
    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // Refreshing the library does not change this.
    aState.refresh();
    _assertPartedFiles(aState, [b]);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });
  }

  test_newFile_libraryDirective() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my;
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my');
      kind.assertLibrary(aState);
    });
  }

  test_newFile_noDirectives() async {
    final a = newFile('$testPackageLibPath/a.dart', '');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });
  }

  test_newFile_partOfName() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my.lib;
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of my.lib;
''');

    final bState = fileStateFor(b);

    // We don't know the library initially.
    // Even though the library file exists, we have not seen it yet.
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      expect(kind.directive.name, 'my.lib');
      expect(kind.libraries, isEmpty);
      expect(kind.library, isNull);
    });

    // Read the library file.
    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(aState, [b]);

    // Now the part knows its library.
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState]);
      kind.assertLibrary(aState);
    });
  }

  test_newFile_partOfName_differentName() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my.lib;
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of other.lib;
''');

    final bState = fileStateFor(b);

    // We don't know the library initially.
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      expect(kind.directive.name, 'other.lib');
      kind.assertLibraries([]);
      expect(kind.library, isNull);
    });

    // Read the library file.
    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(aState, [b]);

    // We still don't know the library, because the part wants `other.lib`,
    // but `a.dart` that includes `b.dart` has the name `my.lib`.
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([]);
      expect(kind.library, isNull);
    });
  }

  test_newFile_partOfName_twoLibraries() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my.lib;
part 'c.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library my.lib;
part 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
part of my.lib;
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(aState, [c]);

    // We set the library while reading `a.dart` file.
    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState]);
      kind.assertLibrary(aState);
    });

    // Reading `b.dart` does not update the part.
    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(bState, [c]);
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState, bState]);
      kind.assertLibrary(aState);
    });

    // Refreshing `b.dart` does not update the part.
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState, bState]);
      kind.assertLibrary(aState);
    });

    // Refreshing `a.dart` does not update the part.
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState, bState]);
      kind.assertLibrary(aState);
    });

    // Exclude the part from `a.dart`, switch to `b.dart` instead.
    newFile(a.path, '');
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([bState]);
      kind.assertLibrary(bState);
    });

    // Exclude the part from `b.dart`, no library.
    newFile(b.path, '');
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([]);
      expect(kind.library, isNull);
    });

    // Include into `b.dart`, use it as the library.
    newFile(b.path, r'''
library my.lib;
part 'c.dart';
''');
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([bState]);
      kind.assertLibrary(bState);
    });

    // Include into `a.dart`, switch to `a.dart`.
    newFile(a.path, r'''
library my.lib;
part 'c.dart';
''');
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState, bState]);
      kind.assertLibrary(aState);
    });
  }

  test_newFile_partOfUri_doesNotExist() async {
    final a = getFile('$testPackageLibPath/a.dart');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
''');

    final bState = fileStateFor(b);

    // The URI in `part of URI` tells us which library to use.
    // However it does not exist, so it does not include the file, so the
    // part file will not be analyzed during the library analysis.
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      expect(kind.library, isNull);
    });

    final aState = fileStateFor(a);
    expect(aState.exists, isFalse);
    _assertPartedFiles(aState, []);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
    });
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });

    // Create `a.dart` that includes the part file.
    newFile(a.path, r'''
part 'b.dart';
''');

    // The library file has already been read because of `part of uri`.
    // So, we explicitly refresh it.
    aState.refresh();
    _assertPartedFiles(aState, [b]);

    // Now the part file knows its library.
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });

    // Refreshing the part file does not break the kind.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });
  }

  test_newFile_partOfUri_exists_hasPart() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
''');

    final bState = fileStateFor(b);
    // We have not read the library file explicitly yet.
    // But it was read because of the `part of` directive.
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile.path, a.path);
      expect(kind.library?.file.path, a.path);
    });

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
    });
    _assertPartedFiles(aState, [b]);
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });

    // Refreshing the part file does not break the kind.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });
  }

  test_newFile_partOfUri_exists_noPart() async {
    final a = newFile('$testPackageLibPath/a.dart', '');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
''');

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    // The URI in `part of URI` tells us which library to use.
    // However `a.dart` does not include `b.dart` as a part, so `b.dart` will
    // not be analyzed during the library analysis.
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });
  }

  test_newFile_partOfUri_invalid() async {
    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'da:';
''');

    final bState = fileStateFor(b);

    // The URI is invalid, so there is no way to discover the library.
    bState.assertKind((kind) {
      kind as PartOfUriUnknownFileStateKind;
      expect(kind.directive.uri, 'da:');
    });

    // Reading a library that includes this part does not change the fact
    // that the URI in the `part of URI` in `b.dart` cannot be resolved.
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');
    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
    });
    _assertPartedFiles(aState, [b]);

    bState.assertKind((kind) {
      kind as PartOfUriUnknownFileStateKind;
      expect(kind.directive.uri, 'da:');
    });
  }

  test_newFile_partOfUri_twoLibraries() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'c.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
part of 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertPartedFiles(aState, [c]);

    // We set the library while reading `a.dart` file.
    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      kind.assertLibrary(aState);
    });

    // Reading `b.dart` does not update the part.
    final bState = fileStateFor(b);
    _assertPartedFiles(bState, [c]);
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      kind.assertLibrary(aState);
    });

    // Refreshing `b.dart` does not update the part.
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      kind.assertLibrary(aState);
    });

    // Refreshing `a.dart` does not update the part.
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      kind.assertLibrary(aState);
    });

    // Exclude the part from `a.dart`, but the URI in `part of` still resolves
    // to `a.dart`, so no changes.
    newFile(a.path, '');
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });

    // Exclude the part from `b.dart`, no changes.
    newFile(b.path, '');
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });

    // Include into `b.dart`, no changes.
    newFile(b.path, r'''
part 'c.dart';
''');
    bState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });

    // Include into `a.dart`, no changes.
    newFile(a.path, r'''
part 'c.dart';
''');
    aState.refresh();
    cState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });
  }

  test_refresh_augmentation_to_library() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Make it a library.
    newFile(b.path, '');

    // Not an augmentation anymore, but a library.
    bState.refresh();
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // But `a.dart` still uses `b.dart` as an augmentation.
    _assertAugmentationFiles(aState, [b]);

    // ...even if we attempt to refresh.
    aState.refresh();
    _assertAugmentationFiles(aState, [b]);
  }

  test_refresh_augmentation_to_partOfName() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my.lib;
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Make it a part.
    newFile(b.path, r'''
part of my.lib;
''');

    // Not an augmentation anymore, but a part.
    // This part can find the referenced library by name `my.lib`.
    // But the library does not include this part, so no library.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState]);
      expect(kind.library, isNull);
    });

    // But `a.dart` still uses `b.dart` as an augmentation.
    _assertAugmentationFiles(aState, [b]);
    _assertPartedFiles(aState, []);

    // ...even if we attempt to refresh.
    aState.refresh();
    _assertAugmentationFiles(aState, [b]);
    _assertPartedFiles(aState, []);

    // Now include `b.dart` into `a.dart` as a part.
    newFile(a.path, r'''
library my.lib;
part 'b.dart';
''');
    aState.refresh();

    // ...not an augmentation, but a known part.
    _assertAugmentationFiles(aState, []);
    _assertPartedFiles(aState, [b]);
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState]);
      kind.assertLibrary(aState);
    });
  }

  test_refresh_augmentation_to_partOfUri() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library augment 'a.dart';
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // Make it a part.
    newFile(b.path, r'''
part of 'a.dart';
''');

    // Not an augmentation anymore, but a part.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      expect(kind.library, isNull);
    });

    // But `a.dart` still uses `b.dart` as an augmentation.
    _assertAugmentationFiles(aState, [b]);
    _assertPartedFiles(aState, []);

    // ...even if we attempt to refresh.
    aState.refresh();
    _assertAugmentationFiles(aState, [b]);
    _assertPartedFiles(aState, []);

    // Now include `b.dart` into `a.dart` as a part.
    newFile(a.path, r'''
part 'b.dart';
''');
    aState.refresh();

    // ...not an augmentation, but a known part.
    _assertAugmentationFiles(aState, []);
    _assertPartedFiles(aState, [b]);
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });
  }

  test_refresh_library_removePart_partOfName() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of my;
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of my;
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library my;
part 'a.dart';
part 'b.dart';
''');

    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my');
    });
    _assertPartedFiles(cState, [a, b]);

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    // Both part files know the library.
    aState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([cState]);
      kind.assertLibrary(cState);
    });
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([cState]);
      kind.assertLibrary(cState);
    });

    newFile(c.path, r'''
library my;
part 'b.dart';
''');

    // Stop referencing `a.dart` part file.
    cState.refresh();
    _assertPartedFiles(cState, [b]);

    // The library does not include `a.dart` as a part anymore.
    // The part `b.dart` is still connected.
    aState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([cState]);
      expect(kind.library, isNull);
    });
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([cState]);
      kind.assertLibrary(cState);
    });
  }

  test_refresh_library_removePart_partOfUri() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of 'c.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'c.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library my;
part 'a.dart';
part 'b.dart';
''');

    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my');
    });
    _assertPartedFiles(cState, [a, b]);

    final aState = fileStateFor(a);
    final bState = fileStateFor(b);

    // Both part files know the library.
    aState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, cState);
      kind.assertLibrary(cState);
    });
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, cState);
      kind.assertLibrary(cState);
    });

    newFile(c.path, r'''
library my;
part 'b.dart';
''');

    // Stop referencing `a.dart` part file.
    cState.refresh();
    _assertPartedFiles(cState, [b]);

    // But the URIs in the `part of URI` are still the same.
    // So, both parts are still linked to the library.
    aState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(cState));
      expect(kind.library, isNull);
    });
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, cState);
      kind.assertLibrary(cState);
    });
  }

  test_refresh_library_to_augmentation() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
import augment 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library b;
''');

    final aState = fileStateFor(a);
    _assertAugmentationFiles(aState, [b]);

    // TODO(scheglov) Restore.
    // final aCycle_1 = aState.libraryCycle;

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'b');
    });

    newFile(b.path, r'''
library augment 'a.dart';
''');

    // We will discover the target by URI.
    bState.refresh();
    bState.assertKind((kind) {
      kind as AugmentationKnownFileStateKind;
      kind.assertAugmented(aState);
      kind.assertLibrary(aState);
    });

    // The file `b.dart` was something else, but now it is a known augmentation.
    // This affects libraries that include it.
    // TODO(scheglov) Restore.
    // final aCycle_2 = aState.libraryCycle;
    // expect(aCycle_2.apiSignature, isNot(aCycle_1.apiSignature));
  }

  test_refresh_library_to_partOfName() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my.lib;
part 'b.dart';
''');

    // No `part of`, so it is a library.
    final b = newFile('$testPackageLibPath/b.dart', '');

    final aState = fileStateFor(a);
    _assertPartedFiles(aState, [b]);

    final aCycle_1 = aState.libraryCycle;

    // No `part of`, so it is a library.
    // It does not matter, that `a.dart` tried to use it as part.
    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // Make it a part.
    newFile(b.path, r'''
part of my.lib;
''');

    // We will discover the library by name.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      kind.assertLibraries([aState]);
      kind.assertLibrary(aState);
    });

    // The file `b.dart` was something else, but now it is a known part.
    // This affects libraries that include it.
    final aCycle_2 = aState.libraryCycle;
    expect(aCycle_2.apiSignature, isNot(aCycle_1.apiSignature));
  }

  test_refresh_library_to_partOfName_noLibrary() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
library my;
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my');
    });

    newFile(a.path, r'''
part of my;
''');

    aState.refresh();

    // No library that includes it, so it stays unknown.
    aState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      expect(kind.directive.name, 'my');
      kind.assertLibraries([]);
      expect(kind.library, isNull);
    });
  }

  test_refresh_library_to_partOfUri() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library b;
''');

    final aState = fileStateFor(a);
    _assertPartedFiles(aState, [b]);

    final aCycle_1 = aState.libraryCycle;

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'b');
    });

    newFile(b.path, r'''
part of 'a.dart';
''');

    // We will discover the library using the URI.
    bState.refresh();
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });

    // The file `b.dart` was something else, but now it is a known part.
    // This affects libraries that include it.
    final aCycle_2 = aState.libraryCycle;
    expect(aCycle_2.apiSignature, isNot(aCycle_1.apiSignature));
  }

  test_refresh_partOfName_twoLibraries() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of my.lib;
class A1 {}
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
library my.lib;
part 'a.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
library my.lib;
part 'a.dart';
''');

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(bState, [a]);

    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, 'my.lib');
    });
    _assertPartedFiles(cState, [a]);

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      expect(kind.directive.name, 'my.lib');
      kind.assertLibraries([bState, cState]);
      kind.assertLibrary(bState);
    });

    final bCycle_1 = bState.libraryCycle;
    final cCycle_1 = cState.libraryCycle;

    // Update `a.dart` part.
    newFile(a.path, r'''
part of my.lib;
class A2 {}
''');
    aState.refresh();
    // `a.dart` is still a part.
    aState.assertKind((kind) {
      kind as PartOfNameFileStateKind;
      expect(kind.directive.name, 'my.lib');
      kind.assertLibraries([bState, cState]);
      kind.assertLibrary(bState);
    });

    // ...but the unlinked signature of `a.dart` is different.
    // We invalidate `b.dart` it references `a.dart`.
    // We invalidate `c.dart` it references `a.dart`.
    // Even though `a.dart` is not a valid part of `c.dart`.
    final bCycle_2 = bState.libraryCycle;
    final cCycle_2 = cState.libraryCycle;
    expect(bCycle_2.apiSignature, isNot(bCycle_1.apiSignature));
    expect(cCycle_2.apiSignature, isNot(cCycle_1.apiSignature));
  }

  test_refresh_partOfUri_to_library() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part 'b.dart';
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part of 'a.dart';
''');

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });
    _assertPartedFiles(aState, [b]);

    final aCycle_1 = aState.libraryCycle;

    // There is `part of` in `b.dart`, so it is a part.
    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(aState));
      kind.assertLibrary(aState);
    });

    // There are no directives in `b.dart`, so it is a library.
    newFile(b.path, r'''
// no part of
''');
    bState.refresh();
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });

    // Library `a.dart` still considers `b.dart` its part.
    _assertPartedFiles(aState, [b]);

    // The library cycle for `a.dart` is different now.
    final aCycle_2 = aState.libraryCycle;
    expect(aCycle_2.apiSignature, isNot(aCycle_1.apiSignature));
  }

  test_refresh_partOfUri_twoLibraries() async {
    final a = newFile('$testPackageLibPath/a.dart', r'''
part of 'b.dart';
class A1 {}
''');

    final b = newFile('$testPackageLibPath/b.dart', r'''
part 'a.dart';
''');

    final c = newFile('$testPackageLibPath/c.dart', r'''
part 'a.dart';
''');

    final bState = fileStateFor(b);
    bState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });
    _assertPartedFiles(bState, [a]);

    final cState = fileStateFor(c);
    cState.assertKind((kind) {
      kind as LibraryFileStateKind;
      expect(kind.name, isNull);
    });
    _assertPartedFiles(cState, [a]);

    final aState = fileStateFor(a);
    aState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(bState));
      kind.assertLibrary(bState);
    });

    final bCycle_1 = bState.libraryCycle;
    final cCycle_1 = cState.libraryCycle;

    // Update `a.dart` part.
    newFile(a.path, r'''
part of 'b.dart';
class A2 {}
''');
    aState.refresh();
    // `a.dart` is still a part.
    aState.assertKind((kind) {
      kind as PartOfUriKnownFileStateKind;
      expect(kind.uriFile, same(bState));
      kind.assertLibrary(bState);
    });

    // ...but the unlinked signature of `a.dart` is different.
    // We invalidate `b.dart` it references `a.dart`.
    // We invalidate `c.dart` it references `a.dart`.
    // Even though `a.dart` is not a valid part of `c.dart`.
    final bCycle_2 = bState.libraryCycle;
    final cCycle_2 = cState.libraryCycle;
    expect(bCycle_2.apiSignature, isNot(bCycle_1.apiSignature));
    expect(cCycle_2.apiSignature, isNot(cCycle_1.apiSignature));
  }

  void _assertAugmentationFiles(FileState fileState, List<File> expected) {
    final actualFiles = fileState.augmentationFiles.map((part) {
      if (part != null) {
        return getFile(part.path);
      }
    }).toList();
    expect(actualFiles, expected);
  }

  void _assertPartedFiles(FileState fileState, List<File> expected) {
    final actualFiles = fileState.partedFiles.map((part) {
      if (part != null) {
        return getFile(part.path);
      }
    }).toList();
    expect(actualFiles, expected);
  }

  Future<File> _writeSdkSummary() async {
    final file = getFile('/home/summaries/sdk.sum');
    final bytes = await buildSdkSummary2(
      resourceProvider: resourceProvider,
      sdkPath: sdkRoot.path,
    );
    file.writeAsBytesSync(bytes);
    return file;
  }
}

@reflectiveTest
class FileSystemStateTest with ResourceProviderMixin {
  final ByteStore byteStore = MemoryByteStore();
  final FileContentOverlay contentOverlay = FileContentOverlay();

  final StringBuffer logBuffer = StringBuffer();
  final _GeneratedUriResolverMock generatedUriResolver =
      _GeneratedUriResolverMock();
  late final SourceFactory sourceFactory;
  late final PerformanceLog logger;

  late final FileSystemState fileSystemState;

  void setUp() {
    logger = PerformanceLog(logBuffer);

    var sdkRoot = newFolder('/sdk');
    createMockSdk(
      resourceProvider: resourceProvider,
      root: sdkRoot,
    );
    var sdk = FolderBasedDartSdk(resourceProvider, sdkRoot);

    var packageMap = <String, List<Folder>>{
      'aaa': [getFolder('/aaa/lib')],
      'bbb': [getFolder('/bbb/lib')],
    };

    var packages = Packages({
      'aaa': Package(
        name: 'aaa',
        rootFolder: newFolder('/packages/aaa'),
        libFolder: newFolder('/packages/aaa/lib'),
        languageVersion: null,
      ),
      'bbb': Package(
        name: 'bbb',
        rootFolder: newFolder('/packages/bbb'),
        libFolder: newFolder('/packages/bbb/lib'),
        languageVersion: null,
      ),
    });

    var workspace = BasicWorkspace.find(
      resourceProvider,
      packages,
      convertPath('/test'),
    );

    sourceFactory = SourceFactory([
      DartUriResolver(sdk),
      generatedUriResolver,
      PackageMapUriResolver(resourceProvider, packageMap),
      ResourceUriResolver(resourceProvider)
    ]);

    AnalysisOptions analysisOptions = AnalysisOptionsImpl();
    var featureSetProvider = FeatureSetProvider.build(
      sourceFactory: sourceFactory,
      resourceProvider: resourceProvider,
      packages: Packages.empty,
      packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
      nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion,
      nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(),
    );
    fileSystemState = FileSystemState(
      logger,
      byteStore,
      resourceProvider,
      'contextName',
      sourceFactory,
      workspace,
      analysisOptions,
      DeclaredVariables(),
      Uint32List(0),
      Uint32List(0),
      featureSetProvider,
      fileContentCache: FileContentCache.ephemeral(resourceProvider),
    );
  }

  test_definedClassMemberNames() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
class A {
  int a, b;
  A();
  A.c();
  d() {}
  get e => null;
  set f(_) {}
}
class B {
  g() {}
}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.definedClassMemberNames,
        unorderedEquals(['a', 'b', 'd', 'e', 'f', 'g']));
  }

  test_definedClassMemberNames_enum() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
enum E1 {
  v1;
  int field1, field2;
  const E1();
  const E1.namedConstructor();
  void method() {}
  get getter => 0;
  set setter(_) {}
}

enum E2 {
  v2;
  get getter2 => 0;
}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(
      file.definedClassMemberNames,
      unorderedEquals([
        'v1',
        'field1',
        'field2',
        'method',
        'getter',
        'setter',
        'v2',
        'getter2',
      ]),
    );
  }

  test_definedTopLevelNames() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
class A {}
class B = Object with A;
typedef C();
D() {}
get E => null;
set F(_) {}
var G, H;
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.definedTopLevelNames,
        unorderedEquals(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']));
  }

  test_getFileForPath_emptyUri() {
    String path = convertPath('/test.dart');
    newFile(path, r'''
import '';
export '';
part '';
''');

    FileState file = fileSystemState.getFileForPath(path);
    _assertIsUnresolvedFile(file.importedFiles[0]);
    _assertIsUnresolvedFile(file.exportedFiles[0]);
    _assertIsUnresolvedFile(file.partedFiles[0]);
  }

  test_getFileForPath_hasLibraryDirective_hasPartOfDirective() {
    String a = convertPath('/test/lib/a.dart');
    newFile(a, r'''
library L;
part of L;
''');
    FileState file = fileSystemState.getFileForPath(a);
    expect(file.isPart, isFalse);
  }

  test_getFileForPath_invalidUri() {
    String a = convertPath('/aaa/lib/a.dart');
    String a1 = convertPath('/aaa/lib/a1.dart');
    String a2 = convertPath('/aaa/lib/a2.dart');
    String a3 = convertPath('/aaa/lib/a3.dart');
    String content_a1 = r'''
import 'package:aaa/a1.dart';
import ':[invalid uri]';

export 'package:aaa/a2.dart';
export ':[invalid uri]';

part 'a3.dart';
part ':[invalid uri]';
''';
    newFile(a, content_a1);

    FileState file = fileSystemState.getFileForPath(a);

    expect(_excludeSdk(file.importedFiles), hasLength(2));
    expect(file.importedFiles[0]!.path, a1);
    expect(file.importedFiles[0]!.uri, Uri.parse('package:aaa/a1.dart'));
    expect(file.importedFiles[0]!.source, isNotNull);
    _assertIsUnresolvedFile(file.importedFiles[1]);

    expect(_excludeSdk(file.exportedFiles), hasLength(2));
    expect(file.exportedFiles[0]!.path, a2);
    expect(file.exportedFiles[0]!.uri, Uri.parse('package:aaa/a2.dart'));
    expect(file.exportedFiles[0]!.source, isNotNull);
    _assertIsUnresolvedFile(file.exportedFiles[1]);

    expect(_excludeSdk(file.partedFiles), hasLength(2));
    expect(file.partedFiles[0]!.path, a3);
    expect(file.partedFiles[0]!.uri, Uri.parse('package:aaa/a3.dart'));
    expect(file.partedFiles[0]!.source, isNotNull);
    _assertIsUnresolvedFile(file.partedFiles[1]);
  }

  test_getFileForPath_onlyDartFiles() {
    String not_dart = convertPath('/test/lib/not_dart.txt');
    String a = convertPath('/test/lib/a.dart');
    String b = convertPath('/test/lib/b.dart');
    String c = convertPath('/test/lib/c.dart');
    String d = convertPath('/test/lib/d.dart');
    newFile(a, r'''
library lib;
import 'dart:math';
import 'b.dart';
import 'not_dart.txt';
export 'c.dart';
export 'not_dart.txt';
part 'd.dart';
part 'not_dart.txt';
''');
    FileState file = fileSystemState.getFileForPath(a);
    expect(_excludeSdk(file.importedFiles).map((f) => f!.path), [b, not_dart]);
    expect(file.exportedFiles.map((f) => f!.path), [c, not_dart]);
    expect(file.partedFiles.map((f) => f!.path), [d, not_dart]);
    expect(_excludeSdk(fileSystemState.knownFilePaths),
        unorderedEquals([a, b, c, d, not_dart]));
  }

  test_getFileForPath_samePath() {
    String path = convertPath('/aaa/lib/a.dart');
    FileState file1 = fileSystemState.getFileForPath(path);
    FileState file2 = fileSystemState.getFileForPath(path);
    expect(file2, same(file1));
  }

  test_getFileForUri_invalidUri() {
    var uri = Uri.parse('package:x');
    fileSystemState.getFileForUri(uri).map(
      (file) {
        expect(file, isNull);
      },
      (_) {
        fail('Expected null.');
      },
    );
  }

  test_getFilesSubtypingName_class() {
    String a = convertPath('/a.dart');
    String b = convertPath('/b.dart');

    newFile(a, r'''
class A {}
class B extends A {}
''');
    newFile(b, r'''
class A {}
class D implements A {}
''');

    FileState aFile = fileSystemState.getFileForPath(a);
    FileState bFile = fileSystemState.getFileForPath(b);

    expect(
      fileSystemState.getFilesSubtypingName('A'),
      unorderedEquals([aFile, bFile]),
    );

    // Change b.dart so that it does not subtype A.
    newFile(b, r'''
class C {}
class D implements C {}
''');
    bFile.refresh();
    expect(
      fileSystemState.getFilesSubtypingName('A'),
      unorderedEquals([aFile]),
    );
    expect(
      fileSystemState.getFilesSubtypingName('C'),
      unorderedEquals([bFile]),
    );
  }

  test_getFilesSubtypingName_enum_implements() {
    String a = convertPath('/a.dart');
    String b = convertPath('/b.dart');

    newFile(a, r'''
class A {}
enum E1 implements A {
  v
}
''');
    newFile(b, r'''
class A {}
enum E2 implements A {
  v
}
''');

    FileState aFile = fileSystemState.getFileForPath(a);
    FileState bFile = fileSystemState.getFileForPath(b);

    expect(
      fileSystemState.getFilesSubtypingName('A'),
      unorderedEquals([aFile, bFile]),
    );

    // Change b.dart so that it does not subtype A.
    newFile(b, r'''
class C {}
enum E2 implements C {
  v
}
''');
    bFile.refresh();
    expect(
      fileSystemState.getFilesSubtypingName('A'),
      unorderedEquals([aFile]),
    );
    expect(
      fileSystemState.getFilesSubtypingName('C'),
      unorderedEquals([bFile]),
    );
  }

  test_getFilesSubtypingName_enum_with() {
    String a = convertPath('/a.dart');
    String b = convertPath('/b.dart');

    newFile(a, r'''
mixin M {}
enum E1 with M {
  v
}
''');
    newFile(b, r'''
mixin M {}
enum E2 with M {
  v
}
''');

    FileState aFile = fileSystemState.getFileForPath(a);
    FileState bFile = fileSystemState.getFileForPath(b);

    expect(
      fileSystemState.getFilesSubtypingName('M'),
      unorderedEquals([aFile, bFile]),
    );
  }

  test_hasUri() {
    Uri uri = Uri.parse('package:aaa/foo.dart');
    String templatePath = convertPath('/aaa/lib/foo.dart');
    String generatedPath = convertPath('/generated/aaa/lib/foo.dart');

    Source generatedSource = _SourceMock(generatedPath, uri);

    generatedUriResolver.resolveAbsoluteFunction = (uri) => generatedSource;

    expect(fileSystemState.hasUri(templatePath), isFalse);
    expect(fileSystemState.hasUri(generatedPath), isTrue);
  }

  test_libraryCycle() {
    String pa = convertPath('/aaa/lib/a.dart');
    String pb = convertPath('/aaa/lib/b.dart');
    String pc = convertPath('/aaa/lib/c.dart');
    String pd = convertPath('/aaa/lib/d.dart');

    FileState fa = fileSystemState.getFileForPath(pa);
    FileState fb = fileSystemState.getFileForPath(pb);
    FileState fc = fileSystemState.getFileForPath(pc);
    FileState fd = fileSystemState.getFileForPath(pd);

    // Compute library cycles for all files.
    fa.libraryCycle;
    fb.libraryCycle;
    fc.libraryCycle;
    fd.libraryCycle;
    _assertFilesWithoutLibraryCycle([]);

    // No imports, so just a single file.
    newFile(pa, '');
    _assertLibraryCycle(fa, [fa], []);

    // Import b.dart into a.dart, two files now.
    newFile(pa, "import 'b.dart';");
    fa.refresh();
    _assertFilesWithoutLibraryCycle([fa]);
    _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);

    // Update b.dart so that it imports c.dart now.
    newFile(pb, "import 'c.dart';");
    fb.refresh();
    _assertFilesWithoutLibraryCycle([fa, fb]);
    _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);
    _assertLibraryCycle(fb, [fb], [fc.libraryCycle]);
    _assertFilesWithoutLibraryCycle([]);

    // Update b.dart so that it exports d.dart instead.
    newFile(pb, "export 'd.dart';");
    fb.refresh();
    _assertFilesWithoutLibraryCycle([fa, fb]);
    _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);
    _assertLibraryCycle(fb, [fb], [fd.libraryCycle]);
    _assertFilesWithoutLibraryCycle([]);

    // Update a.dart so that it does not import b.dart anymore.
    newFile(pa, '');
    fa.refresh();
    _assertFilesWithoutLibraryCycle([fa]);
    _assertLibraryCycle(fa, [fa], []);
  }

  test_libraryCycle_cycle() {
    String pa = convertPath('/aaa/lib/a.dart');
    String pb = convertPath('/aaa/lib/b.dart');

    newFile(pa, "import 'b.dart';");
    newFile(pb, "import 'a.dart';");

    FileState fa = fileSystemState.getFileForPath(pa);
    FileState fb = fileSystemState.getFileForPath(pb);

    // Compute library cycles for all files.
    fa.libraryCycle;
    fb.libraryCycle;
    _assertFilesWithoutLibraryCycle([]);

    // It's a cycle.
    _assertLibraryCycle(fa, [fa, fb], []);
    _assertLibraryCycle(fb, [fa, fb], []);
    expect(fa.libraryCycle, same(fb.libraryCycle));

    // Update a.dart so that it does not import b.dart anymore.
    newFile(pa, '');
    fa.refresh();
    _assertFilesWithoutLibraryCycle([fa, fb]);
    _assertLibraryCycle(fa, [fa], []);
    _assertLibraryCycle(fb, [fb], [fa.libraryCycle]);
  }

  test_libraryCycle_invalidPart_withPart() {
    var pa = convertPath('/aaa/lib/a.dart');

    newFile(pa, r'''
part of lib;
part 'a.dart';
''');

    var fa = fileSystemState.getFileForPath(pa);

    _assertLibraryCycle(fa, [fa], []);
  }

  test_libraryCycle_part() {
    var a_path = convertPath('/aaa/lib/a.dart');
    var b_path = convertPath('/aaa/lib/b.dart');

    newFile(a_path, r'''
part 'b.dart';
''');
    newFile(b_path, r'''
part of 'a.dart';
''');

    var a_file = fileSystemState.getFileForPath(a_path);
    var b_file = fileSystemState.getFileForPath(b_path);
    _assertFilesWithoutLibraryCycle([a_file, b_file]);

    // Compute the library cycle for 'a.dart', the library.
    var a_libraryCycle = a_file.libraryCycle;
    _assertFilesWithoutLibraryCycle([b_file]);

    // The part 'b.dart' has its own library cycle.
    // If the user chooses to import a part, it is a compile-time error.
    // We could handle this in different ways:
    // 1. Completely ignore an import of a file with a `part of` directive.
    // 2. Treat such file as a library anyway.
    // By giving a part its own library cycle we support (2).
    var b_libraryCycle = b_file.libraryCycle;
    expect(b_libraryCycle, isNot(same(a_libraryCycle)));
    _assertFilesWithoutLibraryCycle([]);
  }

  test_referencedNames() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
A foo(B p) {
  foo(null);
  C c = new C(p);
  return c;
}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.referencedNames, unorderedEquals(['A', 'B', 'C']));
  }

  test_refresh_differentApiSignature() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
class A {}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.definedTopLevelNames, contains('A'));
    List<int> signature = file.apiSignature;

    // Update the resource and refresh the file state.
    newFile(path, r'''
class B {}
''');
    final changeKind = file.refresh();
    expect(changeKind, FileStateRefreshResult.apiChanged);

    expect(file.definedTopLevelNames, contains('B'));
    expect(file.apiSignature, isNot(signature));
  }

  test_refresh_sameApiSignature() {
    String path = convertPath('/aaa/lib/a.dart');
    newFile(path, r'''
class C {
  foo() {
    print(111);
  }
}
''');
    FileState file = fileSystemState.getFileForPath(path);
    List<int> signature = file.apiSignature;

    // Update the resource and refresh the file state.
    newFile(path, r'''
class C {
  foo() {
    print(222);
  }
}
''');
    final changeKind = file.refresh();
    expect(changeKind, FileStateRefreshResult.contentChanged);

    expect(file.apiSignature, signature);
  }

  test_store_zeroLengthUnlinked() {
    String path = convertPath('/test.dart');
    newFile(path, 'class A {}');

    // Get the file, prepare unlinked.
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.unlinked2, isNotNull);

    // Make the unlinked unit in the byte store zero-length, damaged.
    byteStore.put(file.test.unlinkedKey, Uint8List(0));

    // Refresh should not fail, zero bytes in the store are ignored.
    file.refresh();
    expect(file.unlinked2, isNotNull);
  }

  test_subtypedNames() {
    String path = convertPath('/test.dart');
    newFile(path, r'''
class X extends A {}
class Y extends A with B {}
class Z implements C, D {}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.referencedNames, unorderedEquals(['A', 'B', 'C', 'D']));
  }

  test_transitiveSignature() {
    String pa = convertPath('/aaa/lib/a.dart');
    String pb = convertPath('/aaa/lib/b.dart');
    String pc = convertPath('/aaa/lib/c.dart');
    String pd = convertPath('/aaa/lib/d.dart');

    newFile(pa, "class A {}");
    newFile(pb, "import 'a.dart';");
    newFile(pc, "import 'b.dart';");
    newFile(pd, "class D {}");

    FileState fa = fileSystemState.getFileForPath(pa);
    FileState fb = fileSystemState.getFileForPath(pb);
    FileState fc = fileSystemState.getFileForPath(pc);
    FileState fd = fileSystemState.getFileForPath(pd);

    // Compute transitive closures for all files.
    // This implicitly computes library cycles.
    expect(fa.transitiveSignature, isNotNull);
    expect(fb.transitiveSignature, isNotNull);
    expect(fc.transitiveSignature, isNotNull);
    expect(fd.transitiveSignature, isNotNull);
    _assertFilesWithoutLibraryCycle([]);

    // Make an update to a.dart that does not change its API signature.
    // All library cycles are still valid.
    newFile(pa, "class A {} // the same API signature");
    fa.refresh();
    _assertFilesWithoutLibraryCycle([]);

    // Change a.dart API signature.
    // This flushes signatures of b.dart and c.dart, but d.dart is still OK.
    newFile(pa, "class A2 {}");
    fa.refresh();
    _assertFilesWithoutLibraryCycle([fa, fb, fc]);
  }

  test_transitiveSignature_part() {
    var aPath = convertPath('/test/lib/a.dart');
    var bPath = convertPath('/test/lib/b.dart');

    newFile(aPath, r'''
part 'b.dart';
''');
    newFile(bPath, '''
part of 'a.dart';
''');

    var aFile = fileSystemState.getFileForPath(aPath);
    var bFile = fileSystemState.getFileForPath(bPath);

    var aSignature = aFile.transitiveSignature;
    var bSignature = bFile.transitiveSignature;

    // It is not valid to use a part as a library, and so ask its signature.
    // But when this happens, we should compute the transitive signature anyway.
    // And it should not be the signature of the containing library.
    expect(bSignature, isNot(aSignature));
  }

  void _assertFilesWithoutLibraryCycle(List<FileState> expected) {
    var actual = fileSystemState.test.filesWithoutLibraryCycle;
    expect(_excludeSdk(actual), unorderedEquals(expected));
  }

  void _assertIsUnresolvedFile(FileState? file) {
    expect(file, isNull);
  }

  void _assertLibraryCycle(
    FileState file,
    List<FileState> expectedLibraries,
    List<LibraryCycle> expectedDirectDependencies,
  ) {
    expect(file.libraryCycle.libraries, unorderedEquals(expectedLibraries));
    expect(
      _excludeSdk(file.libraryCycle.directDependencies),
      unorderedEquals(expectedDirectDependencies),
    );
  }

  List<T> _excludeSdk<T>(Iterable<T> files) {
    return files.where((file) {
      if (file is LibraryCycle) {
        return !file.libraries.any((file) => file.uri.isScheme('dart'));
      } else if (file is FileState) {
        return !file.uri.isScheme('dart');
      } else if (file == null) {
        return true;
      } else {
        return !(file as String).startsWith(convertPath('/sdk'));
      }
    }).toList();
  }
}

class _GeneratedUriResolverMock extends UriResolver {
  Source? Function(Uri)? resolveAbsoluteFunction;

  Uri? Function(String)? pathToUriFunction;

  @override
  noSuchMethod(Invocation invocation) {
    throw StateError('Unexpected invocation of ${invocation.memberName}');
  }

  @override
  Uri? pathToUri(String path) {
    return pathToUriFunction?.call(path);
  }

  @override
  Source? resolveAbsolute(Uri uri) {
    if (resolveAbsoluteFunction != null) {
      return resolveAbsoluteFunction!(uri);
    }
    return null;
  }
}

class _SourceMock implements Source {
  @override
  final String fullName;

  @override
  final Uri uri;

  _SourceMock(this.fullName, this.uri);

  @override
  noSuchMethod(Invocation invocation) {
    throw StateError('Unexpected invocation of ${invocation.memberName}');
  }
}

extension on FileState {
  void assertKind(void Function(FileStateKind kind) f) {
    expect(kind.file, same(this));
    f(kind);
  }
}

extension on FileStateKind {
  void assertLibrary(FileState expectedLibraryFile) {
    final expectedKind = expectedLibraryFile.kind as LibraryFileStateKind;
    expect(library, same(expectedKind));
  }
}

extension on AugmentationKnownFileStateKind {
  void assertAugmented(FileState expectedFile) {
    // The expected file must be a valid augmentation target.
    final expectedKind = expectedFile.kind as LibraryOrAugmentationFileKind;

    // Any valid augmentation target is always the URI target.
    expect(uriFile, same(expectedFile));

    // Check the augmentation target itself.
    expect(augmented, same(expectedKind));
  }
}

extension on PartOfNameFileStateKind {
  void assertLibraries(Iterable<FileState> expectedFiles) {
    final expectedKinds = expectedFiles.map((e) {
      return e.kind as LibraryFileStateKind;
    }).toList();
    expect(libraries, unorderedEquals(expectedKinds));
  }
}

extension on CheckTarget<ImportDirectiveState> {
  @useResult
  CheckTarget<Source?> get importedLibrarySource {
    return nest(
      value.importedLibrarySource,
      (selected) => 'importedLibrarySource ${valueStr(selected)}',
    );
  }

  @useResult
  CheckTarget<bool> get isSyntheticDartCoreImport {
    return nest(
      value.isSyntheticDartCoreImport,
      (selected) => 'isSyntheticDartCoreImport ${valueStr(selected)}',
    );
  }

  /// Is [ImportDirectiveWithFile], but not a library.
  void isFile(FileState expected) {
    this.isA<ImportDirectiveWithFile>()
      ..importedFile.isIdenticalTo(expected)
      ..importedSource.uri.isEqualTo(expected.uri)
      ..importedLibrary.isNull
      ..importedLibrarySource.isNull;
  }

  /// Is [ImportDirectiveWithFile], and is a library.
  void isLibrary(FileState expected) {
    final expectedKind = expected.kind as LibraryFileStateKind;
    this.isA<ImportDirectiveWithFile>()
      ..importedFile.isIdenticalTo(expected)
      ..importedSource.uri.isEqualTo(expected.uri)
      ..importedLibrary.isNotNull.isIdenticalTo(expectedKind)
      ..importedLibrarySource.isNotNull.uri.isEqualTo(expected.uri);
  }

  /// Exactly [ImportDirectiveState], even the file is not known.
  void isNotFile() {
    hasExactType<ImportDirectiveState>();
  }

  void withInSummaryLibrary(Uri expected) {
    this.isA<ImportDirectiveWithInSummarySource>()
      ..importedSource.uri.isEqualTo(expected)
      ..importedLibrarySource.isNotNull.uri.isEqualTo(expected);
  }

  void withInSummaryNotLibrary(Uri expected) {
    this.isA<ImportDirectiveWithInSummarySource>()
      ..importedSource.uri.isEqualTo(expected)
      ..importedLibrarySource.isNull;
  }
}

extension on CheckTarget<ExportDirectiveState> {
  @useResult
  CheckTarget<Source?> get exportedLibrarySource {
    return nest(
      value.exportedLibrarySource,
      (selected) => 'exportedLibrarySource ${valueStr(selected)}',
    );
  }

  /// Is [ExportDirectiveWithFile], but not a library.
  void isFile(FileState expected) {
    this.isA<ExportDirectiveWithFile>()
      ..exportedFile.isIdenticalTo(expected)
      ..exportedSource.uri.isEqualTo(expected.uri)
      ..exportedLibrary.isNull
      ..exportedLibrarySource.isNull;
  }

  /// Is [ExportDirectiveWithFile], and is a library.
  void isLibrary(FileState expected) {
    final expectedKind = expected.kind as LibraryFileStateKind;
    this.isA<ExportDirectiveWithFile>()
      ..exportedFile.isIdenticalTo(expected)
      ..exportedSource.uri.isEqualTo(expected.uri)
      ..exportedLibrary.isIdenticalTo(expectedKind)
      ..exportedLibrarySource.isNotNull.uri.isEqualTo(expected.uri);
  }

  /// Exactly [ExportDirectiveState], even the file is not known.
  void isNotFile() {
    hasExactType<ExportDirectiveState>();
  }

  void withInSummaryLibrary(Uri expected) {
    this.isA<ExportDirectiveWithInSummarySource>()
      ..exportedSource.uri.isEqualTo(expected)
      ..exportedLibrarySource.isNotNull.uri.isEqualTo(expected);
  }

  void withInSummaryNotLibrary(Uri expected) {
    this.isA<ExportDirectiveWithInSummarySource>()
      ..exportedSource.uri.isEqualTo(expected)
      ..exportedLibrarySource.isNull;
  }
}

extension on CheckTarget<ImportDirectiveWithFile> {
  @useResult
  CheckTarget<FileState> get importedFile {
    return nest(
      value.importedFile,
      (selected) => 'importedFile ${valueStr(selected)}',
    );
  }

  @useResult
  CheckTarget<LibraryFileStateKind?> get importedLibrary {
    return nest(
      value.importedLibrary,
      (selected) => 'importedLibrary ${valueStr(selected)}',
    );
  }

  @useResult
  CheckTarget<Source> get importedSource {
    return nest(
      value.importedSource,
      (selected) => 'importedSource ${valueStr(selected)}',
    );
  }
}

extension on CheckTarget<ExportDirectiveWithFile> {
  @useResult
  CheckTarget<FileState> get exportedFile {
    return nest(
      value.exportedFile,
      (selected) => 'exportedFile ${valueStr(selected)}',
    );
  }

  @useResult
  CheckTarget<LibraryFileStateKind?> get exportedLibrary {
    return nest(
      value.exportedLibrary,
      (selected) => 'exportedLibrary ${valueStr(selected)}',
    );
  }

  @useResult
  CheckTarget<Source> get exportedSource {
    return nest(
      value.exportedSource,
      (selected) => 'exportedSource ${valueStr(selected)}',
    );
  }
}

extension on CheckTarget<ImportDirectiveWithInSummarySource> {
  @useResult
  CheckTarget<InSummarySource> get importedSource {
    return nest(
      value.importedSource,
      (selected) => 'importedSource ${valueStr(selected)}',
    );
  }
}

extension on CheckTarget<ExportDirectiveWithInSummarySource> {
  @useResult
  CheckTarget<InSummarySource> get exportedSource {
    return nest(
      value.exportedSource,
      (selected) => 'exportedSource ${valueStr(selected)}',
    );
  }
}

extension on CheckTarget<Source> {
  @useResult
  CheckTarget<Uri> get uri {
    return nest(
      value.uri,
      (selected) => 'uri ${valueStr(selected)}',
    );
  }
}

extension _Either2Extension<T1, T2> on Either2<T1, T2> {
  T1 get t1 {
    late T1 result;
    map(
      (t1) => result = t1,
      (_) => throw 'Expected T1',
    );
    return result;
  }
}
