|  | // 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. | 
|  |  | 
|  | // @dart = 2.7 | 
|  |  | 
|  | // 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;}; | 
|  |  | 
|  | self.makeA = function(){return new A()}; | 
|  | self.makeX = function(){return new X()}; | 
|  |  | 
|  | self.nativeConstructor(A); | 
|  | self.nativeConstructor(X); | 
|  | })()"""); | 
|  | applyTestExtensions(['A', '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(); | 
|  | } |