// 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:convert';
import 'dart:typed_data';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/file_system/file_system.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:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../context/mock_sdk.dart';

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

@reflectiveTest
class FileSystemStateTest {
  final MemoryResourceProvider provider = new MemoryResourceProvider();
  MockSdk sdk;

  final ByteStore byteStore = new MemoryByteStore();
  final FileContentOverlay contentOverlay = new FileContentOverlay();

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

  FileSystemState fileSystemState;

  void setUp() {
    logger = new PerformanceLog(logBuffer);
    sdk = new MockSdk(resourceProvider: provider);
    sourceFactory = new SourceFactory([
      new DartUriResolver(sdk),
      generatedUriResolver,
      new PackageMapUriResolver(provider, <String, List<Folder>>{
        'aaa': [provider.getFolder(_p('/aaa/lib'))],
        'bbb': [provider.getFolder(_p('/bbb/lib'))],
      }),
      new ResourceUriResolver(provider)
    ], null, provider);
    AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
    fileSystemState = new FileSystemState(logger, byteStore, contentOverlay,
        provider, sourceFactory, analysisOptions, new Uint32List(0));
  }

  test_definedClassMemberNames() {
    String path = _p('/aaa/lib/a.dart');
    provider.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_definedTopLevelNames() {
    String path = _p('/aaa/lib/a.dart');
    provider.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_exportedTopLevelDeclarations_cycle() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    String c = _p('/aaa/lib/c.dart');
    provider.newFile(a, r'''
export 'b.dart';
class A {}
''');
    provider.newFile(b, r'''
export 'c.dart';
class B {}
''');
    provider.newFile(c, r'''
export 'a.dart';
class C {}
''');
    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C']);

    // We asked for 'a', and it was computed.
    // But 'b' and 'c' are not computed, because we detect that there is
    // cycle with 'a', so we cannot get all exported declarations of 'a'.
    _assertHasComputedExportedDeclarations([a]);
  }

  test_exportedTopLevelDeclarations_cycle_anotherOutsideCycle() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    String c = _p('/aaa/lib/c.dart');
    String d = _p('/aaa/lib/d.dart');
    provider.newFile(a, r'''
export 'b.dart';
class A {}
''');
    provider.newFile(b, r'''
export 'c.dart';
class B {}
''');
    provider.newFile(c, r'''
export 'b.dart';
export 'd.dart';
class C {}
''');
    provider.newFile(d, r'''
class D {}
''');
    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D']);

    // To compute 'a' we compute 'b'.
    // But 'c' is not computed, because of the cycle [b, c].
    // However 'd' is not a part of a cycle, so it is computed too.
    _assertHasComputedExportedDeclarations([a, b, d]);
  }

  test_exportedTopLevelDeclarations_cycle_onSequence() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    String c = _p('/aaa/lib/c.dart');
    String d = _p('/aaa/lib/d.dart');
    String e = _p('/aaa/lib/e.dart');
    provider.newFile(a, r'''
export 'b.dart';
class A {}
''');
    provider.newFile(b, r'''
export 'c.dart';
class B {}
''');
    provider.newFile(c, r'''
export 'd.dart';
class C {}
''');
    provider.newFile(d, r'''
export 'e.dart';
class D {}
''');
    provider.newFile(e, r'''
export 'c.dart';
class E {}
''');
    // We compute 'a'.
    // To compute it we also compute 'b' and 'c'.
    // But 'd' and 'e' are not computed, because of the cycle [c, d, e].
    _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D', 'E']);
    _assertHasComputedExportedDeclarations([a, b, c]);

    // We compute 'd', and try to compute 'e', because 'd' needs 'e'; 'e' can
    // be computed because 'c' is ready, so the cycle [c, d, e] is broken.
    _assertExportedTopLevelDeclarations(d, ['C', 'D', 'E']);
    _assertHasComputedExportedDeclarations([a, b, c, d, e]);
  }

  test_exportedTopLevelDeclarations_export() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class A {}
''');
    provider.newFile(b, r'''
export 'a.dart';
class B {}
''');
    _assertExportedTopLevelDeclarations(b, ['A', 'B']);
    _assertHasComputedExportedDeclarations([a, b]);
  }

  test_exportedTopLevelDeclarations_export2_show() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    String c = _p('/aaa/lib/c.dart');
    provider.newFile(a, r'''
