// Copyright (c) 2017, 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:expect/legacy/minitest.dart"; // ignore: deprecated_member_use

import "package:kernel/ast.dart";
import "package:kernel/class_hierarchy.dart";
import "package:kernel/core_types.dart";
import "package:kernel/testing/mock_sdk_component.dart";
import "package:kernel/text/ast_to_text.dart";
import "package:kernel/src/text_util.dart";

void main() {
  new ClosedWorldClassHierarchyTest().test_applyTreeChanges();

  new ClosedWorldClassHierarchyTest().test_applyMemberChanges();

  new ClosedWorldClassHierarchyTest()
      .test_getSingleTargetForInterfaceInvocation();

  new ClosedWorldClassHierarchyTest().test_getSubtypesOf();

  new ClosedWorldClassHierarchyTest()
      .test_forEachOverridePair_supertypeOverridesInterface();

  new ClosedWorldClassHierarchyTest()
      .test_forEachOverridePair_supertypeOverridesThis();

  new ClosedWorldClassHierarchyTest()
      .test_forEachOverridePair_supertypeOverridesThisAbstract();

  new ClosedWorldClassHierarchyTest()
      .test_forEachOverridePair_thisOverridesSupertype();

  new ClosedWorldClassHierarchyTest()
      .test_forEachOverridePair_thisOverridesSupertype_setter();

  new ClosedWorldClassHierarchyTest()
      .test_getClassAsInstanceOf_generic_extends();

  new ClosedWorldClassHierarchyTest()
      .test_getClassAsInstanceOf_generic_implements();

  new ClosedWorldClassHierarchyTest().test_getClassAsInstanceOf_generic_with();

  new ClosedWorldClassHierarchyTest()
      .test_getClassAsInstanceOf_notGeneric_extends();

  new ClosedWorldClassHierarchyTest()
      .test_getClassAsInstanceOf_notGeneric_implements();

  new ClosedWorldClassHierarchyTest()
      .test_getClassAsInstanceOf_notGeneric_with();

  new ClosedWorldClassHierarchyTest().test_getDeclaredMembers();

  new ClosedWorldClassHierarchyTest().test_getDispatchTarget();

  new ClosedWorldClassHierarchyTest().test_getDispatchTarget_abstract();

  new ClosedWorldClassHierarchyTest().test_getInterfaceMember_extends();

  new ClosedWorldClassHierarchyTest().test_getInterfaceMember_implements();

  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_in_class();

  new ClosedWorldClassHierarchyTest()
      .test_getInterfaceMembers_inherited_or_mixed_in();

  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_multiple();

  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_shadowed();

  new ClosedWorldClassHierarchyTest().test_getOrderedClasses();

  new ClosedWorldClassHierarchyTest()
      .test_getTypeAsInstanceOf_generic_extends();
}

class ClosedWorldClassHierarchyTest {
  final Component component = createMockSdkComponent();
  late CoreTypes coreTypes;

  late Library library;

  ClassHierarchy? _hierarchy;

  ClosedWorldClassHierarchyTest() {
    coreTypes = new CoreTypes(component);
    Uri uri = Uri.parse('org-dartlang:///test.dart');
    library = new Library(uri, fileUri: uri, name: 'test');
    library.parent = component;
    component.libraries.add(library);
  }

  ClassHierarchy createClassHierarchy(Component component) {
    return new ClassHierarchy(component, coreTypes);
  }

  void test_applyTreeChanges() {
    Class a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    _assertLibraryText(library, '''
class A {}
''');

    Uri uriB = Uri.parse('org-dartlang:///test_b.dart');
    Class b = new Class(
        name: 'B', supertype: a.asThisSupertype, fileUri: library.fileUri);
    Library libWithB = new Library(uriB, fileUri: uriB, name: 'test_b');
    libWithB.parent = component;
    component.libraries.add(libWithB);
    libWithB.addClass(b);
    _assertLibraryText(libWithB, '''
library test_b;
import self as self;
import "test.dart" as test;

class B extends test::A { // from org-dartlang:///test.dart
}
''');

    // No updated classes, the same hierarchy.
    expect(hierarchy.applyTreeChanges([], [], []), same(hierarchy));

    // Has updated classes, still the same hierarchy (instance). Can answer
    // queries about the new classes.
    var c = new Class(
        name: 'C', supertype: a.asThisSupertype, fileUri: library.fileUri);
    Uri uriC = Uri.parse('org-dartlang:///test2.dart');
    Library libWithC = new Library(uriC, fileUri: uriC, name: 'test2');
    libWithC.parent = component;
    component.libraries.add(libWithC);
    libWithC.addClass(c);

    expect(hierarchy.applyTreeChanges([libWithB], [libWithC], []),
        same(hierarchy));
    expect(hierarchy.isSubclassOf(a, c), false);
    expect(hierarchy.isSubclassOf(c, a), true);

    // Remove so A should no longer be a super of anything.
    expect(hierarchy.applyTreeChanges([libWithC], [], []), same(hierarchy));
  }

