// 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/matchers_lite.dart";

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";

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();
  CoreTypes coreTypes;

  final Library library =
      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');

  ClassHierarchy _hierarchy;

  ClosedWorldClassHierarchyTest() {
    coreTypes = new CoreTypes(component);
    library.parent = component;
    component.libraries.add(library);
  }

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

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

    Class b = new Class(name: 'B', supertype: a.asThisSupertype);
    Library libWithB =
        new Library(Uri.parse('org-dartlang:///test_b.dart'), 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 {}
''');

    // 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);
    Library libWithC =
        new Library(Uri.parse('org-dartlang:///test2.dart'), 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]));
    var b = addClass(new Class(
        name: 'B', supertype: a.asThisSupertype, procedures: [methodB1]));

    _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.addMember(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]));
    var b = addClass(new Class(
        name: 'B',
        isAbstract: true,
        supertype: objectSuper,
        procedures: [methodInB]));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        implementedTypes: [a.asThisSupertype]));
    addClass(new Class(
        name: 'D', supertype: b.asThisSupertype, procedures: [methodInD]));
    addClass(new Class(
        name: 'E',
        isAbstract: true,
        supertype: objectSuper,
        implementedTypes: [c.asThisSupertype],
        procedures: [methodInE]));

    _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));
    var b = addClass(new Class(name: 'B', supertype: objectSuper));
    var c = addClass(new Class(name: 'C', supertype: objectSuper));

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

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

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

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

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

    _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 classs 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 extends_(List<DartType> typeParameterTypes),
      List<Supertype> implements_(List<DartType> typeParameterTypes)}) {
    var typeParameters = typeParameterNames
        .map((name) => new TypeParameter(name, objectClass.rawType))
        .toList();
    var typeParameterTypes = typeParameters
        .map((parameter) => new TypeParameterType(parameter))
        .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));
  }

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

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

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

  /// 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')]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)]));
    var c = addClass(new Class(
        name: 'C',
        supertype: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype]));
    var d = addClass(new Class(name: 'D', supertype: objectSuper));
    var e = addClass(new Class(
        name: 'E',
        supertype: d.asThisSupertype,
        mixedInType: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype]));

    _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')]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)]));
    var c = addClass(new Class(
        name: 'C',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)],
        isAbstract: true));
    var d = addClass(new Class(name: 'D', supertype: b.asThisSupertype));
    var e = addClass(new Class(name: 'E', supertype: c.asThisSupertype));

    _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')]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo', isAbstract: true)]));

    _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')]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptyMethod('foo')]));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        procedures: [newEmptyMethod('bar')]));

    _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')]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [newEmptySetter('foo')]));
    var c = addClass(new Class(
        name: 'C',
        supertype: b.asThisSupertype,
        procedures: [newEmptySetter('bar')]));

    _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.intClass.rawType;
    var bool = coreTypes.boolClass.rawType;

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

    var bT = new TypeParameter('T', objectClass.rawType);
    var bTT = new TypeParameterType(bT);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: new Supertype(a, [bTT, bool])));

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

    _assertTestLibraryText('''
class A<T, U> {}
class B<T> 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.intClass.rawType;
    var bool = coreTypes.boolClass.rawType;

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

    var bT = new TypeParameter('T', objectClass.rawType);
    var bTT = new TypeParameterType(bT);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: objectSuper,
        implementedTypes: [
          new Supertype(a, [bTT, bool])
        ]));

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

    _assertTestLibraryText('''
class A<T, U> {}
class B<T> 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.intClass.rawType;
    var bool = coreTypes.boolClass.rawType;

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

    var bT = new TypeParameter('T', objectClass.rawType);
    var bTT = new TypeParameterType(bT);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: objectSuper,
        mixedInType: new Supertype(a, [bTT, bool])));

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

    _assertTestLibraryText('''
class A<T, U> {}
class B<T> = 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));
    var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype));
    var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));
    var z = addClass(new Class(name: 'Z', supertype: objectSuper));

    _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));
    var b = addClass(new Class(name: 'B', supertype: objectSuper));
    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype]));
    var d = addClass(new Class(
        name: 'D',
        supertype: objectSuper,
        implementedTypes: [c.asThisSupertype]));
    var e = addClass(new Class(
        name: 'D',
        supertype: a.asThisSupertype,
        implementedTypes: [b.asThisSupertype]));
    var z = addClass(new Class(name: 'Z', supertype: objectSuper));

    _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));
    var b = addClass(new Class(
        name: 'B', supertype: objectSuper, mixedInType: a.asThisSupertype));
    var z = addClass(new Class(name: 'Z', supertype: objectSuper));

    _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(new Name('nonFinalField'));
    var finalField = new Field(new Name('finalField'), isFinal: true);
    var a = addClass(new Class(
        isAbstract: true,
        name: 'A',
        supertype: objectSuper,
        fields: [
          nonFinalField,
          finalField
        ],
        procedures: [
          method,
          getter,
          setter,
          abstractMethod,
          abstractGetter,
          abstractSetter
        ]));
    var b = addClass(
        new Class(isAbstract: true, name: 'B', supertype: a.asThisSupertype));

    _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);
    expect(hierarchy.getDeclaredMembers(b, setters: true), isEmpty);
  }

  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]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bMethod, bSetter]));
    var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));

    _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]));
    var b = addClass(new Class(
        isAbstract: true,
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bFoo, bBar]));
    var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));

    _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]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        procedures: [bMethod, bSetter]));
    var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));

    _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]));
    var b = addClass(new Class(
        name: 'B',
        supertype: objectSuper,
        implementedTypes: [a.asThisSupertype],
        procedures: [bMethod, bSetter]));
    var c = addClass(new Class(
        name: 'C',
        supertype: objectSuper,
        implementedTypes: [b.asThisSupertype]));

    _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(new Name('nonFinalField'));
    var finalField = new Field(new Name('finalField'), isFinal: true);
    var a = addClass(new Class(
        isAbstract: true,
        name: 'A',
        supertype: objectSuper,
        fields: [
          nonFinalField,
          finalField
        ],
        procedures: [
          method,
          getter,
          setter,
          abstractMethod,
          abstractGetter,
          abstractSetter
        ]));

    _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(new Name('nonFinalField'));
    var finalField = new Field(new Name('finalField'), isFinal: true);

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

    _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(new Name('nonFinalField'));
    var finalField_a = new Field(new Name('finalField'), isFinal: true);
    var method_b = newEmptyMethod('method');
    var getter_b = newEmptyGetter('getter');
    var setter_b = newEmptySetter('setter');
    var nonFinalField_b = new Field(new Name('nonFinalField'));
    var finalField_b = new Field(new Name('finalField'), isFinal: true);

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

    _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(new Name('nonFinalField'));
    var finalField_a = new Field(new Name('finalField'), isFinal: true);
    var method_b = newEmptyMethod('method');
    var getter_b = newEmptyGetter('getter');
    var setter_b = newEmptySetter('setter');
    var nonFinalField_b = new Field(new Name('nonFinalField'));
    var finalField_b = new Field(new Name('finalField'), isFinal: true);

    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
    ]));
    var b = addClass(new Class(
        name: 'B',
        supertype: a.asThisSupertype,
        fields: [nonFinalField_b, finalField_b],
        procedures: [method_b, getter_b, setter_b]));

    _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));
    var b = addClass(new Class(name: 'B', supertype: a.asThisSupertype));
    var c = addClass(new Class(name: 'C', supertype: b.asThisSupertype));

    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.intClass.rawType;
    var bool = coreTypes.boolClass.rawType;

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

    var bT = new TypeParameter('T', objectClass.rawType);
    var bTT = new TypeParameterType(bT);
    var b = addClass(new Class(
        name: 'B',
        typeParameters: [bT],
        supertype: new Supertype(a, [bTT, bool])));

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

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

  void _assertOverridePairs(Class class_, List<String> expected) {
    List<String> overrideDescriptions = [];
    void callback(
        Member declaredMember, Member interfaceMember, bool isSetter) {
      var suffix = isSetter ? '=' : '';
      String declaredName = '$declaredMember$suffix';
      String interfaceName = '$interfaceMember$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);
  }
}
