// Copyright (c) 2018, 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 'dart:io';

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_emitter/program_builder/program_builder.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../helpers/program_lookup.dart';
import '../memory_compiler.dart';

main() {
  runTest({bool useKernel}) async {
    CompilationResult result = await runCompiler(
        entryPoint: Platform.script.resolve('data/subtype_named_args.dart'),
        options: useKernel ? [] : [Flags.useOldFrontend]);
    Expect.isTrue(result.isSuccess);
    Compiler compiler = result.compiler;
    ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
    ProgramLookup programLookup = new ProgramLookup(compiler);

    List<ClassEntity> found = <ClassEntity>[];
    for (ClassEntity element
        in Collector.getBackendTypeHelpers(closedWorld.commonElements)) {
      if (programLookup.getClass(element) != null) {
        found.add(element);
      }
    }
    Expect.isTrue(found.isEmpty, "Classes ${found} should not be emitted");
  }

  asyncTest(() async {
    print('--test from ast---------------------------------------------------');
    await runTest(useKernel: false);
    print('--test from kernel------------------------------------------------');
    await runTest(useKernel: true);
  });
}