  void test_applyMemberChanges() {
    var methodA1 = newEmptyMethod('memberA1');
    var methodA2 = newEmptyMethod('memberA2');
    var methodA3 = newEmptyMethod('memberA3');
    var methodB1 = newEmptyMethod('memberB1');

    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [methodA1, methodA2],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [methodB1],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method memberA1() → void {}
  method memberA2() → void {}
}
class B extends self::A {
  method memberB1() → void {}
}
''');

    // No changes: B has memberA1, memberA2 and memberB1;
    // A has memberA1 and memberA2
    expect(hierarchy.getDispatchTargets(b),
        unorderedEquals([methodA1, methodA2, methodB1]));
    expect(
        hierarchy.getDispatchTargets(a), unorderedEquals([methodA1, methodA2]));

    // Add a member to A, but only update A.
    a.addProcedure(methodA3);
    hierarchy.applyMemberChanges([a]);
    expect(hierarchy.getDispatchTargets(b),
        unorderedEquals([methodA1, methodA2, methodB1]));
    expect(hierarchy.getDispatchTargets(a),
        unorderedEquals([methodA1, methodA2, methodA3]));

    // Apply member changes again, this time telling the hierarchy to find
    // descendants.
    hierarchy.applyMemberChanges([a], findDescendants: true);
    expect(hierarchy.getDispatchTargets(b),
        unorderedEquals([methodA1, methodA2, methodA3, methodB1]));
    expect(hierarchy.getDispatchTargets(a),
        unorderedEquals([methodA1, methodA2, methodA3]));
  }

  void test_getSingleTargetForInterfaceInvocation() {
    var methodInA = newEmptyMethod('foo', isAbstract: true);
    var methodInB = newEmptyMethod('foo');
    var methodInD = newEmptyMethod('foo');
    var methodInE = newEmptyMethod('foo');

    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [methodInA],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        isAbstract: true,
        supertype: objectSuper,
        procedures: [methodInB],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        implementedTypes: [a.asThisSupertype],
        fileUri: library.fileUri));
    addClass(new Class(
        name: 'D',
        supertype: b.asThisSupertype,
        procedures: [methodInD],
        fileUri: library.fileUri));
    addClass(new Class(
        name: 'E',
        isAbstract: true,
        supertype: objectSuper,
        implementedTypes: [c.asThisSupertype],
        procedures: [methodInE],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  abstract method foo() → void;
}
abstract class B {
  method foo() → void {}
}
class C extends self::B implements self::A {}
class D extends self::B {
  method foo() → void {}
}
abstract class E implements self::C {
  method foo() → void {}
}
''');

    ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
    ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();

    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInA), methodInB);
    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInB),
        null); // B::foo and D::foo
    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInD), methodInD);
    expect(cwchst.getSingleTargetForInterfaceInvocation(methodInE),
        null); // no concrete subtypes
  }

  void test_getSubtypesOf() {
    var a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    var b = addClass(
        new Class(name: 'B', supertype: objectSuper, fileUri: library.fileUri));
    var c = addClass(
        new Class(name: 'C', supertype: objectSuper, fileUri: library.fileUri));

    var d = addClass(new Class(
        name: 'D', supertype: a.asThisSupertype, fileUri: library.fileUri));

    var e = addClass(new Class(
        name: 'E',
        supertype: b.asThisSupertype,
        implementedTypes: [c.asThisSupertype],
        fileUri: library.fileUri));

    var f = addClass(new Class(
        name: 'F',
        supertype: e.asThisSupertype,
        implementedTypes: [a.asThisSupertype],
        fileUri: library.fileUri));

    var g = addClass(
        new Class(name: 'G', supertype: objectSuper, fileUri: library.fileUri));

    var h = addClass(new Class(
        name: 'H',
        supertype: g.asThisSupertype,
        implementedTypes: [c.asThisSupertype, a.asThisSupertype],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {}
class B {}
class C {}
class D extends self::A {}
class E extends self::B implements self::C {}
class F extends self::E implements self::A {}
class G {}
class H extends self::G implements self::C, self::A {}
''');

    ClosedWorldClassHierarchy cwch = hierarchy as ClosedWorldClassHierarchy;
    ClassHierarchySubtypes cwchst = cwch.computeSubtypesInformation();

    expect(cwchst.getSubtypesOf(a), unorderedEquals([a, d, f, h]));
    expect(cwchst.getSubtypesOf(b), unorderedEquals([b, e, f]));
    expect(cwchst.getSubtypesOf(c), unorderedEquals([c, e, f, h]));
    expect(cwchst.getSubtypesOf(d), unorderedEquals([d]));
    expect(cwchst.getSubtypesOf(e), unorderedEquals([e, f]));
    expect(cwchst.getSubtypesOf(f), unorderedEquals([f]));
    expect(cwchst.getSubtypesOf(g), unorderedEquals([g, h]));
    expect(cwchst.getSubtypesOf(h), unorderedEquals([h]));
  }

  /// Return the new or existing instance of [ClassHierarchy].
  ClassHierarchy get hierarchy {
    return _hierarchy ??= createClassHierarchy(component);
  }

  Class get objectClass => coreTypes.objectClass;

  Supertype get objectSuper => coreTypes.objectClass.asThisSupertype;

  Class addClass(Class c) {
    if (_hierarchy != null) {
      fail('The class hierarchy has already been created.');
    }
    library.addClass(c);
    return c;
  }

  /// Add a new generic class with the given [name] and [typeParameterNames].
  /// The [TypeParameterType]s corresponding to [typeParameterNames] are
  /// passed to optional [extends_] and [implements_] callbacks.
  Class addGenericClass(String name, List<String> typeParameterNames,
      {Supertype Function(List<DartType> typeParameterTypes)? extends_,
      List<Supertype> Function(List<DartType> typeParameterTypes)?
          implements_}) {
    var typeParameters = typeParameterNames
        .map((name) => new TypeParameter(
            name, coreTypes.objectNullableRawType, const DynamicType()))
        .toList();
    var typeParameterTypes = typeParameters
        .map((parameter) =>
            new TypeParameterType(parameter, Nullability.undetermined))
        .toList();
    var supertype =
        extends_ != null ? extends_(typeParameterTypes) : objectSuper;
    var implementedTypes =
        implements_ != null ? implements_(typeParameterTypes) : <Supertype>[];
    return addClass(new Class(
        name: name,
        typeParameters: typeParameters,
        supertype: supertype,
        implementedTypes: implementedTypes,
        fileUri: library.fileUri));
  }

  Procedure newEmptyGetter(String name,
      {DartType returnType = const DynamicType(), bool isAbstract = false}) {
    var body =
        isAbstract ? null : new Block([new ReturnStatement(new NullLiteral())]);
    return new Procedure(new Name(name), ProcedureKind.Getter,
        new FunctionNode(body, returnType: returnType),
        fileUri: library.fileUri);
  }

  Procedure newEmptyMethod(String name, {bool isAbstract = false}) {
    var body = isAbstract ? null : new Block([]);
    return new Procedure(new Name(name), ProcedureKind.Method,
        new FunctionNode(body, returnType: const VoidType()),
        isAbstract: isAbstract, fileUri: library.fileUri);
  }

  Procedure newEmptySetter(String name,
      {bool isAbstract = false, DartType type = const DynamicType()}) {
    var body = isAbstract ? null : new Block([]);
    return new Procedure(
        new Name(name),
        ProcedureKind.Setter,
        new FunctionNode(body,
            returnType: const VoidType(),
            positionalParameters: [new VariableDeclaration('_', type: type)]),
        fileUri: library.fileUri);
  }

  /// 2. A non-abstract member is inherited from a superclass, and in the
  /// context of this class, it overrides an abstract member inheritable through
  /// one of its superinterfaces.
  void test_forEachOverridePair_supertypeOverridesInterface() {
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype],
        fileUri: library.fileUri));
    var d = addClass(
        new Class(name: 'D', supertype: objectSuper, fileUri: library.fileUri));
    var e = addClass(new Class(
        name: 'E',
        supertype: d.asThisSupertype,
        mixedInType: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method foo() → void {}
  method bar() → void {}
}
class B extends self::A {
  abstract method foo() → void;
}
class C extends self::A implements self::B {}
class D {}
class E = self::D with self::A implements self::B {}
''');

    _assertOverridePairs(c, []);
    _assertOverridePairs(e, ['test::A.foo overrides test::B.foo']);
  }

  /// An abstract member declared in the class is overridden by a member in
  /// one of the interfaces.
  void test_forEachOverridePair_supertypeOverridesThis() {
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [newEmptyMethod('foo')],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)],
        isAbstract: true,
        fileUri: library.fileUri));
    var d = addClass(new Class(
        name: 'D', supertype: b.asThisSupertype, fileUri: library.fileUri));
    var e = addClass(new Class(
        name: 'E', supertype: c.asThisSupertype, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method foo() → void {}
}
class B extends self::A {
  abstract method foo() → void;
}
abstract class C extends self::A {
  abstract method foo() → void;
}
class D extends self::B {}
class E extends self::C {}
''');

    _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
    _assertOverridePairs(c, ['test::C.foo overrides test::A.foo']);
    _assertOverridePairs(d, []);
    _assertOverridePairs(e, []);
  }

  /// 3. A non-abstract member is inherited from a superclass, and it overrides
  /// an abstract member declared in this class.
  void test_forEachOverridePair_supertypeOverridesThisAbstract() {
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method foo() → void {}
  method bar() → void {}
}
class B extends self::A {
  abstract method foo() → void;
}
''');

    // The documentation says:
    // It is possible for two methods to override one another in both
    // directions.
    _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
  }

  /// 1. A member declared in the class overrides a member inheritable through
  /// one of the supertypes of the class.
  void test_forEachOverridePair_thisOverridesSupertype() {
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo')],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        procedures: [newEmptyMethod('bar')],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method foo() → void {}
  method bar() → void {}
}
class B extends self::A {
  method foo() → void {}
}
class C extends self::B {
  method bar() → void {}
}
''');

    _assertOverridePairs(b, ['test::B.foo overrides test::A.foo']);
    _assertOverridePairs(c, ['test::C.bar overrides test::A.bar']);
  }

  /// 1. A member declared in the class overrides a member inheritable through
  /// one of the supertypes of the class.
  void test_forEachOverridePair_thisOverridesSupertype_setter() {
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [newEmptySetter('foo'), newEmptySetter('bar')],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptySetter('foo')],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        procedures: [newEmptySetter('bar')],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  set foo(dynamic _) → void {}
  set bar(dynamic _) → void {}
}
class B extends self::A {
  set foo(dynamic _) → void {}
}
class C extends self::B {
  set bar(dynamic _) → void {}
}
''');

    _assertOverridePairs(b, ['test::B.foo= overrides test::A.foo=']);
    _assertOverridePairs(c, ['test::C.bar= overrides test::A.bar=']);
  }

  void test_getClassAsInstanceOf_generic_extends() {
    var int = coreTypes.intNonNullableRawType;
    var bool = coreTypes.boolNonNullableRawType;

    var a = addGenericClass('A', ['T', 'U']);

    var bT = new TypeParameter(
        'T', coreTypes.objectNullableRawType, const DynamicType());
    var bTT = new TypeParameterType(bT, Nullability.undetermined);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: new Supertype(a, [bTT, bool]),
        fileUri: library.fileUri));

    var c = addClass(new Class(
        name: 'C',
        supertype: new Supertype(b, [int]),
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A<T? = dynamic, U? = dynamic> {}
class B<T? = dynamic> extends self::A<self::B::T%, core::bool> {}
class C extends self::B<core::int> {}
''');

    expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
    expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
    expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
    expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
  }

  void test_getClassAsInstanceOf_generic_implements() {
    var int = coreTypes.intNonNullableRawType;
    var bool = coreTypes.boolNonNullableRawType;

    var a = addGenericClass('A', ['T', 'U']);

    var bT = new TypeParameter(
        'T', coreTypes.objectNullableRawType, const DynamicType());
    var bTT = new TypeParameterType(bT, Nullability.undetermined);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: objectSuper,
        implementedTypes: [
          new Supertype(a, [bTT, bool])
        ],
        fileUri: library.fileUri));

    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [
          new Supertype(b, [int])
        ],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A<T? = dynamic, U? = dynamic> {}
class B<T? = dynamic> implements self::A<self::B::T%, core::bool> {}
class C implements self::B<core::int> {}
''');

    expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
    expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
    expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
    expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
  }

  void test_getClassAsInstanceOf_generic_with() {
    var int = coreTypes.intNonNullableRawType;
    var bool = coreTypes.boolNonNullableRawType;

    var a = addGenericClass('A', ['T', 'U']);

    var bT = new TypeParameter(
        'T', coreTypes.objectNullableRawType, const DynamicType());
    var bTT = new TypeParameterType(bT, Nullability.undetermined);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: objectSuper,
        mixedInType: new Supertype(a, [bTT, bool]),
        fileUri: library.fileUri));

    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        mixedInType: new Supertype(b, [int]),
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A<T? = dynamic, U? = dynamic> {}
class B<T? = dynamic> = core::Object with self::A<self::B::T%, core::bool> {}
class C = core::Object with self::B<core::int> {}
''');

    expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
    expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(b, a), new Supertype(a, [bTT, bool]));
    expect(hierarchy.getClassAsInstanceOf(c, b), new Supertype(b, [int]));
    expect(hierarchy.getClassAsInstanceOf(c, a), new Supertype(a, [int, bool]));
  }

  void test_getClassAsInstanceOf_notGeneric_extends() {
    var a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B', supertype: a.asThisSupertype, fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C', supertype: b.asThisSupertype, fileUri: library.fileUri));
    var z = addClass(
        new Class(name: 'Z', supertype: objectSuper, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {}
class B extends self::A {}
class C extends self::B {}
class Z {}
''');

    expect(hierarchy.getClassAsInstanceOf(a, objectClass), objectSuper);
    expect(hierarchy.getClassAsInstanceOf(a, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(b, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(c, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(c, b), b.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(z, a), null);
    expect(hierarchy.getClassAsInstanceOf(z, objectClass), objectSuper);
  }

  void test_getClassAsInstanceOf_notGeneric_implements() {
    var a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    var b = addClass(
        new Class(name: 'B', supertype: objectSuper, fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype],
        fileUri: library.fileUri));
    var d = addClass(new Class(
        name: 'D',
        supertype: objectSuper,
        implementedTypes: [c.asThisSupertype],
        fileUri: library.fileUri));
    var e = addClass(new Class(
        name: 'D',
        supertype: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype],
        fileUri: library.fileUri));
    var z = addClass(
        new Class(name: 'Z', supertype: objectSuper, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {}
class B {}
class C implements self::A {}
class D implements self::C {}
class D extends self::A implements self::B {}
class Z {}
''');

    expect(hierarchy.getClassAsInstanceOf(c, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(d, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(d, c), c.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(e, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(e, b), b.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(z, a), null);
  }

  void test_getClassAsInstanceOf_notGeneric_with() {
    var a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: objectSuper,
        mixedInType: a.asThisSupertype,
        fileUri: library.fileUri));
    var z = addClass(
        new Class(name: 'Z', supertype: objectSuper, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {}
class B = core::Object with self::A {}
class Z {}
''');

    expect(hierarchy.getClassAsInstanceOf(b, objectClass), objectSuper);
    expect(hierarchy.getClassAsInstanceOf(b, a), a.asThisSupertype);
    expect(hierarchy.getClassAsInstanceOf(z, a), null);
  }

  void test_getDeclaredMembers() {
    var method = newEmptyMethod('method');
    var getter = newEmptyGetter('getter');
    var setter = newEmptySetter('setter');
    var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true);
    var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true);
    var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true);
    var nonFinalField =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);
    var a = addClass(new Class(
        isAbstract: true,
        name: 'A',
        supertype: objectSuper,
        fields: [nonFinalField, finalField],
        procedures: [
          method,
          getter,
          setter,
          abstractMethod,
          abstractGetter,
          abstractSetter
        ],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        isAbstract: true,
        name: 'B',
        supertype: a.asThisSupertype,
        fileUri: library.fileUri));

    _assertTestLibraryText('''
abstract class A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
  abstract method abstractMethod() → void;
  get abstractGetter() → dynamic;
  set abstractSetter(dynamic _) → void;
}
abstract class B extends self::A {}
''');

    expect(
        hierarchy.getDeclaredMembers(a),
        unorderedEquals([
          method,
          getter,
          abstractMethod,
          abstractGetter,
          nonFinalField,
          finalField
        ]));
    expect(hierarchy.getDeclaredMembers(a, setters: true),
        unorderedEquals([setter, abstractSetter, nonFinalField]));
    expect(hierarchy.getDeclaredMembers(b).isEmpty, isTrue);
    expect(hierarchy.getDeclaredMembers(b, setters: true).isEmpty, isTrue);
  }

  void test_getDispatchTarget() {
    var aMethod = newEmptyMethod('aMethod');
    var aSetter = newEmptySetter('aSetter');
    var bMethod = newEmptyMethod('bMethod');
    var bSetter = newEmptySetter('bSetter');
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [aMethod, aSetter],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bMethod, bSetter],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C', supertype: b.asThisSupertype, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method aMethod() → void {}
  set aSetter(dynamic _) → void {}
}
class B extends self::A {
  method bMethod() → void {}
  set bSetter(dynamic _) → void {}
}
class C extends self::B {}
''');

    var aMethodName = new Name('aMethod');
    var aSetterName = new Name('aSetter');
    var bMethodName = new Name('bMethod');
    var bSetterName = new Name('bSetter');
    expect(hierarchy.getDispatchTarget(a, aMethodName), aMethod);
    expect(hierarchy.getDispatchTarget(a, bMethodName), isNull);
    expect(hierarchy.getDispatchTarget(a, aSetterName, setter: true), aSetter);
    expect(hierarchy.getDispatchTarget(a, bSetterName, setter: true), isNull);
    expect(hierarchy.getDispatchTarget(b, aMethodName), aMethod);
    expect(hierarchy.getDispatchTarget(b, bMethodName), bMethod);
    expect(hierarchy.getDispatchTarget(b, aSetterName, setter: true), aSetter);
    expect(hierarchy.getDispatchTarget(b, bSetterName, setter: true), bSetter);
    expect(hierarchy.getDispatchTarget(c, aMethodName), aMethod);
    expect(hierarchy.getDispatchTarget(c, bMethodName), bMethod);
    expect(hierarchy.getDispatchTarget(c, aSetterName, setter: true), aSetter);
    expect(hierarchy.getDispatchTarget(c, bSetterName, setter: true), bSetter);
  }

  void test_getDispatchTarget_abstract() {
    var aFoo = newEmptyMethod('foo', isAbstract: true);
    var aBar = newEmptyMethod('bar');
    var bFoo = newEmptyMethod('foo');
    var bBar = newEmptyMethod('bar', isAbstract: true);
    var a = addClass(new Class(
        isAbstract: true,
        name: 'A',
        supertype: objectSuper,
        procedures: [aFoo, aBar],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        isAbstract: true,
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bFoo, bBar],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C', supertype: b.asThisSupertype, fileUri: library.fileUri));

    _assertTestLibraryText('''
