// Copyright (c) 2014, 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.

library instantiated_classes_test;

import 'dart:async';
import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/elements/entities.dart'
    show ClassEntity, LibraryEntity;
import 'type_test_helper.dart';

void main() {
  Future runTests() async {
    Future test(String source, List<String> directlyInstantiatedClasses,
        [List<String> newClasses = const <String>["Class"]]) async {
      StringBuffer mainSource = new StringBuffer();
      mainSource.writeln(source);
      mainSource.write('main() {\n');
      for (String newClass in newClasses) {
        mainSource.write('  new $newClass();\n');
      }
      mainSource.write('}');
      dynamic env = await TypeEnvironment.create(mainSource.toString());
      LibraryEntity mainLibrary =
          env.compiler.frontendStrategy.elementEnvironment.mainLibrary;
      Iterable<ClassEntity> expectedClasses =
          directlyInstantiatedClasses.map((String name) {
        return env.getElement(name);
      });
      Iterable<ClassEntity> actualClasses = env
          .compiler.resolutionWorldBuilder.directlyInstantiatedClasses
          .where((c) => c.library == mainLibrary);
      Expect.setEquals(
          expectedClasses,
          actualClasses,
          "Instantiated classes mismatch: "
          "Expected $expectedClasses, actual: $actualClasses");
    }

    await test("class Class {}", ["Class"]);
    await test("""abstract class A {}
                  class Class extends A {}""", ["Class"]);
    await test("""class A {}
                  class Class extends A {}""", ["Class"]);
    await test("""class A {}
                  class B {}
                  class Class extends A {}""", ["Class"]);
    await test("""class A {}
                  class Class implements A {}""", ["Class"]);
    await test("""class A {}
                  class Class extends Object with A {}""", ["Class"]);
    await test("""class A {}
                  class B {}
                  class Class extends Object with B implements A {}""",
        ["Class"]);

    await test("""class A {}
                  class Class {}""", ["Class", "A"], ["Class", "A"]);
    await test("""class A {}
                  class Class extends A {}""", ["Class", "A"], ["Class", "A"]);
    await test("""class A {}
                  class Class implements A {}""", ["Class", "A"],
        ["Class", "A"]);
    await test("""class A {}
                  class B extends A {}
                  class Class extends B {}""", ["Class", "A"], ["Class", "A"]);
    await test("""class A {}
                  class B {}
                  class Class extends B with A {}""", ["Class", "A"],
        ["Class", "A"]);

    await test("""class A {}
                  class Class implements A {
                    factory Class() = A;
                  }""", ["A"], ["Class"]);
  }

  asyncTest(() async {
    print('--test from kernel------------------------------------------------');
    await runTests();
  });
}
