blob: 8358a1841580586146a6466ee94da661c08e926d [file] [log] [blame]
// Copyright (c) 2019, 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.
// SharedOptions=--enable-experiment=extension-methods
// Tests interactions between getters and setters where one or both is defined
// by an extension.
import "package:expect/expect.dart";
main() {
C c = C();
// v1: C get, C set
expectGet("C.v1", c.v1);
expectSet("C.v1=1", c.v1 = Result("1"));
// v2: C get, E1 set
expectGet("C.v2", c.v2);
expectSet("E1.v2=2", c.v2 = Result("2"));
// v3: E1 get, C set
expectGet("E1.v3", c.v3);
expectSet("C.v3=3", c.v3 = Result("3"));
// v4: E1 get, E1 set
expectGet("E1.v4", c.v4);
expectSet("E1.v4=4", c.v4 = Result("4"));
// v5: E1 get, E2 set
expectGet("E1.v5", c.v5);
expectSet("E2.v5=5", c.v5 = Result("5"));
expectSet("C.v1=C.v1+1", c.v1++);
expectSet("E1.v2=C.v2+1", c.v2++);
expectSet("C.v3=E1.v3+1", c.v3++);
expectSet("E1.v4=E1.v4+1", c.v4++);
expectSet("E2.v5=E1.v5+1", c.v5++);
expectSet("C.v1=C.v1+a", c.v1 += "a");
expectSet("C.v1=C.v1-b", c.v1 -= "b");
// Cascades work.
expectSet(
"E1.v4=E2.v4+[C.v1=[E1.v2=a]]",
c
..v2 = Result("a")
..v1 = Result("[$lastSetter]")
..v4 += Result("[$lastSetter]"));
// Override used by all accesses of read/write operations
expectSet("E1.v1=E1.v1+1", E1(c).v1++);
expectSet("E1.v2=E1.v2+1", E1(c).v2++);
expectSet("E1.v3=E1.v3+1", E1(c).v3++);
// Same using `+= 1` instead of `++`.
expectSet("E1.v1=E1.v1+1", E1(c).v1 += 1);
expectSet("E1.v2=E1.v2+1", E1(c).v2 += 1);
expectSet("E1.v3=E1.v3+1", E1(c).v3 += 1);
// Same fully expanded.
expectSet("E1.v1=E1.v1+1", E1(c).v1 = E1(c).v1 + 1);
expectSet("E1.v2=E1.v2+1", E1(c).v2 = E1(c).v2 + 1);
expectSet("E1.v3=E1.v3+1", E1(c).v3 = E1(c).v3 + 1);
}
/// Expect the value of [result] to be the [expected] string
expectGet(String expected, Result result) {
Expect.equals(expected, result.value);
}
/// Expect the [lastSetter] value set by evaluating [assignment] to be
/// [expected].
expectSet(String expected, void assignment) {
Expect.equals(expected, lastSetter);
}
/// Last value passed to any of our tested setters.
String lastSetter = null;
/// A type which supports a `+` operation accepting `int`,
/// so we can test `+=` and `++`.
class Result {
final String value;
Result(this.value);
Result operator +(Object o) => Result("$value+$o");
Result operator -(Object o) => Result("$value-$o");
String toString() => value;
}
/// Target type for extensions.
///
/// Declares [v1] getter and setter, [v2] getter and [v3] setter.
class C {
Result get v1 => Result("C.v1");
void set v1(Result value) {
lastSetter = "C.v1=$value";
}
Result get v2 => Result("C.v2");
void set v3(Result value) {
lastSetter = "C.v3=$value";
}
}
/// Primary extension on [C].
///
/// Declares [v1], [v2] and [v3] getters and setters.
///
/// Declares [v4] getter and setter, and [v5] getter
/// which are supplemented by a setter from the [E2] extension.
extension E1 on C {
// Overlaps with C on both.
Result get v1 => Result("E1.v1");
void set v1(Result value) {
lastSetter = "E1.v1=$value";
}
// Overlaps with C on getter.
Result get v2 => Result("E1.v2");
void set v2(Result value) {
lastSetter = "E1.v2=$value";
}
// Overlaps with C on setter.
Result get v3 => Result("E1.v3");
void set v3(Result value) {
lastSetter = "E1.v3=$value";
}
// Overlaps with nothing.
Result get v4 => Result("E1.v4");
void set v4(Result value) {
lastSetter = "E1.v4=$value";
}
// Combines with E2 setter.
Result get v5 => Result("E1.v5");
}
/// A different extension than [E1] on [C].
///
/// Declares [v5] setter.
/// Together with [E1], this defined both getter and setter.
extension E2 on C {
void set v5(Result value) {
lastSetter = "E2.v5=$value";
}
}