|
| 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