// 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 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'test_strategies.dart';

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

@reflectiveTest
class LinkerUnitTest extends SummaryLinkerTestStrategyTwoPhase
    with LinkerUnitTestCases {}

/// Test cases that exercise the summary linker in a white-box fashion.
///
/// These test cases may be mixed into any class derived from
/// [SummaryLinkerTestStrategy], allowing the linker to be unit-tested in a
/// variety of ways.
mixin LinkerUnitTestCases implements SummaryLinkerTestStrategy {
  Matcher get isUndefined => const TypeMatcher<UndefinedElementForLink>();

  LibraryElementForLink getLibrary(String uri) {
    return linker.getLibrary(Uri.parse(uri));
  }

  void test_baseClass_genericWithAccessor() {
    createLinker('''
class B<T> {
  int get i => null;
}
class C<U> extends B<U> {
  var j;
}
    ''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_baseClass_genericWithField() {
    createLinker('''
class B<T> {
  int i = 0;
}
class C<T> extends B<T> {
  void f() {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_baseClass_genericWithFunctionTypedParameter() {
    createLinker('''
class B<T> {
  void f(void g(T t));
}
class C<U> extends B<U> {
  void f(g) {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_baseClass_genericWithGenericMethod() {
    createLinker('''
class B<T> {
  List<U> f<U>(U u) => null;
}
class C<V> extends B<V> {
  var j;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_baseClass_genericWithGenericMethod_returnsGenericFuture() {
    createLinker('''
import 'dart:async';
class B<T> {
  Future<T> f() => null;
}
class C<T> extends B<T> {
  Future<T> f() => null;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_baseClass_genericWithStaticFinal() {
    createLinker('''
class B<T> {
  static final int i = 0;
}
class C<T> extends B<T> {
  void f() {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
  }

  void test_baseClass_withPrivateField() {
    createLinker('''
class B {
  var _b;
}
class C extends B {
  var c;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_bundle_refers_to_bundle() {
    var bundle1 = createPackageBundle('''
var x = 0;
''', path: '/a.dart');
    addBundle('/a.ds', bundle1);
    var bundle2 = createPackageBundle('''
import "a.dart";
var y = x;
''', path: '/b.dart');
    addBundle('/a.ds', bundle1);
    addBundle('/b.ds', bundle2);
    createLinker('''
import "b.dart";
var z = y;
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
        'int');
  }

  void test_constCycle_viaLength() {
    createLinker('''
class C {
  final y;
  const C() : y = x.length;
}
const x = [const C()];
''');
    testLibrary.libraryCycleForLink.ensureLinked();
    ClassElementForLink classC = testLibrary.getContainedName('C');
    expect(classC.unnamedConstructor.isCycleFree, false);
  }

  void test_covariance() {
    createLinker('''
class A<T> {
  void f(covariant T t) {}
}
class B<T> extends A<T> {
  void f(T t) {}
}
''');
    testLibrary.libraryCycleForLink.ensureLinked();
    ClassElementForLink classA = testLibrary.getContainedName('A');
    MethodElementForLink methodAF = classA.getContainedName('f');
    ParameterElementForLink parameterAFT = methodAF.parameters[0];
    expect(parameterAFT.isCovariant, isTrue);
    expect(parameterAFT.inheritsCovariant, isFalse);
    ClassElementForLink classB = testLibrary.getContainedName('B');
    MethodElementForLink methodBF = classB.getContainedName('f');
    ParameterElementForLink parameterBFT = methodBF.parameters[0];
    expect(parameterAFT.isCovariant, isTrue);
    expect(parameterBFT.inheritsCovariant, isTrue);
  }

  void test_createPackageBundle_withPackageUri() {
    PackageBundle bundle = createPackageBundle('''
class B {
  void f(int i) {}
}
class C extends B {
  f(i) {} // Inferred param type: int
}
''', uri: 'package:foo/bar.dart');
    UnlinkedExecutable cf = bundle.unlinkedUnits[0].classes[1].executables[0];
    UnlinkedParam cfi = cf.parameters[0];
    expect(cfi.inferredTypeSlot, isNot(0));
    EntityRef typeRef = _lookupInferredType(
        bundle.linkedLibraries[0].units[0], cfi.inferredTypeSlot);
    expect(typeRef, isNotNull);
    expect(bundle.unlinkedUnits[0].references[typeRef.reference].name, 'int');
  }

  void test_genericTypeAlias_fromBundle() {
    var bundle = createPackageBundle('''
typedef F<S> = S Function(num);
''', path: '/a.dart');
    addBundle('/a.ds', bundle);

    createLinker('''
import 'a.dart';
class A {
  F<int> f;
}
class B implements A {
  F<int> f;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();

    ClassElementForLink_Class B = library.getContainedName('B');
    expect(B.fields, hasLength(1));
    FieldElementForLink f = B.fields[0];
    expect(f.type.toString(), '(num) → int');
  }

  void test_getContainedName_nonStaticField() {
    createLinker('class C { var f; }');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.getContainedName('f'), isNot(isUndefined));
  }

  void test_getContainedName_nonStaticGetter() {
    createLinker('class C { get g => null; }');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.getContainedName('g'), isNot(isUndefined));
  }

  void test_getContainedName_nonStaticMethod() {
    createLinker('class C { m() {} }');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.getContainedName('m'), isNot(isUndefined));
  }

  void test_getContainedName_nonStaticSetter() {
    createLinker('class C { void set s(value) {} }');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.getContainedName('s='), isNot(isUndefined));
  }

  void test_inferredType_closure_fromBundle() {
    var bundle = createPackageBundle('''
var x = () {};
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
var y = x;
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
        '() → Null');
  }

  void test_inferredType_closure_fromBundle_identifierSequence() {
    var bundle = createPackageBundle('''
class C {
  static final x = (D d) => d.e;
}
class D {
  E e;
}
class E {}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
var y = C.x;
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
        '(D) → E');
  }

  void test_inferredType_implicitFunctionTypeIndices() {
    var bundle = createPackageBundle('''
class A {
  void foo(void bar(int arg)) {}
}
class B extends A {
  void foo(bar) {}
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class C extends B {
  void foo(bar) {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.methods, hasLength(1));
    MethodElementForLink foo = cls.methods[0];
    expect(foo.parameters, hasLength(1));
    FunctionType barType = foo.parameters[0].type;
    expect(barType.parameters[0].type.toString(), 'int');
  }

  void test_inferredType_instanceField_conditional_genericFunctions() {
    createLinker('''
class C {
  final f = true ? <T>(T t) => 0 : <T>(T t) => 1;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.fields, hasLength(1));
    var field = cls.fields[0];
    expect(field.type.toString(), '(<bottom>) → int');
  }

  void test_inferredType_instanceField_dynamic() {
    createLinker('''
var x;
class C {
  var f = x; // Inferred type: dynamic
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.fields, hasLength(1));
    var field = cls.fields[0];
    expect(field.type.toString(), 'dynamic');
  }

  void test_inferredType_methodParamType_dynamic() {
    createLinker('''
clas B {
  void f(dynamic x) {}
}
class C extends B {
  f(x) {} // Inferred param type: dynamic
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.methods, hasLength(1));
    var method = cls.methods[0];
    expect(method.parameters, hasLength(1));
    expect(method.parameters[0].type.toString(), 'dynamic');
  }

  void test_inferredType_methodParamType_genericFunction() {
    createLinker('''
class A {
  void m(Map<T, List<U>> Function<T, U>(T, U) p) {}
}
class B<V> extends A {
  void m(p) {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('B');
    expect(cls.methods, hasLength(1));
    var method = cls.methods[0];
    expect(method.parameters, hasLength(1));
    var pType = method.parameters[0].type;
    expect(pType.toString(), '<T,U>(T, U) → Map<T, List<U>>');
  }

  void test_inferredType_methodReturnType_dynamic() {
    createLinker('''
class B {
  dynamic f() {}
}
class C extends B {
  f() {} // Inferred return type: dynamic
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.methods, hasLength(1));
    expect(cls.methods[0].returnType.toString(), 'dynamic');
  }

  void test_inferredType_methodReturnType_void() {
    createLinker('''
class B {
  void f() {}
}
class C extends B {
  f() {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('C');
    expect(cls.methods, hasLength(1));
    expect(cls.methods[0].returnType.toString(), 'void');
  }

  void test_inferredType_parameter_genericFunctionType() {
    var bundle = createPackageBundle('''
class A<T> {
  A<R> map<R>(R Function(T) f) => null;
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class C extends A<int> {
  map<R2>(f) => null;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.methods, hasLength(1));
    MethodElementForLink map = c.methods[0];
    expect(map.parameters, hasLength(1));
    FunctionType fType = map.parameters[0].type;
    expect(fType.returnType.toString(), 'R2');
    expect(fType.parameters[0].type.toString(), 'int');
  }

  void test_inferredType_parameter_genericFunctionType_asTypeArgument() {
    var bundle = createPackageBundle('''
class A<T> {
  A<R> map<R>(List<R Function(T)> fs) => null;
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class C extends A<int> {
  map<R2>(fs) => null;
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class c = library.getContainedName('C');
    expect(c.methods, hasLength(1));
    MethodElementForLink map = c.methods[0];
    expect(map.parameters, hasLength(1));
    InterfaceType iType = map.parameters[0].type;
    expect(iType.typeArguments, hasLength(1));
    FunctionType fType = iType.typeArguments[0];
    expect(fType.returnType.toString(), 'R2');
    expect(fType.parameters[0].type.toString(), 'int');
  }

  void test_inferredType_staticField_dynamic() {
    createLinker('''
dynamic x = null;
class C {
  static var y = x;
}
''');
    expect(
        _getVariable(linker
                .getLibrary(testDartUri)
                .getContainedName('C')
                .getContainedName('y'))
            .inferredType
            .toString(),
        'dynamic');
  }

  void test_inferredType_topLevelVariable_dynamic() {
    createLinker('''
dynamic x = null;
var y = x;
''');
    expect(
        _getVariable(linker.getLibrary(testDartUri).getContainedName('y'))
            .inferredType
            .toString(),
        'dynamic');
  }

  void test_inferredTypeFromOutsideBuildUnit_dynamic() {
    var bundle = createPackageBundle('''
var x;
var y = x; // Inferred type: dynamic
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
var z = y; // Inferred type: dynamic
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
        'dynamic');
  }

  void test_inferredTypeFromOutsideBuildUnit_instanceField() {
    var bundle = createPackageBundle('''
class C {
  var f = 0; // Inferred type: int
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
var x = new C().f; // Inferred type: int
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
        'dynamic');
  }

  void test_inferredTypeFromOutsideBuildUnit_instanceField_toInstanceField() {
    var bundle = createPackageBundle('''
class C {
  var f = 0; // Inferred type: int
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class D {
  var g = new C().f; // Inferred type: int
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    ClassElementForLink_Class classD = library.getContainedName('D');
    expect(classD.fields[0].inferredType.toString(), 'dynamic');
  }

  void test_inferredTypeFromOutsideBuildUnit_methodParamType_viaInheritance() {
    var bundle = createPackageBundle('''
class B {
  void f(int i) {}
}
class C extends B {
  f(i) {} // Inferred param type: int
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class D extends C {
  f(i) {} // Inferred param type: int
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('D');
    expect(cls.methods, hasLength(1));
    var method = cls.methods[0];
    expect(method.parameters, hasLength(1));
    expect(method.parameters[0].type.toString(), 'int');
  }

  void test_inferredTypeFromOutsideBuildUnit_methodReturnType_viaCall() {
    var bundle = createPackageBundle('''
class B {
  int f() => 0;
}
class C extends B {
  f() => 1; // Inferred return type: int
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
var x = new C().f(); // Inferred type: int
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
        'int');
  }

  void test_inferredTypeFromOutsideBuildUnit_methodReturnType_viaInheritance() {
    var bundle = createPackageBundle('''
class B {
  int f() => 0;
}
class C extends B {
  f() => 1; // Inferred return type: int
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('''
import 'a.dart';
class D extends C {
  f() => 2; //Inferred return type: int
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    ClassElementForLink_Class cls = library.getContainedName('D');
    expect(cls.methods, hasLength(1));
    expect(cls.methods[0].returnType.toString(), 'int');
  }

  void test_inferredTypeFromOutsideBuildUnit_staticField() {
    var bundle =
        createPackageBundle('class C { static var f = 0; }', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('import "a.dart"; var x = C.f;', path: '/b.dart');
    expect(
        _getVariable(linker.getLibrary(testDartUri).getContainedName('x'))
            .inferredType
            .toString(),
        'int');
  }

  void test_inferredTypeFromOutsideBuildUnit_topLevelVariable() {
    var bundle = createPackageBundle('var a = 0;', path: '/a.dart');
    addBundle('/a.ds', bundle);
    createLinker('import "a.dart"; var b = a;', path: '/b.dart');
    expect(
        _getVariable(linker.getLibrary(testDartUri).getContainedName('b'))
            .inferredType
            .toString(),
        'int');
  }

  void test_inheritsCovariant_fromBundle() {
    var bundle = createPackageBundle('''
class X1 {}
class X2 extends X1 {}
class A {
  void foo(covariant X1 x) {}
}
class B extends A {
  void foo(X2 x) {}
}
''', path: '/a.dart');
    addBundle('/a.ds', bundle);

    // C.foo.x must inherit covariance from B.foo.x, even though it is
    // resynthesized from the bundle.
    createLinker('''
import 'a.dart';
class C extends B {
  void foo(X2 x) {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();

    ClassElementForLink_Class C = library.getContainedName('C');
    expect(C.methods, hasLength(1));
    MethodElementForLink foo = C.methods[0];
    expect(foo.parameters, hasLength(1));
    expect(foo.parameters[0].isCovariant, isTrue);
  }

  void test_instantiate_param_of_param_to_bounds() {
    createLinker('''
class C<T> {}
class D<T extends num> {}
final x = new C<D>();
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
    ParameterizedType type1 = x.returnType;
    expect(type1.element.name, 'C');
    expect(type1.typeArguments, hasLength(1));
    ParameterizedType type2 = type1.typeArguments[0];
    expect(type2.element.name, 'D');
    expect(type2.typeArguments, hasLength(1));
    DartType type3 = type2.typeArguments[0];
    expect(type3.toString(), 'num');
  }

  void test_instantiate_param_to_bounds_class() {
    createLinker('''
class C<T extends num> {}
final x = new C();
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
    ParameterizedType type1 = x.returnType;
    expect(type1.element.name, 'C');
    expect(type1.typeArguments, hasLength(1));
    DartType type2 = type1.typeArguments[0];
    expect(type2.toString(), 'num');
  }

  void test_instantiate_param_to_bounds_typedef() {
    createLinker('''
typedef T F<T extends num>();
final x = new List<F>();
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
    ParameterizedType type1 = x.returnType;
    expect(type1.element.name, 'List');
    expect(type1.typeArguments, hasLength(1));
    FunctionType type2 = type1.typeArguments[0];
    expect(type2.element.name, 'F');
    expect(type2.returnType.toString(), 'num');
  }

  void test_isSimplyBounded_class_in_other_bundle() {
    var bundle = createPackageBundle('''
class C<T extends C> {} // Not simply bounded
class D<T extends D<Null>> {} // Simply bounded
''', path: '/a.dart');
    addBundle('/a.ds', bundle);

    createLinker('''
import 'a.dart';
class A<T extends C> {} // Not simply bounded
class B<T extends D> {} // Simply bounded
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();

    expect(library.getContainedName('A').isSimplyBounded, false);
    expect(library.getContainedName('B').isSimplyBounded, true);
  }

  void test_isSimplyBounded_new_typedef_in_other_bundle() {
    var bundle = createPackageBundle('''
typedef C<T extends C> = void Function(T x); // Not simply bounded
typedef D<T extends D<Null>> = void Function(T x); // Simply bounded
''', path: '/a.dart');
    addBundle('/a.ds', bundle);

    createLinker('''
import 'a.dart';
class A<T extends C> {} // Not simply bounded
class B<T extends D> {} // Simply bounded
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();

    expect(library.getContainedName('A').isSimplyBounded, false);
    expect(library.getContainedName('B').isSimplyBounded, true);
  }

  void test_isSimplyBounded_old_typedef_in_other_bundle() {
    var bundle = createPackageBundle('''
typedef void C<T extends C>(T x); // Not simply bounded
typedef void D<T extends D<Null>>(T x); // Simply bounded
''', path: '/a.dart');
    addBundle('/a.ds', bundle);

    createLinker('''
import 'a.dart';
class A<T extends C> {} // Not simply bounded
class B<T extends D> {} // Simply bounded
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();

    expect(library.getContainedName('A').isSimplyBounded, false);
    expect(library.getContainedName('B').isSimplyBounded, true);
  }

  void test_leastUpperBound_functionAndClass() {
    createLinker('''
class C {}
void f() {}
var x = {
  'C': C,
  'f': f
};
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_libraryCycle_ignoresDependenciesOutsideBuildUnit() {
    createLinker('import "dart:async";');
    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
    expect(libraryCycle.dependencies, isEmpty);
    expect(libraryCycle.libraries, [testLibrary]);
  }

  void test_libraryCycle_linkEnsuresDependenciesLinked() {
    addNamedSource('/a.dart', 'import "b.dart";');
    addNamedSource('/b.dart', '');
    addNamedSource('/c.dart', '');
    createLinker('import "a.dart"; import "c.dart";');
    LibraryElementForLink libA = getLibrary('file:///a.dart');
    LibraryElementForLink libB = getLibrary('file:///b.dart');
    LibraryElementForLink libC = getLibrary('file:///c.dart');
    expect(libA.libraryCycleForLink.node.isEvaluated, isFalse);
    expect(libB.libraryCycleForLink.node.isEvaluated, isFalse);
    expect(libC.libraryCycleForLink.node.isEvaluated, isFalse);
    libA.libraryCycleForLink.ensureLinked();
    expect(libA.libraryCycleForLink.node.isEvaluated, isTrue);
    expect(libB.libraryCycleForLink.node.isEvaluated, isTrue);
    expect(libC.libraryCycleForLink.node.isEvaluated, isFalse);
  }

  void test_libraryCycle_nontrivial() {
    addNamedSource('/a.dart', 'import "b.dart";');
    addNamedSource('/b.dart', 'import "a.dart";');
    createLinker('');
    LibraryElementForLink libA = getLibrary('file:///a.dart');
    LibraryElementForLink libB = getLibrary('file:///b.dart');
    LibraryCycleForLink libraryCycle = libA.libraryCycleForLink;
    expect(libB.libraryCycleForLink, same(libraryCycle));
    expect(libraryCycle.dependencies, isEmpty);
    expect(libraryCycle.libraries, unorderedEquals([libA, libB]));
  }

  void test_libraryCycle_nontrivial_dependencies() {
    addNamedSource('/a.dart', '');
    addNamedSource('/b.dart', '');
    addNamedSource('/c.dart', 'import "a.dart"; import "d.dart";');
    addNamedSource('/d.dart', 'import "b.dart"; import "c.dart";');
    createLinker('');
    LibraryElementForLink libA = getLibrary('file:///a.dart');
    LibraryElementForLink libB = getLibrary('file:///b.dart');
    LibraryElementForLink libC = getLibrary('file:///c.dart');
    LibraryElementForLink libD = getLibrary('file:///d.dart');
    LibraryCycleForLink libraryCycle = libC.libraryCycleForLink;
    expect(libD.libraryCycleForLink, same(libraryCycle));
    expect(libraryCycle.dependencies,
        unorderedEquals([libA.libraryCycleForLink, libB.libraryCycleForLink]));
    expect(libraryCycle.libraries, unorderedEquals([libC, libD]));
  }

  void test_libraryCycle_nontrivial_via_export() {
    addNamedSource('/a.dart', 'export "b.dart";');
    addNamedSource('/b.dart', 'export "a.dart";');
    createLinker('');
    LibraryElementForLink libA = getLibrary('file:///a.dart');
    LibraryElementForLink libB = getLibrary('file:///b.dart');
    LibraryCycleForLink libraryCycle = libA.libraryCycleForLink;
    expect(libB.libraryCycleForLink, same(libraryCycle));
    expect(libraryCycle.dependencies, isEmpty);
    expect(libraryCycle.libraries, unorderedEquals([libA, libB]));
  }

  void test_libraryCycle_trivial() {
    createLinker('');
    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
    expect(libraryCycle.dependencies, isEmpty);
    expect(libraryCycle.libraries, [testLibrary]);
  }

  void test_libraryCycle_trivial_dependencies() {
    addNamedSource('/a.dart', '');
    addNamedSource('/b.dart', '');
    createLinker('import "a.dart"; import "b.dart";');
    LibraryElementForLink libA = getLibrary('file:///a.dart');
    LibraryElementForLink libB = getLibrary('file:///b.dart');
    LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
    expect(libraryCycle.dependencies,
        unorderedEquals([libA.libraryCycleForLink, libB.libraryCycleForLink]));
    expect(libraryCycle.libraries, [testLibrary]);
  }

  void test_multiplyInheritedExecutable_differentSignatures() {
    createLinker('''
class B {
  void f() {}
}
abstract class I {
   f();
}
class C extends B with I {}
class D extends C {
  void f() {}
}
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    library.libraryCycleForLink.ensureLinked();
    // No assertions--just make sure it doesn't crash.
  }

  void test_parameterParentElementForLink_implicitFunctionTypeIndices() {
    createLinker('void f(a, void g(b, c, d, void h())) {}');
    TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
    expect(f.implicitFunctionTypeIndices, []);
    ParameterElementForLink g = f.parameters[1];
    FunctionType gType = g.type;
    FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
    expect(gTypeElement.implicitFunctionTypeIndices, [1]);
    ParameterElementForLink h = gTypeElement.parameters[3];
    FunctionType hType = h.type;
    FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
    expect(hTypeElement.implicitFunctionTypeIndices, [1, 3]);
  }

  void test_parameterParentElementForLink_innermostExecutable() {
    createLinker('void f(void g(void h())) {}');
    TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
    expect(f.typeParameterContext, same(f));
    ParameterElementForLink g = f.parameters[0];
    FunctionType gType = g.type;
    FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
    expect(gTypeElement.typeParameterContext, same(f));
    ParameterElementForLink h = gTypeElement.parameters[0];
    FunctionType hType = h.type;
    FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
    expect(hTypeElement.typeParameterContext, same(f));
  }

  void test_topLevelFunction_isStatic() {
    createLinker('f() {}');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    TopLevelFunctionElementForLink f = library.getContainedName('f');
    expect(f.isStatic, true);
  }

  void test_topLevelGetter_isStatic() {
    createLinker('get x => null;');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    PropertyAccessorElementForLink_Executable x = library.getContainedName('x');
    expect(x.isStatic, true);
  }

  void test_topLevelSetter_isStatic() {
    createLinker('void set x(value) {}');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    PropertyAccessorElementForLink_Executable x =
        library.getContainedName('x=');
    expect(x.isStatic, true);
  }

  void test_topLevelVariable_isStatic() {
    createLinker('var x;');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
    expect(x.isStatic, true);
    expect(x.variable.isStatic, true);
  }

  void test_typeParameter_computeDeBruijnIndex_direct() {
    createLinker('class C<T, U> {}');
    ClassElementForLink_Class c = testLibrary.getContainedName('C');
    TypeParameterElementImpl t = c.typeParameters[0];
    TypeParameterElementImpl u = c.typeParameters[1];
    expect(c.computeDeBruijnIndex(t), 2);
    expect(c.computeDeBruijnIndex(u), 1);
  }

  void test_typeParameter_computeDeBruijnIndex_indirect() {
    createLinker('class C<T, U> { f<V, W>() {} }');
    ClassElementForLink_Class c = testLibrary.getContainedName('C');
    MethodElementForLink f = c.methods[0];
    TypeParameterElementImpl t = c.typeParameters[0];
    TypeParameterElementImpl u = c.typeParameters[1];
    expect(f.computeDeBruijnIndex(t), 4);
    expect(f.computeDeBruijnIndex(u), 3);
  }

  void test_typeParameter_computeDeBruijnIndex_reversed() {
    createLinker('class C<T, U> { f<V, W>() {} }');
    ClassElementForLink_Class c = testLibrary.getContainedName('C');
    MethodElementForLink f = c.methods[0];
    TypeParameterElementImpl v = f.typeParameters[0];
    TypeParameterElementImpl w = f.typeParameters[1];
    expect(c.computeDeBruijnIndex(v), isNull);
    expect(c.computeDeBruijnIndex(w), isNull);
  }

  void test_typeParameter_computeDeBruijnIndex_unrelated() {
    createLinker('class C<T, U> {} class D<V, W> {}');
    ClassElementForLink_Class c = testLibrary.getContainedName('C');
    ClassElementForLink_Class d = testLibrary.getContainedName('D');
    TypeParameterElementImpl t = c.typeParameters[0];
    TypeParameterElementImpl u = c.typeParameters[1];
    TypeParameterElementImpl v = d.typeParameters[0];
    TypeParameterElementImpl w = d.typeParameters[1];
    expect(c.computeDeBruijnIndex(v), isNull);
    expect(c.computeDeBruijnIndex(w), isNull);
    expect(d.computeDeBruijnIndex(t), isNull);
    expect(d.computeDeBruijnIndex(u), isNull);
  }

  void test_variable_initializer_presence() {
    // Any variable declaration with an initializer should have a non-null value
    // for `initializer`, regardless of whether it is constant and regardless of
    // whether it has an explicit type.
    createLinker('''
const int c = 0;
int i = 0;
int j;
var v = 0;
''');
    LibraryElementForLink library = linker.getLibrary(testDartUri);
    PropertyAccessorElementForLink_Variable c = library.getContainedName('c');
    expect(c.variable.initializer, isNotNull);
    PropertyAccessorElementForLink_Variable i = library.getContainedName('i');
    expect(i.variable.initializer, isNotNull);
    PropertyAccessorElementForLink_Variable j = library.getContainedName('j');
    expect(j.variable.initializer, isNull);
    PropertyAccessorElementForLink_Variable v = library.getContainedName('v');
    expect(v.variable.initializer, isNotNull);
  }

  VariableElementForLink _getVariable(ReferenceableElementForLink element) {
    return (element as PropertyAccessorElementForLink_Variable).variable;
  }

  /**
   * Finds the first inferred type stored in [unit] whose slot matches [slot].
   */
  EntityRef _lookupInferredType(LinkedUnit unit, int slot) {
    for (EntityRef ref in unit.types) {
      if (ref.slot == slot) {
        return ref;
      }
    }
    return null;
  }
}
