// 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. import "native_testing.dart"; import 'dart:_js_helper' show setNativeSubclassDispatchRecord; import 'dart:_interceptors' show findInterceptorForType, findConstructorForNativeSubclassType; // Test for super access from classes that extend native classes. @Native("N1") class N1 {} @Native("N2") class N2 extends N1 { N2.init(); void set text(String unused) native; String get text native; foo() native; } class AA extends N2 { AA.init() : super.init(); String? afield; afun() => 'afun:$afield'; } class BB extends AA { BB.init() : super.init(); get text => super.text; set text(value) => super.text = value; foo() => super.foo(); get afield => super.afield; set afield(value) => super.afield = value; afun() => super.afun(); } BB makeBB() native; @Creates('=Object') getBBPrototype() native; void setup() { JS('', r""" (function(){ function N2() {} N2.prototype.foo = function() { return "foo:" + this.text; }; function BB() {} BB.prototype.__proto__ = N2.prototype; self.makeBB = function(){return new BB()}; self.getBBPrototype = function(){return BB.prototype;}; })()"""); } testSuperOnNative() { BB b1 = makeBB(); BB b2 = makeBB(); var constructor = findConstructorForNativeSubclassType(BB, 'init'); Expect.isNotNull(constructor); JS('', '#(#)', constructor, b1); JS('', '#(#)', constructor, b2); b1.text = confuse('one'); b2.text = confuse('two'); print('b1.text ${confuse(b1).text}'); print('b2.text ${confuse(b2).text}'); print('b1.foo() ${confuse(b1).foo()}'); print('b2.foo() ${confuse(b2).foo()}'); Expect.equals('one', b1.text); Expect.equals('two', b2.text); Expect.equals('foo:one', b1.foo()); Expect.equals('foo:two', b2.foo()); confuse(b1).text = confuse('three'); confuse(b2).text = confuse('four'); Expect.equals('three', confuse(b1).text); Expect.equals('four', confuse(b2).text); Expect.equals('foo:three', confuse(b1).foo()); Expect.equals('foo:four', confuse(b2).foo()); } testSuperOnSubclassOfNative() { BB b1 = makeBB(); BB b2 = makeBB(); var constructor = findConstructorForNativeSubclassType(BB, 'init'); Expect.isNotNull(constructor); JS('', '#(#)', constructor, b1); JS('', '#(#)', constructor, b2); b1.afield = confuse('one'); b2.afield = confuse('two'); print('b1.afield ${confuse(b1).afield}'); print('b2.afield ${confuse(b2).afield}'); print('b1.afun() ${confuse(b1).afun()}'); print('b2.afun() ${confuse(b2).afun()}'); Expect.equals('one', b1.afield); Expect.equals('two', b2.afield); Expect.equals('afun:one', b1.afun()); Expect.equals('afun:two', b2.afun()); confuse(b1).afield = confuse('three'); confuse(b2).afield = confuse('four'); Expect.equals('three', confuse(b1).afield); Expect.equals('four', confuse(b2).afield); Expect.equals('afun:three', confuse(b1).afun()); Expect.equals('afun:four', confuse(b2).afun()); } main() { nativeTesting(); setup(); setNativeSubclassDispatchRecord(getBBPrototype(), findInterceptorForType(BB)); testSuperOnNative(); testSuperOnSubclassOfNative(); }