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

/// Test that the @MirrorsUsed annotation suppress hints and that only
/// requested elements are retained for reflection.
library dart2js.test.mirrors_used_test;

import 'package:expect/expect.dart';
import "package:async_helper/async_helper.dart";

import 'memory_compiler.dart' show
    compilerFor;

import 'package:compiler/src/apiimpl.dart' show
    Compiler;

import 'package:compiler/src/constants/values.dart' show
    ConstantValue,
    TypeConstantValue;

import 'package:compiler/src/elements/elements.dart' show
    Element,
    Elements;

import 'package:compiler/src/js_backend/js_backend.dart' show
    JavaScriptBackend;

void expectOnlyVerboseInfo(Uri uri, int begin, int end, String message, kind) {
  if (kind.name == 'verbose info') {
    print(message);
    return;
  }
  if (message.contains('methods retained for use by dart:mirrors out of')) {
    print(message);
    return;
  }
  if (kind.name == 'info') return;

  // TODO(aprelev@gmail.com): Remove once dartbug.com/13907 is fixed.
  if (message.contains("Warning: 'typedef' not allowed here")) return;

  throw '$uri:$begin:$end: $kind: $message';
}

void main() {
  Compiler compiler = compilerFor(
      MEMORY_SOURCE_FILES, diagnosticHandler: expectOnlyVerboseInfo,
      options: ['--enable-experimental-mirrors']);
  asyncTest(() => compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
    print('');
    List generatedCode =
        Elements.sortedByPosition(compiler.enqueuer.codegen.generatedCode.keys);
    for (var element in generatedCode) {
      print(element);
    }
    print('');

    // This assertion can fail for two reasons:
    // 1. Too many elements retained for reflection.
    // 2. Some code was refactored, and there are more methods.
    // Either situation could be problematic, but in situation 2, it is often
    // acceptable to increase [expectedMethodCount] a little.
    int expectedMethodCount = 431;
    Expect.isTrue(
        generatedCode.length <= expectedMethodCount,
        'Too many compiled methods: '
        '${generatedCode.length} > $expectedMethodCount');

    // The following names should be retained:
    List expectedNames = [
        'Foo', // The name of class Foo.
        r'Foo$', // The name of class Foo's constructor.
        r'get$field']; // The (getter) name of Foo.field.
    // TODO(ahe): Check for the following names, currently they are not being
    // recorded correctly, but are being emitted.
    [
        'Foo_staticMethod', // The name of Foo.staticMethod.
        r'instanceMethod$0']; // The name of Foo.instanceMethod.

    // We always include the names of some native classes.
    List<Element> nativeClasses = [
          compiler.intClass, compiler.doubleClass, compiler.numClass,
          compiler.stringClass, compiler.boolClass, compiler.nullClass,
          compiler.listClass
        ];
    JavaScriptBackend backend = compiler.backend;
    Iterable<String> nativeNames =
        nativeClasses.map(backend.namer.getNameOfClass);
    expectedNames.addAll(nativeNames);

    Set recordedNames = new Set()
        ..addAll(backend.emitter.oldEmitter.recordedMangledNames)
        ..addAll(backend.emitter.oldEmitter.mangledFieldNames.keys)
        ..addAll(backend.emitter.oldEmitter.mangledGlobalFieldNames.keys);
    Expect.setEquals(new Set.from(expectedNames), recordedNames);

    for (var library in compiler.libraryLoader.libraries) {
      library.forEachLocalMember((member) {
        if (library == compiler.mainApp && member.name == 'Foo') {
          Expect.isTrue(
              compiler.backend.isAccessibleByReflection(member), '$member');
          member.forEachLocalMember((classMember) {
            Expect.isTrue(
                compiler.backend.isAccessibleByReflection(classMember),
                '$classMember');
          });
        } else {
          Expect.isFalse(
              compiler.backend.isAccessibleByReflection(member), '$member');
        }
      });
    }

    // There should at least be one metadata constant:
    // 1. The constructed constant for 'MirrorsUsed'.
    Expect.isTrue(backend.metadataConstants.length >= 1);

    Set<ConstantValue> compiledConstants = backend.constants.compiledConstants;
    // Make sure that most of the metadata constants aren't included in the
    // generated code.
    for (var dependency in backend.metadataConstants) {
      ConstantValue constant = dependency.constant;
      Expect.isFalse(compiledConstants.contains(constant),
                     constant.toStructuredString());
    }

    // The type literal 'Foo' is both used as metadata, and as a plain value in
    // the program. Make sure that it isn't duplicated.
    int fooConstantCount = 0;
    for (ConstantValue constant in compiledConstants) {
      if (constant is TypeConstantValue &&
          '${constant.representedType}' == 'Foo') {
        fooConstantCount++;
      }
    }
    Expect.equals(
        1, fooConstantCount,
        "The type literal 'Foo' is duplicated or missing.");
  }));
}

const MEMORY_SOURCE_FILES = const <String, String> {
  'main.dart': """
// The repeated constant value for symbols and targets used to crash dart2js in
// host-checked mode, and could potentially lead to other problems.
@MirrorsUsed(symbols: 'Foo', targets: 'Foo', override: '*')
import 'dart:mirrors';

import 'library.dart';

class Foo {
  int field;
  instanceMethod() {}
  static staticMethod() {}
}

unusedFunction() {
}

main() {
  useReflect(Foo);
}
""",
  'library.dart': """
library lib;

import 'dart:mirrors';

useReflect(type) {
  print(new Symbol('Foo'));
  print(MirrorSystem.getName(reflectClass(type).owner.qualifiedName));
}
""",
};
