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 |