// 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 '../helpers/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 implements Class {}
                  class Class {
                    factory Class() = A;
                  }""", ["A"], ["Class"]);
  }

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