// 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 {
  @override
  bool get retainDataForTesting => true;

  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);
    });
  }

  /// TODO(scheglov) Test discovery of a sibling library
  test_newFile_partOfName() async {
    final a = newFile('$testPackageLibPath/nested/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,
      fileContentStrategy: StoredFileContentStrategy(
        FileContentCache.ephemeral(resourceProvider),
      ),
      prefetchFiles: null,
      isGenerated: (_) => false,
      testData: null,
    );
  }

  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.putGet(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;
  }
}
