// 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.

// @dart = 2.7

import "native_testing.dart";
import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
import 'dart:_interceptors'
    show findInterceptorForType, findConstructorForNativeSubclassType;

// Test for fields with same name as native fields.  We expect N.foo to have the
// property name 'foo' and A.foo and B.foo to have non-conflicting names.

@Native("N")
class N {
  var foo;
  N.init();
}

class A extends N {
  var foo = 222;
  A.init() : super.init();
  Nfoo() => super.foo; // TODO(sra): Fix compiler assert.
}

class B extends A {
  var foo = 333;
  B.init() : super.init();
  Afoo() => super.foo;
  Bfoo() => foo;

  toString() => '[N.foo = ${Nfoo()}, A.foo = ${Afoo()}, B.foo = ${Bfoo()}]';
}

B makeB() native;

@Creates('=Object')
getBPrototype() native;

void setup() {
  JS('', r"""
(function(){
  function B() { this.foo = 111; }  // N.foo
  makeB = function(){return new B()};

  getBPrototype = function(){return B.prototype;};
})()""");
}

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

  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));

  B b = makeB();

  var constructor = findConstructorForNativeSubclassType(B, 'init');
  Expect.isNotNull(constructor);
  JS('', '#(#)', constructor, b);

  print(b);

  Expect.equals(333, confuse(b).Bfoo());
  Expect.equals(222, confuse(b).Afoo());
  Expect.equals(111, confuse(b).Nfoo());

  Expect.equals(333, b.Bfoo());
  Expect.equals(222, b.Afoo());
  Expect.equals(111, b.Nfoo());
}
