// 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 "package:expect/expect.dart";
import 'dart:_js_helper' show JSName;

abstract class I {
  int key;
}

class A implements I native "A" {
  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;
}

class X native "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() native """
// This code is all inside 'setup' and so not accesible 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};
""";

testDynamic() {
  var things = [makeA(), new B(), makeX()];
  var a = things[0];
  var b = things[1];
  var x = things[2];

  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() {
  setup();

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