OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // Dart test for testing the ternary operator. | 4 // Dart test for testing the ternary operator. |
5 | 5 |
6 import "package:expect/expect.dart"; | 6 import "package:expect/expect.dart"; |
7 | 7 |
8 // Test that `Null` acts like the bottom type - less than any other type. | 8 // Test that `Null` acts like the bottom type - less than any other type. |
9 | 9 |
10 bool isCheckedMode = () { bool c = false; assert(c = true); return c; } (); | 10 bool isCheckedMode = () { |
| 11 bool c = false; |
| 12 assert(c = true); |
| 13 return c; |
| 14 }(); |
11 | 15 |
12 typedef R Fun<A, R>(A argument); | 16 typedef R Fun<A, R>(A argument); |
13 | 17 |
14 class C<T> { | 18 class C<T> { |
15 const C(); | 19 const C(); |
16 T returns() => null; | 20 T returns() => null; |
17 void accepts(T x) {} | 21 void accepts(T x) {} |
18 } | 22 } |
19 | 23 |
20 class NullBound<T extends num> {} | 24 class NullBound<T extends num> {} |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 var co = new C<Object>(); | 57 var co = new C<Object>(); |
54 Expect.isFalse(co is C<Null>); | 58 Expect.isFalse(co is C<Null>); |
55 | 59 |
56 if (!isCheckedMode) return; | 60 if (!isCheckedMode) return; |
57 | 61 |
58 List<int> li1 = const <Null>[]; | 62 List<int> li1 = const <Null>[]; |
59 | 63 |
60 C<Null> x1 = cn; | 64 C<Null> x1 = cn; |
61 C<Object> x2 = cn; | 65 C<Object> x2 = cn; |
62 | 66 |
63 Expect.identical(x1 , cn); | 67 Expect.identical(x1, cn); |
64 Expect.identical(x2 , cn); | 68 Expect.identical(x2, cn); |
65 | 69 |
66 const C<Null> cocn = const C<Null>(); | 70 const C<Null> cocn = const C<Null>(); |
67 const C<Object> coco = cocn; | 71 const C<Object> coco = cocn; |
68 const C<int> coci = cocn; | 72 const C<int> coci = cocn; |
69 | 73 |
70 Expect.identical(cocn, coco); | 74 Expect.identical(cocn, coco); |
71 Expect.identical(cocn, coci); | 75 Expect.identical(cocn, coci); |
72 | 76 |
73 Expect.throws(() { | 77 Expect.throws(() { |
74 Null x = "string" as dynamic; | 78 Null x = "string" as dynamic; |
75 use(x); // Avoid "x unused" warning. | 79 use(x); // Avoid "x unused" warning. |
76 }); | 80 }); |
77 | 81 |
78 Expect.throws(() { | 82 Expect.throws(() { |
79 Null x = new Object(); | 83 Null x = new Object(); |
80 use(x); // Avoid "x unused" warning. | 84 use(x); // Avoid "x unused" warning. |
81 }); | 85 }); |
82 | 86 |
83 NullBound<int> nb = new NullBound<Null>(); // Should not fail. | 87 NullBound<int> nb = new NullBound<Null>(); // Should not fail. |
84 use(nb); // Avoid "nb unused" warning. | 88 use(nb); // Avoid "nb unused" warning. |
85 ListBound<List<Null>> lb = new ListBound<Null>(); // Should not fails | 89 ListBound<List<Null>> lb = new ListBound<Null>(); // Should not fails |
86 use(lb); // Avoid "nb unused" warning. | 90 use(lb); // Avoid "nb unused" warning. |
87 } | 91 } |
88 | 92 |
89 void testFunctionTypes() { | 93 void testFunctionTypes() { |
90 T1 t1 = new T1(); | 94 T1 t1 = new T1(); |
91 T2 t2 = new T2(); | 95 T2 t2 = new T2(); |
92 T1 t = t2; | 96 T1 t = t2; |
93 | 97 |
94 Fun<int, Null> f1 = t1.foo; | 98 Fun<int, Null> f1 = t1.foo; |
95 Fun<Null, int> f2 = t.bar; | 99 Fun<Null, int> f2 = t.bar; |
96 f1 = t1.baz; | 100 f1 = t1.baz; |
97 f2 = t.qux; | 101 f2 = t.qux; |
98 use(f1); | 102 use(f1); |
99 use(f2); | 103 use(f2); |
100 | 104 |
101 var l = new List<Fun<Null, Null>>(); | 105 var l = new List<Fun<Null, Null>>(); |
102 Expect.isTrue(l is List<Fun<Null, int>>); | 106 Expect.isTrue(l is List<Fun<Null, int>>); |
103 l = new List<Fun<int, int>>(); | 107 l = new List<Fun<int, int>>(); |
104 Expect.isTrue(l is List<Fun<Null, num>>); | 108 Expect.isTrue(l is List<Fun<Null, num>>); |
105 | 109 |
106 Expect.isTrue(((int _) => null) is Fun<int, Null>); | 110 Expect.isTrue(((int _) => null) is Fun<int, Null>); |
107 | 111 |
108 Null fun(int x) => null; | 112 Null fun(int x) => null; |
109 Fun<Null, int> fun2 = fun; // Safe assignment. | 113 Fun<Null, int> fun2 = fun; // Safe assignment. |
110 if (fun2 is Fun<int, Null>) { | 114 if (fun2 is Fun<int, Null>) { |
111 // If int->Null is *subtype* of Null->int (which it should be), | 115 // If int->Null is *subtype* of Null->int (which it should be), |
112 // then type promotion succeeds. | 116 // then type promotion succeeds. |
113 // If type promotion succeeds, the static type is int->Null, otherwise | 117 // If type promotion succeeds, the static type is int->Null, otherwise |
114 // it's Null->int. | 118 // it's Null->int. |
115 fun2(42); // Should not give a warning after type promotion. | 119 fun2(42); // Should not give a warning after type promotion. |
116 fun2(null).abs(); // //# 03: runtime error | 120 fun2(null).abs(); // //# 03: runtime error |
117 } | 121 } |
118 } | 122 } |
119 | 123 |
120 class T1 { | 124 class T1 { |
121 Null foo(int x) => null; | 125 Null foo(int x) => null; |
122 int bar(Null x) => null; | 126 int bar(Null x) => null; |
123 Null baz(int x) => null; | 127 Null baz(int x) => null; |
124 int qux(Null x) => null; | 128 int qux(Null x) => null; |
125 } | 129 } |
126 | 130 |
127 class T2 extends T1 { | 131 class T2 extends T1 { |
128 Null foo(Null x) => null; | 132 Null foo(Null x) => null; |
129 Null bar(Null x) => null; | 133 Null bar(Null x) => null; |
130 int baz(int x) => x; | 134 int baz(int x) => x; |
131 int qux(int x) => x; | 135 int qux(int x) => x; |
132 } | 136 } |
133 | 137 |
134 // Avoid "variable not used" warnings. | 138 // Avoid "variable not used" warnings. |
135 use(x) { | 139 use(x) { |
136 return identical(x, x); | 140 return identical(x, x); |
137 } | 141 } |
OLD | NEW |