class A1 {}
class A2 {}
class A3 {}
''');
    provider.newFile(b, r'''
export 'a.dart' show A1, A2;
class B1 {}
class B2 {}
''');
    provider.newFile(c, r'''
export 'b.dart' show A2, A3, B1;
class C {}
''');
    _assertExportedTopLevelDeclarations(c, ['A2', 'B1', 'C']);
    _assertHasComputedExportedDeclarations([a, b, c]);
  }

  test_exportedTopLevelDeclarations_export_flushOnChange() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class A {}
''');
    provider.newFile(b, r'''
export 'a.dart';
class B {}
''');

    // Initial exported declarations.
    _assertExportedTopLevelDeclarations(b, ['A', 'B']);

    // Update a.dart, so a.dart and b.dart exported declarations are flushed.
    provider.newFile(a, 'class A {} class A2 {}');
    fileSystemState.getFileForPath(a).refresh();
    _assertExportedTopLevelDeclarations(b, ['A', 'A2', 'B']);
  }

  test_exportedTopLevelDeclarations_export_hide() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class A1 {}
class A2 {}
class A3 {}
''');
    provider.newFile(b, r'''
export 'a.dart' hide A2;
class B {}
''');
    _assertExportedTopLevelDeclarations(b, ['A1', 'A3', 'B']);
  }

  test_exportedTopLevelDeclarations_export_preferLocal() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class V {}
''');
    provider.newFile(b, r'''
export 'a.dart';
int V;
''');
    FileState file = fileSystemState.getFileForPath(b);
    Map<String, TopLevelDeclaration> declarations =
        file.exportedTopLevelDeclarations;
    expect(declarations.keys, unorderedEquals(['V']));
    expect(declarations['V'].kind, TopLevelDeclarationKind.variable);
  }

  test_exportedTopLevelDeclarations_export_show() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class A1 {}
class A2 {}
''');
    provider.newFile(b, r'''
export 'a.dart' show A2;
class B {}
''');
    _assertExportedTopLevelDeclarations(b, ['A2', 'B']);
  }

  test_exportedTopLevelDeclarations_export_show2() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    String c = _p('/aaa/lib/c.dart');
    String d = _p('/aaa/lib/d.dart');
    provider.newFile(a, r'''
export 'b.dart' show Foo;
export 'c.dart' show Bar;
''');
    provider.newFile(b, r'''
export 'd.dart';
''');
    provider.newFile(c, r'''
export 'd.dart';
''');
    provider.newFile(d, r'''
class Foo {}
class Bar {}
''');
    _assertExportedTopLevelDeclarations(a, ['Foo', 'Bar']);
  }

  test_exportedTopLevelDeclarations_import() {
    String a = _p('/aaa/lib/a.dart');
    String b = _p('/aaa/lib/b.dart');
    provider.newFile(a, r'''
class A {}
''');
    provider.newFile(b, r'''
import 'a.dart';
class B {}
''');
    _assertExportedTopLevelDeclarations(b, ['B']);
  }

  test_exportedTopLevelDeclarations_parts() {
    String a = _p('/aaa/lib/a.dart');
    String a2 = _p('/aaa/lib/a2.dart');
    provider.newFile(a, r'''
library lib;
part 'a2.dart';
class A1 {}
''');
    provider.newFile(a2, r'''
part of lib;
class A2 {}
''');
    _assertExportedTopLevelDeclarations(a, ['A1', 'A2']);
  }

  test_getFileForPath_doesNotExist() {
    String path = _p('/aaa/lib/a.dart');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.path, path);
    expect(file.uri, Uri.parse('package:aaa/a.dart'));
    expect(file.content, '');
    expect(file.contentHash, _md5(''));
    expect(_excludeSdk(file.importedFiles), isEmpty);
    expect(file.exportedFiles, isEmpty);
    expect(file.partedFiles, isEmpty);
    expect(_excludeSdk(file.directReferencedFiles), isEmpty);
    expect(file.isPart, isFalse);
    expect(file.library, isNull);
    expect(file.unlinked, isNotNull);
    expect(file.unlinked.classes, isEmpty);
  }

  test_getFileForPath_emptyUri() {
    String path = _p('/test.dart');
    provider.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 = _p('/test/lib/a.dart');
    provider.newFile(a, r'''
