OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 | 4 |
5 library mixin_typevariable_test; | 5 library mixin_typevariable_test; |
6 | 6 |
7 import 'package:expect/expect.dart'; | 7 import 'package:expect/expect.dart'; |
8 import "package:async_helper/async_helper.dart"; | 8 import "package:async_helper/async_helper.dart"; |
9 import 'type_test_helper.dart'; | 9 import 'type_test_helper.dart'; |
10 import 'package:compiler/src/dart_types.dart'; | 10 import 'package:compiler/src/dart_types.dart'; |
11 import "package:compiler/src/elements/elements.dart" | 11 import "package:compiler/src/elements/elements.dart" show Element, ClassElement; |
12 show Element, ClassElement; | |
13 | 12 |
14 void main() { | 13 void main() { |
15 testMixinSupertypes(); | 14 testMixinSupertypes(); |
16 testNonTrivialSubstitutions(); | 15 testNonTrivialSubstitutions(); |
17 } | 16 } |
18 | 17 |
19 void testMixinSupertypes() { | 18 void testMixinSupertypes() { |
20 asyncTest(() => TypeEnvironment.create(r""" | 19 asyncTest(() => TypeEnvironment |
| 20 .create( |
| 21 r""" |
21 class S<S_T> {} | 22 class S<S_T> {} |
22 class M1<M1_T> {} | 23 class M1<M1_T> {} |
23 class M2<M2_T> {} | 24 class M2<M2_T> {} |
24 class M3<M3_T> {} | 25 class M3<M3_T> {} |
25 | 26 |
26 class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {} | 27 class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {} |
27 class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>; | 28 class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>; |
28 """, expectNoWarningsOrErrors: true).then((env) { | 29 """, |
| 30 expectNoWarningsOrErrors: true) |
| 31 .then((env) { |
| 32 ClassElement Object = env.getElement('Object'); |
| 33 ClassElement S = env.getElement('S'); |
| 34 ClassElement M1 = env.getElement('M1'); |
| 35 ClassElement M2 = env.getElement('M2'); |
| 36 ClassElement M3 = env.getElement('M3'); |
| 37 ClassElement C1 = env.getElement('C1'); |
| 38 ClassElement C2 = env.getElement('C2'); |
29 | 39 |
30 ClassElement Object = env.getElement('Object'); | 40 ClassElement C1_S_M1_M2_M3 = C1.superclass; |
31 ClassElement S = env.getElement('S'); | 41 ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass; |
32 ClassElement M1 = env.getElement('M1'); | 42 ClassElement C1_S_M1 = C1_S_M1_M2.superclass; |
33 ClassElement M2 = env.getElement('M2'); | |
34 ClassElement M3 = env.getElement('M3'); | |
35 ClassElement C1 = env.getElement('C1'); | |
36 ClassElement C2 = env.getElement('C2'); | |
37 | 43 |
38 ClassElement C1_S_M1_M2_M3 = C1.superclass; | 44 ClassElement C2_S_M1_M2 = C2.superclass; |
39 ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass; | 45 ClassElement C2_S_M1 = C2_S_M1_M2.superclass; |
40 ClassElement C1_S_M1 = C1_S_M1_M2.superclass; | |
41 | 46 |
42 ClassElement C2_S_M1_M2 = C2.superclass; | 47 void testSupertypes(ClassElement element) { |
43 ClassElement C2_S_M1 = C2_S_M1_M2.superclass; | 48 if (element != Object) { |
| 49 Expect.isTrue(element.typeVariables.length == 1); |
| 50 Expect.equals( |
| 51 element, element.typeVariables.first.element.enclosingElement); |
| 52 } |
| 53 for (InterfaceType supertype in element.allSupertypesAndSelf.types) { |
| 54 if (!supertype.typeArguments.isEmpty) { |
| 55 Expect.listEquals(element.typeVariables, supertype.typeArguments, |
| 56 "Type argument mismatch on supertype $supertype of $element.")
; |
| 57 } else { |
| 58 Expect.equals(Object, supertype.element); |
| 59 } |
| 60 } |
| 61 } |
44 | 62 |
45 void testSupertypes(ClassElement element) { | 63 testSupertypes(Object); |
46 if (element != Object) { | 64 testSupertypes(S); |
47 Expect.isTrue(element.typeVariables.length == 1); | 65 testSupertypes(M1); |
48 Expect.equals(element, | 66 testSupertypes(M2); |
49 element.typeVariables.first.element.enclosingElement); | 67 testSupertypes(C1_S_M1); |
50 } | 68 testSupertypes(C1_S_M1_M2); |
51 for (InterfaceType supertype in element.allSupertypesAndSelf.types) { | 69 testSupertypes(C1_S_M1_M2_M3); |
52 if (!supertype.typeArguments.isEmpty) { | 70 testSupertypes(C1); |
53 Expect.listEquals(element.typeVariables, supertype.typeArguments, | 71 testSupertypes(C2_S_M1); |
54 "Type argument mismatch on supertype $supertype of $element."); | 72 testSupertypes(C2_S_M1_M2); |
55 } else { | 73 testSupertypes(C2); |
56 Expect.equals(Object, supertype.element); | 74 })); |
57 } | |
58 } | |
59 } | |
60 | |
61 testSupertypes(Object); | |
62 testSupertypes(S); | |
63 testSupertypes(M1); | |
64 testSupertypes(M2); | |
65 testSupertypes(C1_S_M1); | |
66 testSupertypes(C1_S_M1_M2); | |
67 testSupertypes(C1_S_M1_M2_M3); | |
68 testSupertypes(C1); | |
69 testSupertypes(C2_S_M1); | |
70 testSupertypes(C2_S_M1_M2); | |
71 testSupertypes(C2); | |
72 })); | |
73 } | 75 } |
74 | 76 |
75 void testNonTrivialSubstitutions() { | 77 void testNonTrivialSubstitutions() { |
76 asyncTest(() => TypeEnvironment.create(r""" | 78 asyncTest(() => TypeEnvironment |
| 79 .create( |
| 80 r""" |
77 class _ {} | 81 class _ {} |
78 class A<A_T> {} | 82 class A<A_T> {} |
79 class B<B_T, B_S> {} | 83 class B<B_T, B_S> {} |
80 | 84 |
81 class C1<C1_T> extends A with B {} | 85 class C1<C1_T> extends A with B {} |
82 class C2<C2_T> = A with B; | 86 class C2<C2_T> = A with B; |
83 | 87 |
84 class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {} | 88 class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {} |
85 class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>; | 89 class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>; |
86 | 90 |
87 class E1<E1_T> extends A<_> with B<_, A<_>> {} | 91 class E1<E1_T> extends A<_> with B<_, A<_>> {} |
88 class E2<E2_T> = A<_> with B<_, A<_>>; | 92 class E2<E2_T> = A<_> with B<_, A<_>>; |
89 | 93 |
90 class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {} | 94 class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {} |
91 class F2<F2_T> = A<_> with B<_, B<F2_T, _>>; | 95 class F2<F2_T> = A<_> with B<_, B<F2_T, _>>; |
92 """, expectNoWarningsOrErrors: true).then((env) { | 96 """, |
93 DartType _dynamic = env['dynamic']; | 97 expectNoWarningsOrErrors: true) |
94 DartType _ = env['_']; | 98 .then((env) { |
| 99 DartType _dynamic = env['dynamic']; |
| 100 DartType _ = env['_']; |
95 | 101 |
96 ClassElement Object = env.getElement('Object'); | 102 ClassElement Object = env.getElement('Object'); |
97 ClassElement A = env.getElement('A'); | 103 ClassElement A = env.getElement('A'); |
98 ClassElement B = env.getElement('B'); | 104 ClassElement B = env.getElement('B'); |
99 ClassElement C1 = env.getElement('C1'); | 105 ClassElement C1 = env.getElement('C1'); |
100 ClassElement C2 = env.getElement('C2'); | 106 ClassElement C2 = env.getElement('C2'); |
101 ClassElement D1 = env.getElement('D1'); | 107 ClassElement D1 = env.getElement('D1'); |
102 ClassElement D2 = env.getElement('D2'); | 108 ClassElement D2 = env.getElement('D2'); |
103 ClassElement E1 = env.getElement('E1'); | 109 ClassElement E1 = env.getElement('E1'); |
104 ClassElement E2 = env.getElement('E2'); | 110 ClassElement E2 = env.getElement('E2'); |
105 ClassElement F1 = env.getElement('F1'); | 111 ClassElement F1 = env.getElement('F1'); |
106 ClassElement F2 = env.getElement('F2'); | 112 ClassElement F2 = env.getElement('F2'); |
107 | 113 |
108 ClassElement C1_A_B = C1.superclass; | 114 ClassElement C1_A_B = C1.superclass; |
109 ClassElement D1_A_B = D1.superclass; | 115 ClassElement D1_A_B = D1.superclass; |
110 ClassElement E1_A_B = E1.superclass; | 116 ClassElement E1_A_B = E1.superclass; |
111 ClassElement F1_A_B = F1.superclass; | 117 ClassElement F1_A_B = F1.superclass; |
112 | 118 |
113 void testSupertypes(ClassElement element, | 119 void testSupertypes(ClassElement element, |
114 Map<ClassElement, List<DartType>> typeArguments) { | 120 Map<ClassElement, List<DartType>> typeArguments) { |
115 if (element != Object) { | 121 if (element != Object) { |
116 Expect.isTrue(element.typeVariables.length == 1); | 122 Expect.isTrue(element.typeVariables.length == 1); |
117 Expect.equals(element, | 123 Expect.equals( |
118 element.typeVariables.first.element.enclosingElement); | 124 element, element.typeVariables.first.element.enclosingElement); |
119 } | 125 } |
120 for (InterfaceType supertype in element.allSupertypesAndSelf.types) { | 126 for (InterfaceType supertype in element.allSupertypesAndSelf.types) { |
121 if (typeArguments.containsKey(supertype.element)) { | 127 if (typeArguments.containsKey(supertype.element)) { |
122 Expect.listEquals(typeArguments[supertype.element], | 128 Expect.listEquals( |
123 supertype.typeArguments, | 129 typeArguments[supertype.element], |
124 "Type argument mismatch on supertype $supertype of $element."); | 130 supertype.typeArguments, |
125 } else if (!supertype.typeArguments.isEmpty) { | 131 "Type argument mismatch on supertype $supertype of $element.")
; |
126 Expect.listEquals(element.typeVariables, supertype.typeArguments, | 132 } else if (!supertype.typeArguments.isEmpty) { |
127 "Type argument mismatch on supertype $supertype of $element."); | 133 Expect.listEquals(element.typeVariables, supertype.typeArguments, |
128 } else { | 134 "Type argument mismatch on supertype $supertype of $element.")
; |
129 Expect.equals(Object, supertype.element); | 135 } else { |
| 136 Expect.equals(Object, supertype.element); |
| 137 } |
| 138 } |
130 } | 139 } |
131 } | |
132 } | |
133 | 140 |
134 testSupertypes(C1, {A: [_dynamic], B: [_dynamic, _dynamic]}); | 141 testSupertypes(C1, { |
135 testSupertypes(C1.superclass, {A: [_dynamic], B: [_dynamic, _dynamic]}); | 142 A: [_dynamic], |
136 testSupertypes(C2, {A: [_dynamic], B: [_dynamic, _dynamic]}); | 143 B: [_dynamic, _dynamic] |
| 144 }); |
| 145 testSupertypes(C1.superclass, { |
| 146 A: [_dynamic], |
| 147 B: [_dynamic, _dynamic] |
| 148 }); |
| 149 testSupertypes(C2, { |
| 150 A: [_dynamic], |
| 151 B: [_dynamic, _dynamic] |
| 152 }); |
137 | 153 |
138 DartType D1_T = D1.typeVariables.first; | 154 DartType D1_T = D1.typeVariables.first; |
139 testSupertypes(D1, {A: [D1_T], B: [D1_T, instantiate(A, [D1_T])]}); | 155 testSupertypes(D1, { |
140 DartType D1_superclass_T = D1.superclass.typeVariables.first; | 156 A: [D1_T], |
141 testSupertypes(D1.superclass, | 157 B: [ |
142 {A: [D1_superclass_T], | 158 D1_T, |
143 B: [D1_superclass_T, instantiate(A, [D1_superclass_T])]}); | 159 instantiate(A, [D1_T]) |
144 DartType D2_T = D2.typeVariables.first; | 160 ] |
145 testSupertypes(D2, {A: [D2_T], B: [D2_T, instantiate(A, [D2_T])]}); | 161 }); |
| 162 DartType D1_superclass_T = D1.superclass.typeVariables.first; |
| 163 testSupertypes(D1.superclass, { |
| 164 A: [D1_superclass_T], |
| 165 B: [ |
| 166 D1_superclass_T, |
| 167 instantiate(A, [D1_superclass_T]) |
| 168 ] |
| 169 }); |
| 170 DartType D2_T = D2.typeVariables.first; |
| 171 testSupertypes(D2, { |
| 172 A: [D2_T], |
| 173 B: [ |
| 174 D2_T, |
| 175 instantiate(A, [D2_T]) |
| 176 ] |
| 177 }); |
146 | 178 |
147 testSupertypes(E1, {A: [_], B: [_, instantiate(A, [_])]}); | 179 testSupertypes(E1, { |
148 testSupertypes(E1.superclass, {A: [_], B: [_, instantiate(A, [_])]}); | 180 A: [_], |
149 testSupertypes(E2, {A: [_], B: [_, instantiate(A, [_])]}); | 181 B: [ |
| 182 _, |
| 183 instantiate(A, [_]) |
| 184 ] |
| 185 }); |
| 186 testSupertypes(E1.superclass, { |
| 187 A: [_], |
| 188 B: [ |
| 189 _, |
| 190 instantiate(A, [_]) |
| 191 ] |
| 192 }); |
| 193 testSupertypes(E2, { |
| 194 A: [_], |
| 195 B: [ |
| 196 _, |
| 197 instantiate(A, [_]) |
| 198 ] |
| 199 }); |
150 | 200 |
151 DartType F1_T = F1.typeVariables.first; | 201 DartType F1_T = F1.typeVariables.first; |
152 testSupertypes(F1, {A: [_], B: [_, instantiate(B, [F1_T, _])]}); | 202 testSupertypes(F1, { |
153 DartType F1_superclass_T = F1.superclass.typeVariables.first; | 203 A: [_], |
154 testSupertypes(F1.superclass, {A: [_], B: [_, instantiate(B, [F1_superclass_
T, _])]}); | 204 B: [ |
155 DartType F2_T = F2.typeVariables.first; | 205 _, |
156 testSupertypes(F2, {A: [_], B: [_, instantiate(B, [F2_T, _])]}); | 206 instantiate(B, [F1_T, _]) |
157 })); | 207 ] |
| 208 }); |
| 209 DartType F1_superclass_T = F1.superclass.typeVariables.first; |
| 210 testSupertypes(F1.superclass, { |
| 211 A: [_], |
| 212 B: [ |
| 213 _, |
| 214 instantiate(B, [F1_superclass_T, _]) |
| 215 ] |
| 216 }); |
| 217 DartType F2_T = F2.typeVariables.first; |
| 218 testSupertypes(F2, { |
| 219 A: [_], |
| 220 B: [ |
| 221 _, |
| 222 instantiate(B, [F2_T, _]) |
| 223 ] |
| 224 }); |
| 225 })); |
158 } | 226 } |
OLD | NEW |