// TODO(multitest): This was automatically migrated from a multitest and may // contain strange or dead code. // 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. // Verify semantics of the ??= operator, including order of operations, by // keeping track of the operations performed. import "package:expect/expect.dart"; import "assignment_helper.dart" as h; bad() { Expect.fail('Should not be executed'); } var xGetValue = null; get x { h.operations.add('x'); var tmp = xGetValue; xGetValue = null; return tmp; } void set x(value) { h.operations.add('x=$value'); } var yGetValue = null; get y { h.operations.add('y'); var tmp = yGetValue; yGetValue = null; return tmp; } void set y(value) { h.operations.add('y=$value'); } var zGetValue = null; get z { h.operations.add('z'); var tmp = zGetValue; zGetValue = null; return tmp; } void set z(value) { h.operations.add('z=$value'); } var fValue = null; f() { h.operations.add('f()'); var tmp = fValue; fValue = null; return tmp; } void check(expectedValue, f(), expectedOperations) { Expect.equals(expectedValue, f()); Expect.listEquals(expectedOperations, h.operations); h.operations = []; } class C { final String s; C(this.s); @override String toString() => s; static var xGetValue = null; static get x { h.operations.add('C.x'); var tmp = xGetValue; xGetValue = null; return tmp; } static void set x(value) { h.operations.add('C.x=$value'); } var vGetValue = null; get v { h.operations.add('$s.v'); var tmp = vGetValue; vGetValue = null; return tmp; } void set v(value) { h.operations.add('$s.v=$value'); } var indexGetValue = null; operator [](index) { h.operations.add('$s[$index]'); var tmp = indexGetValue; indexGetValue = null; return tmp; } void operator []=(index, value) { h.operations.add('$s[$index]=$value'); } final finalOne = 1; final finalNull = null; void instanceTest() { // v ??= e is equivalent to ((x) => x == null ? v = e : x)(v) yGetValue = 1; } } class D extends C { D(String s) : super(s); get v => bad(); void set v(value) { bad(); } void derivedInstanceTest() { // super.v ??= e is equivalent to // ((x) => x == null ? super.v = e : x)(super.v) } } main() { // Make sure the "none" test fails if "??=" is not implemented. This makes // status files easier to maintain. var _; _ ??= null; new C('c').instanceTest(); new D('d').derivedInstanceTest(); // v ??= e is equivalent to ((x) => x == null ? v = e : x)(v) // C.v ??= e is equivalent to ((x) => x == null ? C.v = e : x)(C.v) // e1.v ??= e2 is equivalent to // ((x) => ((y) => y == null ? x.v = e2 : y)(x.v))(e1) // e1[e2] ??= e3 is equivalent to // ((a, i) => ((x) => x == null ? a[i] = e3 : x)(a[i]))(e1, e2) // e1?.v ??= e2 is equivalent to ((x) => x == null ? null : x.v ??= e2)(e1). // C?.v ??= e2 is equivalent to C.v ??= e2. }