library L;
part of L;
''');
    FileState file = fileSystemState.getFileForPath(a);
    expect(file.isPart, isFalse);
  }

  test_getFileForPath_invalidUri() {
    String a = _p('/aaa/lib/a.dart');
    String a1 = _p('/aaa/lib/a1.dart');
    String a2 = _p('/aaa/lib/a2.dart');
    String a3 = _p('/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]';
''';
    provider.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_library() {
    String a1 = _p('/aaa/lib/a1.dart');
    String a2 = _p('/aaa/lib/a2.dart');
    String a3 = _p('/aaa/lib/a3.dart');
    String a4 = _p('/aaa/lib/a4.dart');
    String b1 = _p('/bbb/lib/b1.dart');
    String b2 = _p('/bbb/lib/b2.dart');
    String content_a1 = r'''
import 'package:aaa/a2.dart';
import 'package:bbb/b1.dart';
export 'package:bbb/b2.dart';
export 'package:aaa/a3.dart';
part 'a4.dart';

class A1 {}
''';
    provider.newFile(a1, content_a1);

    FileState file = fileSystemState.getFileForPath(a1);
    expect(file.path, a1);
    expect(file.content, content_a1);
    expect(file.contentHash, _md5(content_a1));

    expect(file.isPart, isFalse);
    expect(file.library, isNull);
    expect(file.unlinked, isNotNull);
    expect(file.unlinked.classes, hasLength(1));
    expect(file.unlinked.classes[0].name, 'A1');

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

    expect(file.exportedFiles, hasLength(2));
    expect(file.exportedFiles[0].path, b2);
    expect(file.exportedFiles[0].uri, Uri.parse('package:bbb/b2.dart'));
    expect(file.exportedFiles[0].source, isNotNull);
    expect(file.exportedFiles[1].path, a3);
    expect(file.exportedFiles[1].uri, Uri.parse('package:aaa/a3.dart'));
    expect(file.exportedFiles[1].source, isNotNull);

    expect(file.partedFiles, hasLength(1));
    expect(file.partedFiles[0].path, a4);
    expect(file.partedFiles[0].uri, Uri.parse('package:aaa/a4.dart'));

    expect(_excludeSdk(file.directReferencedFiles), hasLength(5));

    expect(fileSystemState.getFilesForPath(a1), [file]);
  }

  test_getFileForPath_onlyDartFiles() {
    String not_dart = _p('/test/lib/not_dart.txt');
    String a = _p('/test/lib/a.dart');
    String b = _p('/test/lib/b.dart');
    String c = _p('/test/lib/c.dart');
    String d = _p('/test/lib/d.dart');
    provider.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),
        unorderedEquals([b, not_dart]));
    expect(
        file.exportedFiles.map((f) => f.path), unorderedEquals([c, not_dart]));
    expect(file.partedFiles.map((f) => f.path), unorderedEquals([d, not_dart]));
    expect(_excludeSdk(fileSystemState.knownFilePaths),
        unorderedEquals([a, b, c, d, not_dart]));
  }

  test_getFileForPath_part() {
    String a1 = _p('/aaa/lib/a1.dart');
    String a2 = _p('/aaa/lib/a2.dart');
    provider.newFile(a1, r'''
library a1;
part 'a2.dart';
''');
    provider.newFile(a2, r'''
part of a1;
class A2 {}
''');

    FileState file_a2 = fileSystemState.getFileForPath(a2);
    expect(file_a2.path, a2);
    expect(file_a2.uri, Uri.parse('package:aaa/a2.dart'));

    expect(file_a2.unlinked, isNotNull);
    expect(file_a2.unlinked.classes, hasLength(1));
    expect(file_a2.unlinked.classes[0].name, 'A2');

    expect(_excludeSdk(file_a2.importedFiles), isEmpty);
    expect(file_a2.exportedFiles, isEmpty);
    expect(file_a2.partedFiles, isEmpty);
    expect(_excludeSdk(file_a2.directReferencedFiles), isEmpty);

    // The library is not known yet.
    expect(file_a2.isPart, isTrue);
    expect(file_a2.library, isNull);

    // Ask for the library.
    FileState file_a1 = fileSystemState.getFileForPath(a1);
    expect(file_a1.partedFiles, hasLength(1));
    expect(file_a1.partedFiles[0], same(file_a2));
    expect(
        _excludeSdk(file_a1.directReferencedFiles), unorderedEquals([file_a2]));

    // Now the part knows its library.
    expect(file_a2.library, same(file_a1));

    // Now update the library, and refresh its file.
    // The 'a2.dart' is not referenced anymore.
    // So the part file does not have the library anymore.
    provider.newFile(a1, r'''
library a1;
part 'not-a2.dart';
''');
    file_a1.refresh();
    expect(file_a2.library, isNull);
  }

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

  test_getFileForUri_packageVsFileUri() {
    String path = _p('/aaa/lib/a.dart');
    var packageUri = Uri.parse('package:aaa/a.dart');
    var fileUri = provider.pathContext.toUri(path);

    // The files with `package:` and `file:` URIs are different.
    FileState filePackageUri = fileSystemState.getFileForUri(packageUri);
    FileState fileFileUri = fileSystemState.getFileForUri(fileUri);
    expect(filePackageUri, isNot(same(fileFileUri)));

    expect(filePackageUri.path, path);
    expect(filePackageUri.uri, packageUri);

    expect(fileFileUri.path, path);
    expect(fileFileUri.uri, fileUri);

    // The file with the `package:` style URI is canonical, and is the first.
    var files = fileSystemState.getFilesForPath(path);
    expect(files, [filePackageUri, fileFileUri]);
  }

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

    Source generatedSource = new _SourceMock(generatedPath, uri);

    generatedUriResolver.resolveAbsoluteFunction =
        (uri, actualUri) => generatedSource;

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

  test_referencedNames() {
    String path = _p('/aaa/lib/a.dart');
    provider.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 = _p('/aaa/lib/a.dart');
    provider.newFile(path, r'''
class A {}
''');
    FileState file = fileSystemState.getFileForPath(path);
    expect(file.unlinked.classes[0].name, 'A');
    List<int> signature = file.apiSignature;

    // Update the resource and refresh the file state.
    provider.newFile(path, r'''
class B {}
''');
    bool apiSignatureChanged = file.refresh();
    expect(apiSignatureChanged, isTrue);

    expect(file.unlinked.classes[0].name, 'B');
    expect(file.apiSignature, isNot(signature));
  }

  test_refresh_sameApiSignature() {
    String path = _p('/aaa/lib/a.dart');
    provider.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.
    provider.newFile(path, r'''
class C {
  foo() {
    print(222);
  }
}
''');
    bool apiSignatureChanged = file.refresh();
    expect(apiSignatureChanged, isFalse);

    expect(file.apiSignature, signature);
  }

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

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

    // Make the unlinked unit in the byte store zero-length, damaged.
    byteStore.put(file.test.unlinkedKey, <int>[]);

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

  test_subtypedNames() {
    String path = _p('/test.dart');
    provider.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_topLevelDeclarations() {
    String path = _p('/aaa/lib/a.dart');
    provider.newFile(path, r'''
class C {}
typedef F();
enum E {E1, E2}
void f() {}
var V1;
get V2 => null;
set V3(_) {}
get V4 => null;
set V4(_) {}

class _C {}
typedef _F();
enum _E {E1, E2}
void _f() {}
var _V1;
get _V2 => null;
set _V3(_) {}
''');
    FileState file = fileSystemState.getFileForPath(path);

    Map<String, TopLevelDeclaration> declarations = file.topLevelDeclarations;

    void assertHas(String name, TopLevelDeclarationKind kind) {
      expect(declarations[name]?.kind, kind);
    }

    expect(declarations.keys,
        unorderedEquals(['C', 'F', 'E', 'f', 'V1', 'V2', 'V3', 'V4']));
    assertHas('C', TopLevelDeclarationKind.type);
    assertHas('F', TopLevelDeclarationKind.type);
    assertHas('E', TopLevelDeclarationKind.type);
    assertHas('f', TopLevelDeclarationKind.function);
    assertHas('V1', TopLevelDeclarationKind.variable);
    assertHas('V2', TopLevelDeclarationKind.variable);
    assertHas('V3', TopLevelDeclarationKind.variable);
    assertHas('V4', TopLevelDeclarationKind.variable);
  }

  test_transitiveFiles() {
    String pa = _p('/aaa/lib/a.dart');
    String pb = _p('/aaa/lib/b.dart');
    String pc = _p('/aaa/lib/c.dart');
    String pd = _p('/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 transitive closures for all files.
    fa.transitiveFiles;
    fb.transitiveFiles;
    fc.transitiveFiles;
    fd.transitiveFiles;
    expect(
        _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);

    // No imports, so just a single file.
    provider.newFile(pa, "");
    _assertTransitiveFiles(fa, [fa]);

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

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

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

    // Update a.dart so that it does not import b.dart anymore.
    provider.newFile(pa, "");
    fa.refresh();
    _assertFilesWithoutTransitiveFiles([fa]);
    _assertTransitiveFiles(fa, [fa]);
  }

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

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

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

    // Compute transitive closures for all files.
    fa.transitiveFiles;
    fb.transitiveFiles;
    _assertFilesWithoutTransitiveFiles([]);

    // It's a cycle.
    _assertTransitiveFiles(fa, [fa, fb]);
    _assertTransitiveFiles(fb, [fa, fb]);

    // Update a.dart so that it does not import b.dart anymore.
    provider.newFile(pa, "");
    fa.refresh();
    _assertFilesWithoutTransitiveFiles([fa, fb]);
    _assertTransitiveFiles(fa, [fa]);
    _assertTransitiveFiles(fb, [fa, fb]);
  }

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

    provider.newFile(pa, "class A {}");
    provider.newFile(pb, "import 'a.dart';");
    provider.newFile(pc, "import 'b.dart';");
    provider.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.
    expect(fa.transitiveSignature, isNotNull);
    expect(fb.transitiveSignature, isNotNull);
    expect(fc.transitiveSignature, isNotNull);
    expect(fd.transitiveSignature, isNotNull);
    expect(
        _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);

    // Make an update to a.dart that does not change its API signature.
    // All transitive signatures are still valid.
    provider.newFile(pa, "class A {} // the same API signature");
    fa.refresh();
    expect(
        _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);

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

  void _assertExportedTopLevelDeclarations(String path, List<String> expected) {
    FileState file = fileSystemState.getFileForPath(path);
    Map<String, TopLevelDeclaration> declarations =
        file.exportedTopLevelDeclarations;
    expect(declarations.keys, unorderedEquals(expected));
  }

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

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

  void _assertHasComputedExportedDeclarations(List<String> expectedPathList) {
    FileSystemStateTestView test = fileSystemState.test;
    expect(test.librariesWithComputedExportedDeclarations.map((f) => f.path),
        unorderedEquals(expectedPathList));
  }

  void _assertIsUnresolvedFile(FileState file) {
    expect(file.path, isNull);
    expect(file.uri, isNull);
    expect(file.source, isNull);
  }

  void _assertTransitiveFiles(FileState file, List<FileState> expected) {
    expect(_excludeSdk(file.transitiveFiles), unorderedEquals(expected));
  }

  List<T> _excludeSdk<T>(Iterable<T> files) {
    return files.where((Object file) {
      if (file is FileState) {
        return file.uri?.scheme != 'dart';
      } else {
        return !(file as String).startsWith(_p('/sdk'));
      }
    }).toList();
  }

  String _p(String path) => provider.convertPath(path);

  static String _md5(String content) {
    return hex.encode(md5.convert(utf8.encode(content)).bytes);
  }
}

class _GeneratedUriResolverMock implements UriResolver {
  Source Function(Uri, Uri) resolveAbsoluteFunction;

  Uri Function(Source) restoreAbsoluteFunction;

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

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    if (resolveAbsoluteFunction != null) {
      return resolveAbsoluteFunction(uri, actualUri);
    }
    return null;
  }

  @override
  Uri restoreAbsolute(Source source) {
    if (restoreAbsoluteFunction != null) {
      return restoreAbsoluteFunction(source);
    }
    return null;
  }
}

class _SourceMock implements Source {
  @override
  final String fullName;

  @override
  final Uri uri;

  _SourceMock(this.fullName, this.uri);

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