// Copyright (c) 2012, 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:uri";

import 'compiler_helper.dart';
import 'parser_helper.dart';

import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dart';
import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart';

void checkAnnotation(String name, String declaration,
                     {bool isTopLevelOnly: false}) {
  var source;

  // Ensure that a compile-time constant can be resolved from an
  // annotation.
  source = """const native = 'xyz';
              @native
              $declaration
              main() {}""";

  compileAndCheck(source, name, (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(1, length(element.metadata));
    MetadataAnnotation annotation = element.metadata.head;
    annotation.ensureResolved(compiler);
    Constant value = annotation.value;
    Expect.stringEquals('xyz', value.value.slowToString());
  });

  // Ensure that each repeated annotation has a unique instance of
  // [MetadataAnnotation].
  source = """const native = 'xyz';
              @native @native
              $declaration
              main() {}""";

  compileAndCheck(source, name, (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(2, length(element.metadata));
    MetadataAnnotation annotation1 = element.metadata.head;
    MetadataAnnotation annotation2 = element.metadata.tail.head;
    annotation1.ensureResolved(compiler);
    annotation2.ensureResolved(compiler);
    Expect.isFalse(identical(annotation1, annotation2),
                   'expected unique instances');
    Expect.notEquals(annotation1, annotation2, 'expected unequal instances');
    Constant value1 = annotation1.value;
    Constant value2 = annotation2.value;
    Expect.identical(value1, value2, 'expected same compile-time constant');
    Expect.stringEquals('xyz', value1.value.slowToString());
    Expect.stringEquals('xyz', value2.value.slowToString());
  });

  if (isTopLevelOnly) return;

  // Ensure that a compile-time constant can be resolved from an
  // annotation.
  source = """const native = 'xyz';
              class Foo {
                @native
                $declaration
              }
              main() {}""";

  compileAndCheck(source, 'Foo', (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(0, length(element.metadata));
    element.ensureResolved(compiler);
    Expect.equals(0, length(element.metadata));
    element = element.lookupLocalMember(buildSourceString(name));
    Expect.equals(1, length(element.metadata));
    MetadataAnnotation annotation = element.metadata.head;
    annotation.ensureResolved(compiler);
    Constant value = annotation.value;
    Expect.stringEquals('xyz', value.value.slowToString());
  });

  // Ensure that each repeated annotation has a unique instance of
  // [MetadataAnnotation].
  source = """const native = 'xyz';
              class Foo {
                @native @native
                $declaration
              }
              main() {}""";

  compileAndCheck(source, 'Foo', (compiler, element) {
    compiler.enqueuer.resolution.queueIsClosed = false;
    Expect.equals(0, length(element.metadata));
    element.ensureResolved(compiler);
    Expect.equals(0, length(element.metadata));
    element = element.lookupLocalMember(buildSourceString(name));
    Expect.equals(2, length(element.metadata));
    MetadataAnnotation annotation1 = element.metadata.head;
    MetadataAnnotation annotation2 = element.metadata.tail.head;
    annotation1.ensureResolved(compiler);
    annotation2.ensureResolved(compiler);
    Expect.isFalse(identical(annotation1, annotation2),
                   'expected unique instances');
    Expect.notEquals(annotation1, annotation2, 'expected unequal instances');
    Constant value1 = annotation1.value;
    Constant value2 = annotation2.value;
    Expect.identical(value1, value2, 'expected same compile-time constant');
    Expect.stringEquals('xyz', value1.value.slowToString());
    Expect.stringEquals('xyz', value2.value.slowToString());
  });
}

void testClassMetadata() {
  checkAnnotation('Foo', 'class Foo {}', isTopLevelOnly: true);
}

void testTopLevelMethodMetadata() {
  checkAnnotation('foo', 'foo() {}');
}

void testTopLevelFieldMetadata() {
  checkAnnotation('foo', 'var foo;');
}

void main() {
  testClassMetadata();
  testTopLevelMethodMetadata();
  testTopLevelFieldMetadata();
}
