Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:03
No void_type1_test.dart?
floitsch
2017/02/22 14:44:42
Existed already.
| |
| 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 | |
| 12 for (x; false; x) {} /// param_for: ok | |
| 13 use(x); /// param_argument: error | |
| 14 use(x as Object); /// param_as: error? | |
|
eernst
2017/02/21 13:39:12
Presumably, a developer could have a situation whe
| |
| 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/02/21 13:39:12
Following the argument for allowing `x as T`, we c
| |
| 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 var z = null ?? x; /// param_null_equals2: error | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Could argue - why allow `?:` but not `??`? Since `
eernst
2017/02/21 13:39:12
I think it's an ugly hack to allow the conditional
floitsch
2017/02/22 14:44:42
Not sure. There are use-cases, but I'm not sure th
| |
| 25 var z = x ?? 499; /// param_null_equals2: error | |
|
eernst
2017/02/21 13:39:12
Here we _obviously_ want to look at the value of a
| |
| 26 return x; /// param_return: error | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Add:
while (x) ;
do {} while (x);
for (var v in
eernst
2017/02/21 13:39:12
For all those I'd prefer a compile-time error: We
floitsch
2017/02/22 14:44:42
Done.
| |
| 27 } | |
| 28 | |
| 29 void testVoidCall(void f()) { | |
| 30 f(); /// call_stmt: ok | |
| 31 true ? f() : f(); /// call_conditional: ok | |
| 32 for (f(); false; f()) {} /// call_for: ok | |
| 33 use(f()); /// call_argument: error | |
| 34 use(f() as Object); /// call_as: error? | |
|
eernst
2017/02/21 13:39:12
Same argument: Let's allow this.
| |
| 35 void y = f(); /// call_void_init: error | |
| 36 dynamic y = f(); /// call_dynamic_init: error | |
| 37 f() is Object; /// call_is: error | |
| 38 throw f(); /// call_throw: error | |
| 39 [f()]; /// call_literal_list_init: error | |
| 40 var m1 = { 4: f() }; /// call_literal_map_value_init: error | |
| 41 var m2 = { f(): 4 }; /// call_literal_map_key_init: error | |
| 42 Map<dynamic, dynamic> m3 = { 4: f() }; /// call_literal_map_value_init2: erro r | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Long line. Style guide says no spaces after '{' an
floitsch
2017/02/22 14:44:43
Done.
| |
| 43 Map<dynamic, dynamic> m4 = { f(): 4 }; /// call_literal_map_key_init2: error | |
| 44 var z = null ?? f(); /// call_null_equals2: error | |
| 45 var z = f() ?? 499; /// call_null_equals2: error | |
| 46 return f(); /// call_return: error | |
|
eernst
2017/02/21 13:39:12
I like this, but doesn't it contradict current tre
| |
| 47 } | |
| 48 | |
| 49 void testVoidLocal() { | |
| 50 void x; | |
| 51 x = 42; /// local_assign: ok; | |
| 52 x; /// local_stmt: ok | |
| 53 true ? x : x; /// local_conditional: ok | |
| 54 for (x; false; x) {} /// local_for: ok | |
| 55 use(x); /// local_argument: error | |
| 56 use(x as Object); /// local_as: error? | |
|
eernst
2017/02/21 13:39:12
I'd propose to allow this, like the others.
| |
| 57 void y = x; /// local_void_init: error | |
| 58 dynamic y = x; /// local_dynamic_init: error | |
| 59 x is Object; /// local_is: error | |
| 60 throw x; /// local_throw: error | |
| 61 [x]; /// local_literal_list_init: error | |
| 62 var m1 = { 4: x }; /// local_literal_map_value_init: error | |
| 63 var m2 = { x: 4 }; /// local_literal_map_key_init: error | |
| 64 Map<dynamic, dynamic> m3 = { 4: x }; /// local_literal_map_value_init2: error | |
| 65 Map<dynamic, dynamic> m4 = { x: 4 }; /// local_literal_map_key_init2: error | |
| 66 var z = null ?? x; /// local_null_equals2: error | |
| 67 var z = x ?? 499; /// local_null_equals2: error | |
| 68 return x; /// local_return: error | |
|
eernst
2017/02/21 13:39:12
Again, I'd support making this an error, but it sh
| |
| 69 } | |
| 70 | |
| 71 void global; | |
| 72 void testVoidGlobal() { | |
| 73 global; /// global_stmt: ok | |
| 74 true ? global : global; /// global_conditional: ok | |
| 75 for (global; false; global) {} /// global_for: ok | |
| 76 use(global); /// global_argument: error | |
| 77 use(global as Object); /// global_as: error? | |
|
eernst
2017/02/21 13:39:12
Allow, as usual.
| |
| 78 void y = global; /// global_void_init: error | |
| 79 dynamic y = global; /// global_dynamic_init: error | |
| 80 global is Object; /// global_is: error | |
| 81 throw global; /// global_throw: error | |
| 82 [global]; /// global_literal_list_init: error | |
| 83 var m1 = { 4: global }; /// global_literal_map_value_init: error | |
| 84 var m2 = { global: 4 }; /// global_literal_map_key_init: error | |
| 85 Map<dynamic, dynamic> m3 = { 4: global }; /// global_literal_map_value_init2: error | |
| 86 Map<dynamic, dynamic> m4 = { global: 4 }; /// global_literal_map_key_init2: e rror | |
| 87 var z = null ?? global; /// global_null_equals2: error | |
| 88 var z = global ?? 499; /// global_null_equals2: error | |
| 89 return global; /// global_return: error | |
| 90 } | |
| 91 | |
| 92 void testVoidConditional() { | |
| 93 void x; | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Consider a version with "final void x" too.
eernst
2017/02/21 13:39:12
That's delightfully useless: Here's a variable whe
floitsch
2017/02/22 14:44:42
Done.
| |
| 94 (true? x: x); /// conditional_parens: error | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
I think we should allow parentheses. It's always s
eernst
2017/02/21 13:39:12
I can see that, especially if we have a need for p
floitsch
2017/02/22 14:44:42
Added a paren version.
| |
| 95 true? x: x; /// conditional_stmt: ok | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Nitpick: Space before ?.
floitsch
2017/02/22 14:44:42
Done.
| |
| 96 true ? true? x: x : true? x: x; /// conditional_conditional: ok | |
| 97 for (true? x: x; false; true? x: x) {} /// conditional_for: ok | |
| 98 use(true? x: x); /// conditional_argument: error | |
| 99 void y = true? x: x; /// conditional_void_init: error | |
| 100 dynamic y = true? x: x; /// conditional_dynamic_init: error | |
| 101 throw true? x: x; /// conditional_throw: error | |
| 102 [true? x: x]; /// conditional_literal_list_init: error | |
| 103 var m1 = { 4: true? x: x }; /// conditional_literal_map_value_init: error | |
| 104 Map<dynamic, dynamic> m3 = { 4: true? x: x }; /// conditional_literal_map_val ue_init2: error | |
| 105 var z = null ?? true? x: x; /// conditional_null_equals2: error | |
| 106 return true? x: x; /// conditional_return: error | |
|
eernst
2017/02/21 13:39:12
Usual consideration: We currently allow `return g(
| |
| 107 | |
| 108 (true? 499: x); /// conditional2_parens: error | |
|
eernst
2017/02/21 13:39:12
With parens allowed, this would be ok.
| |
| 109 true? 499: x; /// conditional2_stmt: ok | |
| 110 true ? true? 499: x : true? 499: x; /// conditional2_conditional: ok | |
| 111 for (true? 499: x; false; true? 499: x) {} /// conditional2_for: ok | |
| 112 use(true? 499: x); /// conditional2_argument: error | |
| 113 void y = true? 499: x; /// conditional2_void_init: error | |
| 114 dynamic y = true? 499: x; /// conditional2_dynamic_init: error | |
| 115 throw true? 499: x; /// conditional2_throw: error | |
| 116 [true? 499: x]; /// conditional2_literal_list_init: error | |
| 117 var m1 = { 4: true? 499: x }; /// conditional2_literal_map_value_init: error | |
| 118 Map<dynamic, dynamic> m3 = { 4: true? 499: x }; /// conditional2_literal_map_ value_init2: error | |
| 119 var z = null ?? true? 499: x; /// conditional2_null_equals2: error | |
| 120 return true? 499: x; /// conditional2_return: error | |
|
eernst
2017/02/21 13:39:11
Same as line 106.
| |
| 121 | |
| 122 (true? x: 499); /// conditional3_parens: error | |
|
eernst
2017/02/21 13:39:12
OK if parens are ok.
| |
| 123 true? x: 499; /// conditional3_stmt: ok | |
| 124 true ? true? x: 499 : true? x: 499; /// conditional3_conditional: ok | |
| 125 for (true? x: 499; false; true? x: 499) {} /// conditional3_for: ok | |
| 126 use(true? x: 499); /// conditional3_argument: error | |
| 127 void y = true? x: 499; /// conditional3_void_init: error | |
| 128 dynamic y = true? x: 499; /// conditional3_dynamic_init: error | |
| 129 throw true? x: 499; /// conditional3_throw: error | |
| 130 [true? x: 499]; /// conditional3_literal_list_init: error | |
| 131 var m1 = { 4: true? x: 499 }; /// conditional3_literal_map_value_init: error | |
| 132 Map<dynamic, dynamic> m3 = { 4: true? x: 499 }; /// conditional3_literal_map_ value_init2: error | |
| 133 var z = null ?? true? x: 499; /// conditional3_null_equals2: error | |
| 134 return true? x: 499; /// conditional3_return: error | |
|
eernst
2017/02/21 13:39:12
Same as line 106.
| |
| 135 } | |
| 136 | |
| 137 | |
| 138 class A<T> { | |
| 139 T x; | |
| 140 | |
| 141 void foo() {} | |
| 142 } | |
| 143 | |
| 144 class B implements A<void> { | |
| 145 void x; | |
| 146 | |
| 147 int foo() => 499; | |
| 148 } | |
| 149 | |
| 150 class C implements A<void> { | |
| 151 void get x => null; | |
| 152 set x(void y) {}; | |
| 153 } | |
| 154 | |
| 155 | |
| 156 void testInstanceField() { | |
| 157 var a = new A<void>(); | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:04
Use A<void> instead of var, otherwise you don't ge
floitsch
2017/02/22 14:44:42
Done.
| |
| 158 a.x = 499; /// field_assign: ok | |
| 159 a.x; /// instance_stmt: ok | |
| 160 true ? a.x : a.x; /// instance_conditional: ok | |
| 161 for (a.x; false; a.x) {} /// instance_for: ok | |
| 162 use(a.x); /// instance_argument: error | |
| 163 use(a.x as Object); /// instance_as: error? | |
|
eernst
2017/02/21 13:39:12
Same as similar cases: `as` could be the tiny exce
| |
| 164 void y = a.x; /// instance_void_init: error | |
| 165 dynamic y = a.x; /// instance_dynamic_init: error | |
| 166 a.x is Object; /// instance_is: error | |
| 167 throw a.x; /// instance_throw: error | |
| 168 [a.x]; /// instance_literal_list_init: error | |
| 169 var m1 = { 4: a.x }; /// instance_literal_map_value_init: error | |
| 170 var m2 = { a.x: 4 }; /// instance_literal_map_key_init: error | |
| 171 Map<dynamic, dynamic> m3 = { 4: a.x }; /// instance_literal_map_value_init2: error | |
| 172 Map<dynamic, dynamic> m4 = { a.x: 4 }; /// instance_literal_map_key_init2: er ror | |
| 173 var z = null ?? a.x; /// instance_null_equals2: error | |
| 174 var z = a.x ?? 499; /// instance_null_equals2: error | |
| 175 return a.x; /// instance_return: error | |
| 176 | |
| 177 var b = new B(); | |
|
Lasse Reichstein Nielsen
2017/02/21 09:37:03
B b = new B();
floitsch
2017/02/22 14:44:42
Done.
| |
| 178 b.x = 42; /// field_assign2: ok | |
| 179 b.x; /// instance2_stmt: ok | |
| 180 true ? b.x : b.x; /// instance2_conditional: ok | |
| 181 for (b.x; false; b.x) {} /// instance2_for: ok | |
| 182 use(b.x); /// instance2_argument: error | |
| 183 use(b.x as Object); /// instance2_as: error? | |
|
eernst
2017/02/21 13:39:12
Like line 163.
| |
| 184 void y = b.x; /// instance2_void_init: error | |
| 185 dynamic y = b.x; /// instance2_dynamic_init: error | |
| 186 b.x is Object; /// instance2_is: error | |
| 187 throw b.x; /// instance2_throw: error | |
| 188 [b.x]; /// instance2_literal_list_init: error | |
| 189 var m1 = { 4: b.x }; /// instance2_literal_map_value_init: error | |
| 190 var m2 = { b.x: 4 }; /// instance2_literal_map_key_init: error | |
| 191 Map<dynamic, dynamic> m3 = { 4: b.x }; /// instance2_literal_map_value_init2: error | |
| 192 Map<dynamic, dynamic> m4 = { b.x: 4 }; /// instance2_literal_map_key_init2: e rror | |
| 193 var z = null ?? b.x; /// instance2_null_equals2: error | |
| 194 var z = b.x ?? 499; /// instance2_null_equals2: error | |
| 195 return b.x; /// instance2_return: error | |
|
eernst
2017/02/21 13:39:12
Like line 106.
| |
| 196 | |
| 197 var c = new C(); | |
| 198 c.x = 32; /// setter_assign: ok | |
| 199 c.x; /// instance3_stmt: ok | |
| 200 true ? c.x : c.x; /// instance3_conditional: ok | |
| 201 for (c.x; false; c.x) {} /// instance3_for: ok | |
| 202 use(c.x); /// instance3_argument: error | |
| 203 use(c.x as Object); /// instance3_as: error? | |
|
eernst
2017/02/21 13:39:12
Like line 163.
| |
| 204 void y = c.x; /// instance3_void_init: error | |
| 205 dynamic y = c.x; /// instance3_dynamic_init: error | |
| 206 c.x is Object; /// instance3_is: error | |
| 207 throw c.x; /// instance3_throw: error | |
| 208 [c.x]; /// instance3_literal_list_init: error | |
| 209 var m1 = { 4: c.x }; /// instance3_literal_map_value_init: error | |
| 210 var m2 = { c.x: 4 }; /// instance3_literal_map_key_init: error | |
| 211 Map<dynamic, dynamic> m3 = { 4: c.x }; /// instance3_literal_map_value_init2: error | |
| 212 Map<dynamic, dynamic> m4 = { c.x: 4 }; /// instance3_literal_map_key_init2: e rror | |
| 213 var z = null ?? c.x; /// instance3_null_equals2: error | |
| 214 var z = c.x ?? 499; /// instance3_null_equals2: error | |
| 215 return c.x; /// instance3_return: error | |
| 216 } | |
| 217 | |
| 218 main() { | |
| 219 testVoidParam(499); | |
| 220 testVoidCall(() {}); | |
| 221 testVoidLocal(); | |
| 222 testVoidConditional(); | |
| 223 testInstanceField(); | |
| 224 } | |
| OLD | NEW |