Chromium Code Reviews| 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 |