Skip to content

Commit 90faef9

Browse files
lrhnpull[bot]
authored andcommitted
Add tests for the user-definable >>> operator.
Change-Id: I485d8cae7499fd31a69f279c64c3f465241a474d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180843 Commit-Queue: Lasse R.H. Nielsen <[email protected]> Reviewed-by: Erik Ernst <[email protected]>
1 parent bb5b0ff commit 90faef9

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// SharedOptions=--enable-experiment=triple-shift
6+
7+
// Can only be declared with exactly one required positional parameter.
8+
class C2 {
9+
Object? operator >>>(arg1, arg2) => arg1;
10+
// ^
11+
// [cfe] Operator '>>>' should have exactly one parameter.
12+
// ^^^
13+
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
14+
}
15+
16+
class CO1 {
17+
Object? operator >>>([arg1]) => arg1;
18+
// ^^^^
19+
// [cfe] An operator can't have optional parameters.
20+
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
21+
}
22+
23+
class C1O1 {
24+
Object? operator >>>(arg1, [arg2]) => arg1;
25+
// ^
26+
// [cfe] Operator '>>>' should have exactly one parameter.
27+
// ^^^^
28+
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
29+
}
30+
31+
class C1N1 {
32+
Object? operator >>>(arg1, {arg2}) => arg1;
33+
// ^
34+
// [cfe] Operator '>>>' should have exactly one parameter.
35+
// ^^^^
36+
// [analyzer] COMPILE_TIME_ERROR.OPTIONAL_PARAMETER_IN_OPERATOR
37+
}
38+
39+
class C0 {
40+
Object? operator >>>() => 0;
41+
// ^
42+
// [cfe] Operator '>>>' should have exactly one parameter.
43+
// ^^^
44+
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
45+
}
46+
47+
// Operators cannot be generic.
48+
class Gen {
49+
Object? operator >>> <T>(T arg1) => arg1;
50+
// ^
51+
// [cfe] Types parameters aren't allowed when defining an operator.
52+
// ^^^
53+
// [analyzer] SYNTACTIC_ERROR.TYPE_PARAMETERS_ON_OPERATOR
54+
}
55+
56+
// Operators cannot be static.
57+
class Static {
58+
/**/ static Object? operator >>>(arg) => arg;
59+
// ^^^^^^
60+
// [cfe] Operators can't be static.
61+
// [analyzer] SYNTACTIC_ERROR.STATIC_OPERATOR
62+
}
63+
64+
main() {
65+
C0();
66+
CO1();
67+
C1O1();
68+
C1N1();
69+
C2();
70+
Gen();
71+
Static();
72+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// SharedOptions=--enable-experiment=triple-shift
6+
7+
import "package:expect/expect.dart";
8+
9+
class C {
10+
static int ctr = 0;
11+
final Object? _text;
12+
C([Object? text]) : _text = text ?? "${++ctr}";
13+
14+
// It's possible to declare a `>>>` operator.
15+
C operator >>>(arg) => C("(${++ctr}:$_text>>>$arg)");
16+
17+
// + binds more strongly than `>>`, `>>>` and `<<`.
18+
C operator +(arg) => C("(${++ctr}:$_text+$arg)");
19+
// Both `>>` and `<<` binds exactly as strongly as `>>>`.
20+
C operator >>(arg) => C("(${++ctr}:$_text>>$arg)");
21+
C operator <<(arg) => C("(${++ctr}:$_text<<$arg)");
22+
// & binds less strongly than `>>`, `>>>` and `<<`.
23+
C operator &(arg) => C("(${++ctr}:$_text&$arg)");
24+
25+
String toString() => "${_text}";
26+
}
27+
28+
class NSM {
29+
noSuchMethod(i) => i.memberName;
30+
}
31+
32+
// Valid in extensions too.
33+
extension ShiftIt<T> on T {
34+
List<T> operator >>>(int count) => List<T>.filled(count, this);
35+
}
36+
37+
main() {
38+
// It's possible to use the `>>>` operator.
39+
// Evaluation is left-to-right.
40+
Expect.equals("(3:1>>>2)", "${C() >>> C()}");
41+
42+
var c = C();
43+
Expect.equals("4", "$c");
44+
c >>>= C();
45+
Expect.equals("(6:4>>>5)", "$c");
46+
47+
// Precedence is as expected.
48+
// Different precedence than + (which binds stronger) and & (which doesn't).
49+
Expect.equals("(11:(9:7+8)>>>10)", "${C() + C() >>> C()}");
50+
Expect.equals("(16:12>>>(15:13+14))", "${C() >>> C() + C()}");
51+
Expect.equals("(23:(19:17+18)>>>(22:20+21))", "${C() + C() >>> C() + C()}");
52+
Expect.equals("(28:(26:24>>>25)&27)", "${C() >>> C() & C()}");
53+
Expect.equals("(33:29&(32:30>>>31))", "${C() & C() >>> C()}");
54+
Expect.equals("(40:(38:34&(37:35>>>36))&39)", "${C() & C() >>> C() & C()}");
55+
56+
// Same precedence as `>>` and `<<`, left associative.
57+
Expect.equals("(45:(43:41>>>42)>>44)", "${C() >>> C() >> C()}");
58+
Expect.equals("(50:(48:46>>47)>>>49)", "${C() >> C() >>> C()}");
59+
Expect.equals("(55:(53:51>>>52)<<54)", "${C() >>> C() << C()}");
60+
Expect.equals("(60:(58:56<<57)>>>59)", "${C() << C() >>> C()}");
61+
Expect.equals("(67:(65:(63:61<<62)>>>64)>>66)",
62+
"${C() << C() >>> C() >> C()}");
63+
64+
/// The `>>>` Symbol works.
65+
var literalSymbol = #>>>;
66+
var constSymbol = const Symbol(">>>");
67+
var newSymbol = new Symbol(">>>");
68+
Expect.identical(literalSymbol, constSymbol);
69+
Expect.equals(literalSymbol, newSymbol);
70+
71+
dynamic n = NSM();
72+
var nsmSymbol = n >>> 42;
73+
Expect.equals(nsmSymbol, literalSymbol);
74+
75+
var o = Object();
76+
Expect.listEquals([o, o, o, o, o], o >>> 5);
77+
}

0 commit comments

Comments
 (0)