abstract class A {
  abstract method foo() → void;
  method bar() → void {}
}
abstract class B extends self::A {
  method foo() → void {}
  abstract method bar() → void;
}
class C extends self::B {}
''');

    expect(hierarchy.getDispatchTarget(a, new Name('foo')), isNull);
    expect(hierarchy.getDispatchTarget(b, new Name('foo')), bFoo);
    expect(hierarchy.getDispatchTarget(c, new Name('foo')), bFoo);

    expect(hierarchy.getDispatchTarget(a, new Name('bar')), aBar);
    expect(hierarchy.getDispatchTarget(b, new Name('bar')), aBar);
    expect(hierarchy.getDispatchTarget(c, new Name('bar')), aBar);
  }

  void test_getInterfaceMember_extends() {
    var aMethod = newEmptyMethod('aMethod');
    var aSetter = newEmptySetter('aSetter');
    var bMethod = newEmptyMethod('bMethod');
    var bSetter = newEmptySetter('bSetter');
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [aMethod, aSetter],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bMethod, bSetter],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C', supertype: b.asThisSupertype, fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method aMethod() → void {}
  set aSetter(dynamic _) → void {}
}
class B extends self::A {
  method bMethod() → void {}
  set bSetter(dynamic _) → void {}
}
class C extends self::B {}
''');

    var aMethodName = new Name('aMethod');
    var aSetterName = new Name('aSetter');
    var bMethodName = new Name('bMethod');
    var bSetterName = new Name('bSetter');
    expect(hierarchy.getInterfaceMember(a, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(a, bMethodName), isNull);
    expect(hierarchy.getInterfaceMember(a, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(a, bSetterName, setter: true), isNull);
    expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod);
    expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter);
    expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod);
    expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter);
  }

  void test_getInterfaceMember_implements() {
    var aMethod = newEmptyMethod('aMethod');
    var aSetter = newEmptySetter('aSetter');
    var bMethod = newEmptyMethod('bMethod');
    var bSetter = newEmptySetter('bSetter');
    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        procedures: [aMethod, aSetter],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype],
        procedures: [bMethod, bSetter],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [b.asThisSupertype],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  method aMethod() → void {}
  set aSetter(dynamic _) → void {}
}
class B implements self::A {
  method bMethod() → void {}
  set bSetter(dynamic _) → void {}
}
class C implements self::B {}
''');

    var aMethodName = new Name('aMethod');
    var aSetterName = new Name('aSetter');
    var bMethodName = new Name('bMethod');
    var bSetterName = new Name('bSetter');
    expect(hierarchy.getInterfaceMember(a, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(a, bMethodName), isNull);
    expect(hierarchy.getInterfaceMember(a, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(a, bSetterName, setter: true), isNull);
    expect(hierarchy.getInterfaceMember(b, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(b, bMethodName), bMethod);
    expect(hierarchy.getInterfaceMember(b, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(b, bSetterName, setter: true), bSetter);
    expect(hierarchy.getInterfaceMember(c, aMethodName), aMethod);
    expect(hierarchy.getInterfaceMember(c, bMethodName), bMethod);
    expect(hierarchy.getInterfaceMember(c, aSetterName, setter: true), aSetter);
    expect(hierarchy.getInterfaceMember(c, bSetterName, setter: true), bSetter);
  }

  void test_getInterfaceMembers_in_class() {
    var method = newEmptyMethod('method');
    var getter = newEmptyGetter('getter');
    var setter = newEmptySetter('setter');
    var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true);
    var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true);
    var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true);
    var nonFinalField =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);
    var a = addClass(new Class(
        isAbstract: true,
        name: 'A',
        supertype: objectSuper,
        fields: [nonFinalField, finalField],
        procedures: [
          method,
          getter,
          setter,
          abstractMethod,
          abstractGetter,
          abstractSetter
        ],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
abstract class A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
  abstract method abstractMethod() → void;
  get abstractGetter() → dynamic;
  set abstractSetter(dynamic _) → void;
}
''');

    expect(
        hierarchy.getInterfaceMembers(a),
        unorderedEquals([
          method,
          getter,
          abstractMethod,
          abstractGetter,
          nonFinalField,
          finalField
        ]));
    expect(hierarchy.getInterfaceMembers(a, setters: true),
        unorderedEquals([setter, abstractSetter, nonFinalField]));
  }

  void test_getInterfaceMembers_inherited_or_mixed_in() {
    var method = newEmptyMethod('method');
    var getter = newEmptyGetter('getter');
    var setter = newEmptySetter('setter');
    var abstractMethod = newEmptyMethod('abstractMethod', isAbstract: true);
    var abstractGetter = newEmptyGetter('abstractGetter', isAbstract: true);
    var abstractSetter = newEmptySetter('abstractSetter', isAbstract: true);
    var nonFinalField =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);

    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        fields: [nonFinalField, finalField],
        procedures: [
          method,
          getter,
          setter,
          abstractMethod,
          abstractGetter,
          abstractSetter
        ],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B', supertype: a.asThisSupertype, fileUri: library.fileUri));
    var c = addClass(new Class(
        isAbstract: true,
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype],
        fileUri: library.fileUri));
    var d = addClass(new Class(
        name: 'D',
        supertype: objectSuper,
        mixedInType: a.asThisSupertype,
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
  abstract method abstractMethod() → void;
  get abstractGetter() → dynamic;
  set abstractSetter(dynamic _) → void;
}
class B extends self::A {}
abstract class C implements self::A {}
class D = core::Object with self::A {}
''');

    var expectedGetters = [
      method,
      getter,
      abstractMethod,
      abstractGetter,
      nonFinalField,
      finalField
    ];
    expect(hierarchy.getInterfaceMembers(b), unorderedEquals(expectedGetters));
    var expectedSetters = [setter, abstractSetter, nonFinalField];
    expect(hierarchy.getInterfaceMembers(b, setters: true),
        unorderedEquals(expectedSetters));
    expect(hierarchy.getInterfaceMembers(c), unorderedEquals(expectedGetters));
    expect(hierarchy.getInterfaceMembers(c, setters: true),
        unorderedEquals(expectedSetters));
    expect(hierarchy.getInterfaceMembers(d), unorderedEquals(expectedGetters));
    expect(hierarchy.getInterfaceMembers(d, setters: true),
        unorderedEquals(expectedSetters));
  }

  void test_getInterfaceMembers_multiple() {
    var method_a = newEmptyMethod('method');
    var getter_a = newEmptyGetter('getter');
    var setter_a = newEmptySetter('setter');
    var nonFinalField_a =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField_a = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);
    var method_b = newEmptyMethod('method');
    var getter_b = newEmptyGetter('getter');
    var setter_b = newEmptySetter('setter');
    var nonFinalField_b =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField_b = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);

    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        fields: [nonFinalField_a, finalField_a],
        procedures: [method_a, getter_a, setter_a],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: objectSuper,
        fields: [nonFinalField_b, finalField_b],
        procedures: [method_b, getter_b, setter_b],
        fileUri: library.fileUri));
    var c = addClass(new Class(
        isAbstract: true,
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype, b.asThisSupertype],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
}
class B {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
}
abstract class C implements self::A, self::B {}
''');

    expect(
        hierarchy.getInterfaceMembers(c),
        unorderedEquals([
          method_a,
          getter_a,
          nonFinalField_a,
          finalField_a,
          method_b,
          getter_b,
          nonFinalField_b,
          finalField_b
        ]));
    expect(
        hierarchy.getInterfaceMembers(c, setters: true),
        unorderedEquals(
            [setter_a, nonFinalField_a, setter_b, nonFinalField_b]));
  }

  void test_getInterfaceMembers_shadowed() {
    var method_a = newEmptyMethod('method');
    var nonShadowedMethod_a = newEmptyMethod('nonShadowedMethod');
    var getter_a = newEmptyGetter('getter');
    var setter_a = newEmptySetter('setter');
    var nonShadowedSetter_a = newEmptySetter('nonShadowedSetter');
    var nonFinalField_a =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField_a = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);
    var method_b = newEmptyMethod('method');
    var getter_b = newEmptyGetter('getter');
    var setter_b = newEmptySetter('setter');
    var nonFinalField_b =
        new Field.mutable(new Name('nonFinalField'), fileUri: library.fileUri);
    var finalField_b = new Field.immutable(new Name('finalField'),
        isFinal: true, fileUri: library.fileUri);

    var a = addClass(new Class(
        name: 'A',
        supertype: objectSuper,
        fields: [nonFinalField_a, finalField_a],
        procedures: [
          method_a,
          nonShadowedMethod_a,
          getter_a,
          setter_a,
          nonShadowedSetter_a
        ],
        fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        fields: [nonFinalField_b, finalField_b],
        procedures: [method_b, getter_b, setter_b],
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  method nonShadowedMethod() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
  set nonShadowedSetter(dynamic _) → void {}
}
class B extends self::A {
  field dynamic nonFinalField;
  final field dynamic finalField;
  method method() → void {}
  get getter() → dynamic {
    return null;
  }
  set setter(dynamic _) → void {}
}
''');

    expect(
        hierarchy.getInterfaceMembers(b),
        unorderedEquals([
          nonShadowedMethod_a,
          method_b,
          getter_b,
          nonFinalField_b,
          finalField_b
        ]));
    expect(hierarchy.getInterfaceMembers(b, setters: true),
        unorderedEquals([nonShadowedSetter_a, setter_b, nonFinalField_b]));
  }

  void test_getOrderedClasses() {
    var a = addClass(
        new Class(name: 'A', supertype: objectSuper, fileUri: library.fileUri));
    var b = addClass(new Class(
        name: 'B', supertype: a.asThisSupertype, fileUri: library.fileUri));
    var c = addClass(new Class(
        name: 'C', supertype: b.asThisSupertype, fileUri: library.fileUri));

    void assertOrderOfClasses(List<Class> unordered, List<Class> expected) {
      var ordered = hierarchy.getOrderedClasses(unordered);
      expect(ordered, expected);
    }

    assertOrderOfClasses([a, b, c], [a, b, c]);
    assertOrderOfClasses([b, a, c], [a, b, c]);
    assertOrderOfClasses([a, c, b], [a, b, c]);
    assertOrderOfClasses([b, c, a], [a, b, c]);
    assertOrderOfClasses([c, a, b], [a, b, c]);
    assertOrderOfClasses([c, b, a], [a, b, c]);
    assertOrderOfClasses([c, b], [b, c]);
  }

  void test_getTypeAsInstanceOf_generic_extends() {
    var int = coreTypes.intNonNullableRawType;
    var bool = coreTypes.boolNonNullableRawType;

    var a = addGenericClass('A', ['T', 'U']);

    var bT = new TypeParameter(
        'T', coreTypes.objectNullableRawType, const DynamicType());
    var bTT = new TypeParameterType(bT, Nullability.undetermined);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: new Supertype(a, [bTT, bool]),
        fileUri: library.fileUri));

    _assertTestLibraryText('''
class A<T? = dynamic, U? = dynamic> {}
class B<T? = dynamic> extends self::A<self::B::T%, core::bool> {}
''');

    var b_int = new InterfaceType(b, Nullability.nonNullable, [int]);
    expect(hierarchy.getInterfaceTypeAsInstanceOfClass(b_int, a),
        new InterfaceType(a, Nullability.nonNullable, [int, bool]));
    expect(hierarchy.getInterfaceTypeAsInstanceOfClass(b_int, objectClass),
        new InterfaceType(objectClass, Nullability.nonNullable));
  }

  void _assertOverridePairs(Class class_, List<String> expected) {
    List<String> overrideDescriptions = [];
    void callback(
        Member declaredMember, Member interfaceMember, bool isSetter) {
      var suffix = isSetter ? '=' : '';
      String declaredMemberName =
          qualifiedMemberNameToString(declaredMember, includeLibraryName: true);
      String declaredName = '${declaredMemberName}$suffix';
      String interfaceMemberName = qualifiedMemberNameToString(interfaceMember,
          includeLibraryName: true);
      String interfaceName = '${interfaceMemberName}$suffix';
      var desc = '$declaredName overrides $interfaceName';
      overrideDescriptions.add(desc);
    }

    hierarchy.forEachOverridePair(class_, callback);
    expect(overrideDescriptions, unorderedEquals(expected));
  }

  /// Assert that the test [library] has the [expectedText] presentation.
  /// The presentation is close, but not identical to the normal Kernel one.
  void _assertTestLibraryText(String expectedText) {
    _assertLibraryText(library, expectedText);
  }

  void _assertLibraryText(Library lib, String expectedText) {
    StringBuffer sb = new StringBuffer();
    Printer printer = new Printer(sb);
    printer.writeLibraryFile(lib);

    String actualText = sb.toString();

    // Clean up the text a bit.
    const oftenUsedPrefix = '''
library test;
import self as self;
import "dart:core" as core;

''';
    if (actualText.startsWith(oftenUsedPrefix)) {
      actualText = actualText.substring(oftenUsedPrefix.length);
    }
    actualText = actualText.replaceAll('{\n}', '{}');
    actualText = actualText.replaceAll(' extends core::Object', '');

    if (actualText != expectedText) {
      print('-------- Actual --------');
      print(actualText + '------------------------');
    }

    expect(actualText, expectedText);
  }
}
