Index: tests/language/void_type2_test.dart |
diff --git a/tests/language/void_type2_test.dart b/tests/language/void_type2_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e66515b8cd921bd142036f2c28b9c6f836ca1e74 |
--- /dev/null |
+++ b/tests/language/void_type2_test.dart |
@@ -0,0 +1,224 @@ |
+// 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.
|
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+// Dart test for type checks involving the void type. |
+ |
+void use(dynamic x) { } |
+ |
+void testVoidParam(void x) { |
+ x; /// param_stmt: ok |
+ true ? x : x; /// param_conditional: ok |
+ for (x; false; x) {} /// param_for: ok |
+ use(x); /// param_argument: error |
+ use(x as Object); /// param_as: error? |
eernst
2017/02/21 13:39:12
Presumably, a developer could have a situation whe
|
+ void y = x; /// param_void_init: error |
+ dynamic y = x; /// param_dynamic_init: error |
+ x is Object; /// param_is: error |
eernst
2017/02/21 13:39:12
Following the argument for allowing `x as T`, we c
|
+ throw x; /// param_throw: error |
+ [x]; /// param_literal_list_init: error |
+ var m1 = { 4: x }; /// param_literal_map_value_init: error |
+ var m2 = { x: 4 }; /// param_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: x }; /// param_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { x: 4 }; /// param_literal_map_key_init2: error |
+ 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
|
+ 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
|
+ 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.
|
+} |
+ |
+void testVoidCall(void f()) { |
+ f(); /// call_stmt: ok |
+ true ? f() : f(); /// call_conditional: ok |
+ for (f(); false; f()) {} /// call_for: ok |
+ use(f()); /// call_argument: error |
+ use(f() as Object); /// call_as: error? |
eernst
2017/02/21 13:39:12
Same argument: Let's allow this.
|
+ void y = f(); /// call_void_init: error |
+ dynamic y = f(); /// call_dynamic_init: error |
+ f() is Object; /// call_is: error |
+ throw f(); /// call_throw: error |
+ [f()]; /// call_literal_list_init: error |
+ var m1 = { 4: f() }; /// call_literal_map_value_init: error |
+ var m2 = { f(): 4 }; /// call_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: f() }; /// call_literal_map_value_init2: error |
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.
|
+ Map<dynamic, dynamic> m4 = { f(): 4 }; /// call_literal_map_key_init2: error |
+ var z = null ?? f(); /// call_null_equals2: error |
+ var z = f() ?? 499; /// call_null_equals2: error |
+ return f(); /// call_return: error |
eernst
2017/02/21 13:39:12
I like this, but doesn't it contradict current tre
|
+} |
+ |
+void testVoidLocal() { |
+ void x; |
+ x = 42; /// local_assign: ok; |
+ x; /// local_stmt: ok |
+ true ? x : x; /// local_conditional: ok |
+ for (x; false; x) {} /// local_for: ok |
+ use(x); /// local_argument: error |
+ use(x as Object); /// local_as: error? |
eernst
2017/02/21 13:39:12
I'd propose to allow this, like the others.
|
+ void y = x; /// local_void_init: error |
+ dynamic y = x; /// local_dynamic_init: error |
+ x is Object; /// local_is: error |
+ throw x; /// local_throw: error |
+ [x]; /// local_literal_list_init: error |
+ var m1 = { 4: x }; /// local_literal_map_value_init: error |
+ var m2 = { x: 4 }; /// local_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: x }; /// local_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { x: 4 }; /// local_literal_map_key_init2: error |
+ var z = null ?? x; /// local_null_equals2: error |
+ var z = x ?? 499; /// local_null_equals2: error |
+ return x; /// local_return: error |
eernst
2017/02/21 13:39:12
Again, I'd support making this an error, but it sh
|
+} |
+ |
+void global; |
+void testVoidGlobal() { |
+ global; /// global_stmt: ok |
+ true ? global : global; /// global_conditional: ok |
+ for (global; false; global) {} /// global_for: ok |
+ use(global); /// global_argument: error |
+ use(global as Object); /// global_as: error? |
eernst
2017/02/21 13:39:12
Allow, as usual.
|
+ void y = global; /// global_void_init: error |
+ dynamic y = global; /// global_dynamic_init: error |
+ global is Object; /// global_is: error |
+ throw global; /// global_throw: error |
+ [global]; /// global_literal_list_init: error |
+ var m1 = { 4: global }; /// global_literal_map_value_init: error |
+ var m2 = { global: 4 }; /// global_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: global }; /// global_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { global: 4 }; /// global_literal_map_key_init2: error |
+ var z = null ?? global; /// global_null_equals2: error |
+ var z = global ?? 499; /// global_null_equals2: error |
+ return global; /// global_return: error |
+} |
+ |
+void testVoidConditional() { |
+ 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.
|
+ (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.
|
+ 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.
|
+ true ? true? x: x : true? x: x; /// conditional_conditional: ok |
+ for (true? x: x; false; true? x: x) {} /// conditional_for: ok |
+ use(true? x: x); /// conditional_argument: error |
+ void y = true? x: x; /// conditional_void_init: error |
+ dynamic y = true? x: x; /// conditional_dynamic_init: error |
+ throw true? x: x; /// conditional_throw: error |
+ [true? x: x]; /// conditional_literal_list_init: error |
+ var m1 = { 4: true? x: x }; /// conditional_literal_map_value_init: error |
+ Map<dynamic, dynamic> m3 = { 4: true? x: x }; /// conditional_literal_map_value_init2: error |
+ var z = null ?? true? x: x; /// conditional_null_equals2: error |
+ return true? x: x; /// conditional_return: error |
eernst
2017/02/21 13:39:12
Usual consideration: We currently allow `return g(
|
+ |
+ (true? 499: x); /// conditional2_parens: error |
eernst
2017/02/21 13:39:12
With parens allowed, this would be ok.
|
+ true? 499: x; /// conditional2_stmt: ok |
+ true ? true? 499: x : true? 499: x; /// conditional2_conditional: ok |
+ for (true? 499: x; false; true? 499: x) {} /// conditional2_for: ok |
+ use(true? 499: x); /// conditional2_argument: error |
+ void y = true? 499: x; /// conditional2_void_init: error |
+ dynamic y = true? 499: x; /// conditional2_dynamic_init: error |
+ throw true? 499: x; /// conditional2_throw: error |
+ [true? 499: x]; /// conditional2_literal_list_init: error |
+ var m1 = { 4: true? 499: x }; /// conditional2_literal_map_value_init: error |
+ Map<dynamic, dynamic> m3 = { 4: true? 499: x }; /// conditional2_literal_map_value_init2: error |
+ var z = null ?? true? 499: x; /// conditional2_null_equals2: error |
+ return true? 499: x; /// conditional2_return: error |
eernst
2017/02/21 13:39:11
Same as line 106.
|
+ |
+ (true? x: 499); /// conditional3_parens: error |
eernst
2017/02/21 13:39:12
OK if parens are ok.
|
+ true? x: 499; /// conditional3_stmt: ok |
+ true ? true? x: 499 : true? x: 499; /// conditional3_conditional: ok |
+ for (true? x: 499; false; true? x: 499) {} /// conditional3_for: ok |
+ use(true? x: 499); /// conditional3_argument: error |
+ void y = true? x: 499; /// conditional3_void_init: error |
+ dynamic y = true? x: 499; /// conditional3_dynamic_init: error |
+ throw true? x: 499; /// conditional3_throw: error |
+ [true? x: 499]; /// conditional3_literal_list_init: error |
+ var m1 = { 4: true? x: 499 }; /// conditional3_literal_map_value_init: error |
+ Map<dynamic, dynamic> m3 = { 4: true? x: 499 }; /// conditional3_literal_map_value_init2: error |
+ var z = null ?? true? x: 499; /// conditional3_null_equals2: error |
+ return true? x: 499; /// conditional3_return: error |
eernst
2017/02/21 13:39:12
Same as line 106.
|
+} |
+ |
+ |
+class A<T> { |
+ T x; |
+ |
+ void foo() {} |
+} |
+ |
+class B implements A<void> { |
+ void x; |
+ |
+ int foo() => 499; |
+} |
+ |
+class C implements A<void> { |
+ void get x => null; |
+ set x(void y) {}; |
+} |
+ |
+ |
+void testInstanceField() { |
+ 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.
|
+ a.x = 499; /// field_assign: ok |
+ a.x; /// instance_stmt: ok |
+ true ? a.x : a.x; /// instance_conditional: ok |
+ for (a.x; false; a.x) {} /// instance_for: ok |
+ use(a.x); /// instance_argument: error |
+ 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
|
+ void y = a.x; /// instance_void_init: error |
+ dynamic y = a.x; /// instance_dynamic_init: error |
+ a.x is Object; /// instance_is: error |
+ throw a.x; /// instance_throw: error |
+ [a.x]; /// instance_literal_list_init: error |
+ var m1 = { 4: a.x }; /// instance_literal_map_value_init: error |
+ var m2 = { a.x: 4 }; /// instance_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: a.x }; /// instance_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { a.x: 4 }; /// instance_literal_map_key_init2: error |
+ var z = null ?? a.x; /// instance_null_equals2: error |
+ var z = a.x ?? 499; /// instance_null_equals2: error |
+ return a.x; /// instance_return: error |
+ |
+ 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.
|
+ b.x = 42; /// field_assign2: ok |
+ b.x; /// instance2_stmt: ok |
+ true ? b.x : b.x; /// instance2_conditional: ok |
+ for (b.x; false; b.x) {} /// instance2_for: ok |
+ use(b.x); /// instance2_argument: error |
+ use(b.x as Object); /// instance2_as: error? |
eernst
2017/02/21 13:39:12
Like line 163.
|
+ void y = b.x; /// instance2_void_init: error |
+ dynamic y = b.x; /// instance2_dynamic_init: error |
+ b.x is Object; /// instance2_is: error |
+ throw b.x; /// instance2_throw: error |
+ [b.x]; /// instance2_literal_list_init: error |
+ var m1 = { 4: b.x }; /// instance2_literal_map_value_init: error |
+ var m2 = { b.x: 4 }; /// instance2_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: b.x }; /// instance2_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { b.x: 4 }; /// instance2_literal_map_key_init2: error |
+ var z = null ?? b.x; /// instance2_null_equals2: error |
+ var z = b.x ?? 499; /// instance2_null_equals2: error |
+ return b.x; /// instance2_return: error |
eernst
2017/02/21 13:39:12
Like line 106.
|
+ |
+ var c = new C(); |
+ c.x = 32; /// setter_assign: ok |
+ c.x; /// instance3_stmt: ok |
+ true ? c.x : c.x; /// instance3_conditional: ok |
+ for (c.x; false; c.x) {} /// instance3_for: ok |
+ use(c.x); /// instance3_argument: error |
+ use(c.x as Object); /// instance3_as: error? |
eernst
2017/02/21 13:39:12
Like line 163.
|
+ void y = c.x; /// instance3_void_init: error |
+ dynamic y = c.x; /// instance3_dynamic_init: error |
+ c.x is Object; /// instance3_is: error |
+ throw c.x; /// instance3_throw: error |
+ [c.x]; /// instance3_literal_list_init: error |
+ var m1 = { 4: c.x }; /// instance3_literal_map_value_init: error |
+ var m2 = { c.x: 4 }; /// instance3_literal_map_key_init: error |
+ Map<dynamic, dynamic> m3 = { 4: c.x }; /// instance3_literal_map_value_init2: error |
+ Map<dynamic, dynamic> m4 = { c.x: 4 }; /// instance3_literal_map_key_init2: error |
+ var z = null ?? c.x; /// instance3_null_equals2: error |
+ var z = c.x ?? 499; /// instance3_null_equals2: error |
+ return c.x; /// instance3_return: error |
+} |
+ |
+main() { |
+ testVoidParam(499); |
+ testVoidCall(() {}); |
+ testVoidLocal(); |
+ testVoidConditional(); |
+ testInstanceField(); |
+} |