| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, 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 import "package:expect/expect.dart"; | |
| 6 | |
| 7 class A { | |
| 8 int value; | |
| 9 A(this.value); | |
| 10 void set(int value) { | |
| 11 this.value = value; | |
| 12 } | |
| 13 | |
| 14 int get() => value; | |
| 15 int operator [](int index) => value + index; | |
| 16 void operator []=(int index, int newValue) { | |
| 17 value += -index + newValue; | |
| 18 } | |
| 19 | |
| 20 void test(int expected) { | |
| 21 Expect.equals(expected, value); | |
| 22 } | |
| 23 | |
| 24 Function limp(int n) { | |
| 25 if (n == 0) return set; | |
| 26 return () => limp(n - 1); | |
| 27 } | |
| 28 | |
| 29 A get self => this; | |
| 30 A operator +(A other) { | |
| 31 this.value += other.value; | |
| 32 return this; | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 class Box { | |
| 37 A value; | |
| 38 Box(this.value); | |
| 39 A operator [](int pos) => value; | |
| 40 void operator []=(int pos, A a) { | |
| 41 value = a; | |
| 42 } | |
| 43 | |
| 44 A get x => value; | |
| 45 void set x(A a) { | |
| 46 value = a; | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 // Subset of grammar being tested. | |
| 51 // | |
| 52 // expression: | |
| 53 // assignableExpression assignmentOperator expression | |
| 54 // | conditionalExpression cascadeSection* | |
| 55 // ; | |
| 56 // expressionWithoutCascade: | |
| 57 // assignableExpression assignmentOperator expressionWithoutCascade | |
| 58 // | conditionalExpression | |
| 59 // ; | |
| 60 // expressionList: | |
| 61 // expression (',' expression)* | |
| 62 // ; | |
| 63 // assignableExpression: | |
| 64 // primary (arguments* assignableSelector)+ | |
| 65 // | super assignableSelector | |
| 66 // | identifier | |
| 67 // ; | |
| 68 // conditionalExpression: | |
| 69 // logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCa
scade)? | |
| 70 // ; | |
| 71 // primary: | |
| 72 // thisExpression | |
| 73 // | super assignableSelector | |
| 74 // | functionExpression | |
| 75 // | literal | |
| 76 // | identifier | |
| 77 // | newExpression | |
| 78 // | constObjectExpression | |
| 79 // | '(' expression ')' | |
| 80 // ; | |
| 81 // assignableSelector: | |
| 82 // '[' expression ']' | |
| 83 // | '.' identifier | |
| 84 // ; | |
| 85 // | |
| 86 // In words: | |
| 87 // An assignableExpression is either a variable or something ending in | |
| 88 // [expression] or .identifier. | |
| 89 | |
| 90 main() { | |
| 91 A a = new A(42); | |
| 92 A original = a; | |
| 93 A b = new A(87); | |
| 94 fa() => a; | |
| 95 Box box = new Box(a); | |
| 96 // Different expressions on the left-hand side of '..'. | |
| 97 // conditionalExpression >> postfixExpression > primary selector* | |
| 98 Expect.equals( | |
| 99 a, | |
| 100 a | |
| 101 ..set(37) | |
| 102 ..get()); | |
| 103 a.test(37); | |
| 104 Expect.equals( | |
| 105 a, | |
| 106 fa() | |
| 107 ..set(42) | |
| 108 ..get()); | |
| 109 a.test(42); | |
| 110 Expect.equals( | |
| 111 a, | |
| 112 box.x | |
| 113 ..set(37) | |
| 114 ..get()); | |
| 115 a.test(37); | |
| 116 // '..' binds to 'b + a', i.e., to the 'b' object, not to 'a'. | |
| 117 Expect.equals( | |
| 118 b, | |
| 119 b + a | |
| 120 ..test(124) | |
| 121 ..set(117) | |
| 122 ..get()); | |
| 123 b.test(117); | |
| 124 a.test(37); | |
| 125 | |
| 126 // expression :: conditionalExpression cascadeSection | |
| 127 // and conditionalExpression ends in expressionWithoutCascade. | |
| 128 // I.e., '..' binds to the entire condition expression, not to 'b'. | |
| 129 (a.value == 37) ? a : b | |
| 130 ..set(42); | |
| 131 a.test(42); | |
| 132 | |
| 133 // This binds .. to 'a', not 'c=a', and performs assignment after reading | |
| 134 // c.get(). | |
| 135 A c = new A(21); | |
| 136 c = a..set(c.get()); // FAILING. | |
| 137 Expect.equals(a, c); | |
| 138 Expect.equals(original, a); | |
| 139 a.test(21); // Fails as 42 if above is parsed as (c = a)..set(c.get()). | |
| 140 | |
| 141 // Should be parsed as (box..x = (c = a))..x.test(21). | |
| 142 c = null; | |
| 143 box | |
| 144 ..x = c = a | |
| 145 ..x.test(21); | |
| 146 c.test(21); | |
| 147 // Other variants | |
| 148 c = null; | |
| 149 box | |
| 150 ..x = c = (a..test(21)) | |
| 151 ..x.test(21); | |
| 152 c.test(21); | |
| 153 | |
| 154 c = null; | |
| 155 box | |
| 156 ..x = (c = a..test(21)) | |
| 157 ..x.test(21); | |
| 158 c.test(21); | |
| 159 | |
| 160 // Should work the same: | |
| 161 (a..set(42))..test(42); | |
| 162 a | |
| 163 ..set(21) | |
| 164 ..test(21); | |
| 165 | |
| 166 c = null; | |
| 167 Box originalBox = box; | |
| 168 // Should parse as: | |
| 169 // box = (box..x = (a.value == 21 ? b : c)..x.test(117)); | |
| 170 box = box | |
| 171 ..x = a.value == 21 ? b : c | |
| 172 ..x.test(117); | |
| 173 Expect.equals(originalBox, box); | |
| 174 Expect.equals(box.value, b); | |
| 175 | |
| 176 // New cascades are allowed inside an expressionWithoutCascade if properly | |
| 177 // delimited. | |
| 178 box | |
| 179 ..x = (a | |
| 180 ..set(42) | |
| 181 ..test(42)) | |
| 182 ..x.test(42); | |
| 183 } | |
| OLD | NEW |