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

// A native method prevents other members from having that name, including
// fields.  However, native fields keep their name.  The implication: a getter
// for the field must be based on the field's name, not the field's jsname.

import 'native_testing.dart';

abstract class I {
  int key;
}

@Native("A")
class A implements I {
  int key; //  jsname is 'key'
  int getKey() => key;
}

class B implements I {
  int key; //  jsname is not 'key'
  B([this.key = 222]);
  int getKey() => key;
}

@Native("X")
class X {
  @JSName('key')
  int native_key_method() native;
  // This should cause B.key to be renamed, but not A.key.
  @JSName('key')
  int key() native;
}

A makeA() native;
X makeX() native;

void setup() {
  JS('', r"""
(function(){
  // This code is inside 'setup' and so not accessible from the global scope.
  function A(){ this.key = 111; }
  A.prototype.getKey = function(){return this.key;};

  function X(){}
  X.prototype.key = function(){return 666;};

  makeA = function(){return new A()};
  makeX = function(){return new X()};

  self.nativeConstructor(A);
  self.nativeConstructor(X);
})()""");
}

testDynamic() {
  var a = confuse(makeA());
  var b = confuse(new B());
  var x = confuse(makeX());

  Expect.equals(111, a.key);
  Expect.equals(222, b.key);
  Expect.equals(111, a.getKey());
  Expect.equals(222, b.getKey());

  Expect.equals(666, x.native_key_method());
  Expect.equals(666, x.key());
  var fn = x.key;
  Expect.equals(666, fn());
}

testPartial() {
  var things = [makeA(), new B(), makeX()];
  I a = things[0];
  I b = things[1];

  // All subtypes of I have a field 'key'. The compiler might be tempted to
  // generate a direct property access, but that will fail since one of the
  // fields is renamed.  A getter call is required here.
  Expect.equals(111, a.key);
  Expect.equals(222, b.key);
}

testTyped() {
  A a = makeA();
  B b = new B();
  X x = makeX();

  Expect.equals(666, x.native_key_method());
  Expect.equals(111, a.key);
  Expect.equals(222, b.key);
  Expect.equals(111, a.getKey());
  Expect.equals(222, b.getKey());
}

main() {
  nativeTesting();
  setup();

  testTyped();
  testPartial();
  testDynamic();
}
