// Copyright (c) 2015, 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'; // Test that compiler is cautious with optimizations on native fields. The // motivation is that DOM properties are getters and setters with arbitrary // effects. Setting CSSStyleDeclaration.borderLeft can canonicalize the value // and changes the value of CSSStyleDeclaration.border. @Native("Foo") class Foo { var a; var b; var ab; } Foo makeFoo() native; void setup() { JS('', r""" (function(){ function Foo() { this.i = 0; } Object.defineProperty(Foo.prototype, 'a', { get: function () { return (this._a || '') + ++this.i; }, set: function (v) { this._a = v.toLowerCase(); } }); Object.defineProperty(Foo.prototype, 'b', { get: function () { return this._b || ''; }, set: function (v) { this._b = v.toLowerCase(); } }); Object.defineProperty(Foo.prototype, 'ab', { get: function () { return this.a + ' ' + this.b; }, set: function (v) { var s = v.split(' '); this.a = s[0]; this.b = s[1]; } }); self.makeFoo = function() { return new Foo() }; self.nativeConstructor(Foo); })()"""); applyTestExtensions(['Foo']); } test1() { var f = makeFoo(); f.a = 'Hi'; f.b = 'There'; Expect.equals('hi1 there', f.ab); } test2() { // Test for CSE. dart2js currently does CSE loads. Is this the right choice? var f = makeFoo(); var a1 = f.a; var b1 = f.b; var a2 = f.a; Expect.equals('1', a1); if (a2 == a1) { // We did CSE. } else { Expect.equals('2', a2); } } test3() { // Must not CSE over a native field store. var f = makeFoo(); var a1 = f.a; f.ab = 'X Y'; var a2 = f.a; Expect.equals('1', a1); Expect.equals('x2', a2); } test4() { // Must not store-forward. var f = makeFoo(); f.a = 'A'; var a2 = f.a; Expect.equals('a1', a2); } main() { nativeTesting(); setup(); (test1)(); (test2)(); (test3)(); (test4)(); }