OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2017, 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 // Dart test for type checks involving the void type. | |
6 | |
7 void use(dynamic x) { } | |
8 | |
9 void testVoidParam(void x) { | |
10 x; /// param_stmt: ok | |
11 true ? x : x; /// param_conditional: ok | |
eernst
2017/07/10 16:05:33
We decided at a language meeting long ago that the
| |
12 for (x; false; x) {} /// param_for: ok | |
13 use(x); /// param_argument: error | |
14 use(x as Object); /// param_as: error? | |
eernst
2017/07/10 16:05:32
It was my understanding that we had agreed to allo
| |
15 void y = x; /// param_void_init: error | |
16 dynamic y = x; /// param_dynamic_init: error | |
17 x is Object; /// param_is: error | |
eernst
2017/07/10 16:05:33
In the informal spec this is allowed, but as I not
| |
18 throw x; /// param_throw: error | |
19 [x]; /// param_literal_list_init: error | |
20 var m1 = {4: x}; /// param_literal_map_value_init: error | |
21 var m2 = {x : 4}; /// param_literal_map_key_init: error | |
22 Map<dynamic, dynamic> m3 = {4: x}; /// param_literal_map_value_init2: error | |
23 Map<dynamic, dynamic> m4 = {x : 4}; /// param_literal_map_key_init2: error | |
24 x ?? 499; /// param_null_equals2: error | |
25 null ?? x; /// param_null_equals2: error | |
26 return x; /// param_return: error | |
27 while (x) {}; /// param_while: error | |
28 do {} while (x); /// param_do_while: error | |
29 for (var v in x) {} /// param_for_in: error | |
30 for (x in [1, 2]) {} /// param_for_in2: ok | |
31 x += 1; /// param_plus_eq: error | |
32 x.toString(); /// param_toString: error | |
33 x?.toString(); /// param_null_dot: error | |
34 x..toString(); /// param_cascade: error | |
35 } | |
36 | |
37 void testVoidCall(void f()) { | |
38 f(); /// call_stmt: ok | |
39 true ? f() : f(); /// call_conditional: ok | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 11.
| |
40 for (f(); false; f()) {} /// call_for: ok | |
41 use(f()); /// call_argument: error | |
42 use(f() as Object); /// call_as: error? | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 14.
| |
43 void y = f(); /// call_void_init: error | |
44 dynamic y = f(); /// call_dynamic_init: error | |
45 f() is Object; /// call_is: error | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 17.
| |
46 throw f(); /// call_throw: error | |
47 [f()]; /// call_literal_list_init: error | |
48 var m1 = {4: f() }; /// call_literal_map_value_init: error | |
49 var m2 = { f(): 4}; /// call_literal_map_key_init: error | |
50 Map<dynamic, dynamic> m3 = {4: f() }; /// call_literal_map_value_init2: error | |
51 Map<dynamic, dynamic> m4 = { f(): 4}; /// call_literal_map_key_init2: error | |
52 f() ?? 499; /// call_null_equals2: error | |
53 null ?? f(); /// call_null_equals2: error | |
54 return f(); /// call_return: error | |
55 while (f()) {}; /// call_while: error | |
56 do {} while (f()); /// call_do_while: error | |
57 for (var v in f()) {} /// call_for_in: error | |
58 f().toString(); /// call_toString: error | |
59 f()?.toString(); /// call_null_dot: error | |
60 f()..toString(); /// call_cascade: error | |
61 } | |
62 | |
63 void testVoidLocal() { | |
64 void x; | |
65 x = 42; /// local_assign: ok; | |
66 x; /// local_stmt: ok | |
67 true ? x : x; /// local_conditional: ok | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 11.
| |
68 for (x; false; x) {} /// local_for: ok | |
69 use(x); /// local_argument: error | |
70 use(x as Object); /// local_as: error? | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 14.
| |
71 void y = x; /// local_void_init: error | |
72 dynamic y = x; /// local_dynamic_init: error | |
73 x is Object; /// local_is: error | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 17.
| |
74 throw x; /// local_throw: error | |
75 [x]; /// local_literal_list_init: error | |
76 var m1 = {4: x}; /// local_literal_map_value_init: error | |
77 var m2 = {x : 4}; /// local_literal_map_key_init: error | |
78 Map<dynamic, dynamic> m3 = {4: x}; /// local_literal_map_value_init2: error | |
79 Map<dynamic, dynamic> m4 = {x : 4}; /// local_literal_map_key_init2: error | |
80 x ?? 499; /// local_null_equals2: error | |
81 null ?? x; /// local_null_equals2: error | |
82 return x; /// local_return: error | |
83 while (x) {}; /// local_while: error | |
84 do {} while (x); /// local_do_while: error | |
85 for (var v in x) {} /// local_for_in: error | |
86 for (x in [1, 2]) {} /// local_for_in2: ok | |
87 x += 1; /// local_plus_eq: error | |
88 x.toString(); /// local_toString: error | |
89 x?.toString(); /// local_null_dot: error | |
90 x..toString(); /// local_cascade: error | |
91 } | |
92 | |
93 void testVoidFinalLocal() { | |
94 final void x; | |
95 x = 42; /// final_local_assign: error; | |
96 x; /// final_local_stmt: ok | |
97 true ? x : x; /// final_local_conditional: ok | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 11.
| |
98 for (x; false; x) {} /// final_local_for: ok | |
99 use(x); /// final_local_argument: error | |
100 use(x as Object); /// final_local_as: error? | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 14.
| |
101 void y = x; /// final_local_void_init: error | |
102 dynamic y = x; /// final_local_dynamic_init: error | |
103 x is Object; /// final_local_is: error | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 17.
| |
104 throw x; /// final_local_throw: error | |
105 [x]; /// final_local_literal_list_init: error | |
106 var m1 = {4: x}; /// final_local_literal_map_value_init: error | |
107 var m2 = {x : 4}; /// final_local_literal_map_key_init: error | |
108 Map<dynamic, dynamic> m3 = {4: x}; /// final_local_literal_map_value_init2: e rror | |
109 Map<dynamic, dynamic> m4 = {x : 4}; /// final_local_literal_map_key_init2: er ror | |
110 x ?? 499; /// final_local_null_equals2: error | |
111 null ?? x; /// final_local_null_equals2: error | |
112 return x; /// final_local_return: error | |
113 while (x) {}; /// final_local_while: error | |
114 do {} while (x); /// final_local_do_while: error | |
115 for (var v in x) {} /// final_local_for_in: error | |
116 for (x in [1, 2]) {} /// final_local_for_in2: ok | |
eernst
2017/07/10 16:05:33
Why would it be OK to assign to a final local, no
| |
117 x += 1; /// final_local_plus_eq: error | |
118 x.toString(); /// final_local_toString: error | |
119 x?.toString(); /// final_local_null_dot: error | |
120 x..toString(); /// final_local_cascade: error | |
121 } | |
122 | |
123 void global; | |
124 void testVoidGlobal() { | |
125 global; /// global_stmt: ok | |
126 true ? global : global; /// global_conditional: ok | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 11.
| |
127 for (global; false; global) {} /// global_for: ok | |
128 use(global); /// global_argument: error | |
129 use(global as Object); /// global_as: error? | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 14.
| |
130 void y = global; /// global_void_init: error | |
131 dynamic y = global; /// global_dynamic_init: error | |
132 global is Object; /// global_is: error | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 17.
| |
133 throw global; /// global_throw: error | |
134 [global]; /// global_literal_list_init: error | |
135 var m1 = {4: global }; /// global_literal_map_value_init: error | |
136 var m2 = { global: 4}; /// global_literal_map_key_init: error | |
137 Map<dynamic, dynamic> m3 = {4: global }; /// global_literal_map_value_init2: error | |
138 Map<dynamic, dynamic> m4 = { global: 4}; /// global_literal_map_key_init2: er ror | |
139 null ?? global; /// global_null_equals2: error | |
140 global ?? 499; /// global_null_equals2: error | |
141 return global; /// global_return: error | |
142 while (global) {}; /// global_while: error | |
143 do {} while (global); /// global_do_while: error | |
144 for (var v in global) {} /// global_for_in: error | |
145 for (global in [1, 2]) {} /// global_for_in2: ok | |
146 global += 1; /// global_plus_eq: error | |
147 global.toString(); /// global_toString: error | |
148 global?.toString(); /// global_null_dot: error | |
149 global..toString(); /// global_cascade: error | |
150 } | |
151 | |
152 void testVoidConditional() { | |
153 void x; | |
154 (true ? x : x); /// conditional_parens: error | |
Leaf
2017/02/23 21:30:52
Seems odd to me. As far as I can find a unifying
eernst
2017/07/10 16:05:30
The informal spec allows `(e)` even for void `e`,
| |
155 true ? x : x; /// conditional_stmt: ok | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 11.
| |
156 true ? true ? x : x : true ? x : x; /// conditional_conditional: ok | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 11.
| |
157 for (true ? x : x; false; true ? x : x) {} /// conditional_for: ok | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 11.
| |
158 use(true ? x : x); /// conditional_argument: error | |
159 void y = true ? x : x; /// conditional_void_init: error | |
160 dynamic y = true ? x : x; /// conditional_dynamic_init: error | |
161 throw true ? x : x; /// conditional_throw: error | |
162 [true ? x : x]; /// conditional_literal_list_init: error | |
163 var m1 = {4: true ? x : x}; /// conditional_literal_map_value_init: error | |
164 Map<dynamic, dynamic> m3 = {4: true ? x : x}; /// conditional_literal_map_val ue_init2: error | |
165 null ?? true ? x : x; /// conditional_null_equals2: error | |
166 return true ? x : x; /// conditional_return: error | |
167 while (true ? x : x) {}; /// conditional_while: error | |
168 do {} while (true ? x : x); /// conditional_do_while: error | |
169 for (var v in true ? x : x) {} /// conditional_for_in: error | |
170 | |
171 (true ? 499 : x); /// conditional2_parens: error | |
172 true ? 499 : x; /// conditional2_stmt: ok | |
173 true ? true ? 499 : x : true ? 499 : x; /// conditional2_conditional: ok | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 11.
| |
174 for (true ? 499 : x; false; true ? 499 : x) {} /// conditional2_for: ok | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 11.
| |
175 use(true ? 499 : x); /// conditional2_argument: error | |
176 void y = true ? 499 : x; /// conditional2_void_init: error | |
177 dynamic y = true ? 499 : x; /// conditional2_dynamic_init: error | |
178 throw true ? 499 : x; /// conditional2_throw: error | |
179 [true ? 499 : x]; /// conditional2_literal_list_init: error | |
180 var m1 = {4: true ? 499 : x}; /// conditional2_literal_map_value_init: error | |
181 Map<dynamic, dynamic> m3 = {4: true ? 499 : x}; /// conditional2_literal_map_ value_init2: error | |
182 null ?? true ? 499 : x; /// conditional2_null_equals2: error | |
183 return true ? 499 : x; /// conditional2_return: error | |
184 while (true ? 499 : x) {}; /// conditional2while: error | |
185 do {} while (true ? 499 : x); /// conditional2do_while: error | |
186 for (var v in true ? 499 : x) {} /// conditional2for_in: error | |
187 | |
188 (true ? x : 499); /// conditional3_parens: error | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 11.
| |
189 true ? x : 499; /// conditional3_stmt: ok | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 11.
| |
190 true ? true ? x : 499 : true ? x : 499; /// conditional3_conditional: ok | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 11.
| |
191 for (true ? x : 499; false; true ? x : 499) {} /// conditional3_for: ok | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 11.
| |
192 use(true ? x : 499); /// conditional3_argument: error | |
193 void y = true ? x : 499; /// conditional3_void_init: error | |
194 dynamic y = true ? x : 499; /// conditional3_dynamic_init: error | |
195 throw true ? x : 499; /// conditional3_throw: error | |
196 [true ? x : 499]; /// conditional3_literal_list_init: error | |
197 var m1 = {4: true ? x : 499 }; /// conditional3_literal_map_value_init: erro r | |
198 Map<dynamic, dynamic> m3 = {4: true ? x : 499 }; /// conditional3_literal_map _value_init2: error | |
199 null ?? true ? x : 499; /// conditional3_null_equals2: error | |
200 return true ? x : 499; /// conditional3_return: error | |
201 while (true ? x : 499) {}; /// conditional_while: error | |
202 do {} while (true ? x : 499); /// conditional_do_while: error | |
203 for (var v in true ? x : 499) {} /// conditional_for_in: error | |
204 } | |
205 | |
206 | |
207 class A<T> { | |
208 T x; | |
209 | |
210 void foo() {} | |
211 } | |
212 | |
213 class B implements A<void> { | |
Leaf
2017/02/23 21:30:52
Consider adding the contra-variant parameter case
| |
214 void x; | |
215 | |
216 int foo() => 499; | |
217 } | |
218 | |
219 class C implements A<void> { | |
Leaf
2017/02/23 21:30:52
Is it deliberate that there is an error here (unim
| |
220 void get x => null; | |
221 set x(void y) {}; | |
222 } | |
223 | |
224 | |
225 void testInstanceField() { | |
226 A<void> a = new A<void>(); | |
227 a.x = 499; /// field_assign: ok | |
228 a.x; /// instance_stmt: ok | |
229 true ? a.x : a.x; /// instance_conditional: ok | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 11.
| |
230 for (a.x; false; a.x) {} /// instance_for: ok | |
231 use(a.x); /// instance_argument: error | |
232 use(a.x as Object); /// instance_as: error? | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 14.
| |
233 void y = a.x; /// instance_void_init: error | |
234 dynamic y = a.x; /// instance_dynamic_init: error | |
235 a.x is Object; /// instance_is: error | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 17.
| |
236 throw a.x; /// instance_throw: error | |
237 [a.x]; /// instance_literal_list_init: error | |
238 var m1 = {4: a.x}; /// instance_literal_map_value_init: error | |
239 var m2 = { a.x : 4}; /// instance_literal_map_key_init: error | |
240 Map<dynamic, dynamic> m3 = {4: a.x}; /// instance_literal_map_value_init2: er ror | |
241 Map<dynamic, dynamic> m4 = { a.x : 4}; /// instance_literal_map_key_init2: er ror | |
242 null ?? a.x; /// instance_null_equals2: error | |
243 a.x ?? 499; /// instance_null_equals2: error | |
244 return a.x; /// instance_return: error | |
245 while (a.x) {}; /// instance_while: error | |
246 do {} while (a.x); /// instance_do_while: error | |
247 for (var v in a.x) {} /// instance_for_in: error | |
248 for (a.x in [1, 2]) {} /// instance_for_in2: ok | |
249 a.x += 1; /// instance_plus_eq: error | |
250 a.x.toString(); /// instance_toString: error | |
251 a.x?.toString(); /// instance_null_dot: error | |
252 a.x..toString(); /// instance_cascade: error | |
253 | |
254 B b = new B(); | |
255 b.x = 42; /// field_assign2: ok | |
256 b.x; /// instance2_stmt: ok | |
257 true ? b.x : b.x; /// instance2_conditional: ok | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 11.
| |
258 for (b.x; false; b.x) {} /// instance2_for: ok | |
259 use(b.x); /// instance2_argument: error | |
260 use(b.x as Object); /// instance2_as: error? | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 14.
| |
261 void y = b.x; /// instance2_void_init: error | |
262 dynamic y = b.x; /// instance2_dynamic_init: error | |
263 b.x is Object; /// instance2_is: error | |
eernst
2017/07/10 16:05:30
Should get the same treatment as line 17.
| |
264 throw b.x; /// instance2_throw: error | |
265 [b.x]; /// instance2_literal_list_init: error | |
266 var m1 = {4: b.x}; /// instance2_literal_map_value_init: error | |
267 var m2 = { b.x : 4}; /// instance2_literal_map_key_init: error | |
268 Map<dynamic, dynamic> m3 = {4: b.x}; /// instance2_literal_map_value_init2: e rror | |
269 Map<dynamic, dynamic> m4 = { b.x : 4}; /// instance2_literal_map_key_init2: e rror | |
270 null ?? b.x; /// instance2_null_equals2: error | |
271 b.x ?? 499; /// instance2_null_equals2: error | |
272 return b.x; /// instance2_return: error | |
273 while (b.x) {}; /// instance2_while: error | |
274 do {} while (b.x); /// instance2_do_while: error | |
275 for (var v in b.x) {} /// instance2_for_in: error | |
276 for (b.x in [1, 2]) {} /// instance2_for_in2: ok | |
277 b.x += 1; /// instance2_plus_eq: error | |
278 b.x.toString(); /// instance2_toString: error | |
279 b.x?.toString(); /// instance2_null_dot: error | |
280 b.x..toString(); /// instance2_cascade: error | |
281 | |
282 C c = new C(); | |
283 c.x = 32; /// setter_assign: ok | |
284 c.x; /// instance3_stmt: ok | |
285 true ? c.x : c.x; /// instance3_conditional: ok | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 11.
| |
286 for (c.x; false; c.x) {} /// instance3_for: ok | |
287 use(c.x); /// instance3_argument: error | |
288 use(c.x as Object); /// instance3_as: error? | |
eernst
2017/07/10 16:05:34
Should get the same treatment as line 14.
| |
289 void y = c.x; /// instance3_void_init: error | |
290 dynamic y = c.x; /// instance3_dynamic_init: error | |
291 c.x is Object; /// instance3_is: error | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 17.
| |
292 throw c.x; /// instance3_throw: error | |
293 [c.x]; /// instance3_literal_list_init: error | |
294 var m1 = {4: c.x}; /// instance3_literal_map_value_init: error | |
295 var m2 = { c.x : 4}; /// instance3_literal_map_key_init: error | |
296 Map<dynamic, dynamic> m3 = {4: c.x}; /// instance3_literal_map_value_init2: e rror | |
297 Map<dynamic, dynamic> m4 = { c.x : 4}; /// instance3_literal_map_key_init2: e rror | |
298 null ?? c.x; /// instance3_null_equals2: error | |
299 c.x ?? 499; /// instance3_null_equals2: error | |
300 return c.x; /// instance3_return: error | |
301 while (c.x) {}; /// instance3_while: error | |
302 do {} while (c.x); /// instance3_do_while: error | |
303 for (var v in c.x) {} /// instance3_for_in: error | |
304 for (c.x in [1, 2]) {} /// instance3_for_in2: ok | |
305 c.x += 1; /// instance3_plus_eq: error | |
306 c.x.toString(); /// instance3_toString: error | |
307 c.x?.toString(); /// instance3_null_dot: error | |
308 c.x..toString(); /// instance3_cascade: error | |
309 } | |
310 | |
311 void testParenthesized() { | |
312 void x; | |
313 (x); /// paren_stmt: ok | |
314 true ? (x) : (x); /// paren_conditional: ok | |
eernst
2017/07/10 16:05:33
Should get the same treatment as line 11.
| |
315 for ((x); false; (x)) {} /// paren_for: ok | |
316 use((x)); /// paren_argument: error | |
317 use((x) as Object); /// paren_as: error? | |
eernst
2017/07/10 16:05:32
Should get the same treatment as line 14.
| |
318 void y = (x); /// paren_void_init: error | |
319 dynamic y = (x); /// paren_dynamic_init: error | |
320 (x) is Object; /// paren_is: error | |
eernst
2017/07/10 16:05:31
Should get the same treatment as line 17.
| |
321 throw (x); /// paren_throw: error | |
322 [(x)]; /// paren_literal_list_init: error | |
323 var m1 = {4: (x) }; /// paren_literal_map_value_init: error | |
324 var m2 = { (x): 4}; /// paren_literal_map_key_init: error | |
325 Map<dynamic, dynamic> m3 = {4: (x) }; /// paren_literal_map_value_init2: erro r | |
326 Map<dynamic, dynamic> m4 = { (x): 4}; /// paren_literal_map_key_init2: error | |
327 (x) ?? 499; /// paren_null_equals2: error | |
328 null ?? (x); /// paren_null_equals2: error | |
329 return (x); /// paren_return: error | |
330 while ((x)) {}; /// paren_while: error | |
331 do {} while ((x)); /// paren_do_while: error | |
332 for (var v in (x)) {} /// paren_for_in: error | |
333 (x).toString(); /// paren_toString: error | |
334 (x)?.toString(); /// paren_null_dot: error | |
335 (x)..toString(); /// paren_cascade: error | |
336 } | |
337 | |
338 main() { | |
339 testVoidParam(499); | |
340 testVoidCall(() {}); | |
341 testVoidLocal(); | |
342 testVoidFinalLocal(); | |
343 testVoidConditional(); | |
344 testInstanceField(); | |
345 testParenthesized(); | |
346 } | |
OLD | NEW |