OLD | NEW |
1 // Copyright (c) 2015, the Dart Team. All rights reserved. Use of this | 1 // Copyright (c) 2015, the Dart Team. All rights reserved. Use of this |
2 // source code is governed by a BSD-style license that can be found in | 2 // source code is governed by a BSD-style license that can be found in |
3 // the LICENSE file. | 3 // the LICENSE file. |
4 | 4 |
5 library test_reflectable.test.mixin_test; | 5 /// File being transformed by the reflectable transformer. |
| 6 /// Creates a `MetaReflector` which may be used to reflect on the set of |
| 7 /// reflectors themselves. |
| 8 library test_reflectable.test.meta_reflector_test; |
6 | 9 |
| 10 @GlobalQuantifyCapability( |
| 11 r"^reflectable.reflectable.Reflectable$", const MetaReflector()) |
7 import "package:reflectable/reflectable.dart"; | 12 import "package:reflectable/reflectable.dart"; |
8 import "package:unittest/unittest.dart"; | 13 import "package:unittest/unittest.dart"; |
9 | 14 |
10 class Reflector extends Reflectable { | 15 abstract class AllReflectorsCapable implements Reflectable { |
| 16 Reflectable get self; |
| 17 Set<String> get scopes; |
| 18 } |
| 19 |
| 20 class MetaReflector extends Reflectable { |
| 21 const MetaReflector() |
| 22 : super(subtypeQuantifyCapability, newInstanceCapability); |
| 23 Set<Reflectable> get allReflectors { |
| 24 Set<Reflectable> result = new Set<Reflectable>(); |
| 25 annotatedClasses.forEach((ClassMirror classMirror) { |
| 26 if (classMirror.isAbstract) return; |
| 27 Reflectable reflector = classMirror.newInstance("", []); |
| 28 if (reflector is AllReflectorsCapable) { |
| 29 result.add(reflector.self); |
| 30 } |
| 31 }); |
| 32 return result; |
| 33 } |
| 34 } |
| 35 |
| 36 Set<String> setOf(String s) => new Set<String>.from(<String>[s]); |
| 37 |
| 38 class Reflector extends Reflectable implements AllReflectorsCapable { |
11 const Reflector() | 39 const Reflector() |
12 : super(invokingCapability, declarationsCapability, libraryCapability); | 40 : super(invokingCapability, declarationsCapability, libraryCapability); |
| 41 Reflectable get self => const Reflector(); |
| 42 Set<String> get scopes => setOf("polymer"); |
13 } | 43 } |
14 | 44 |
15 // Note the class `A` is not annotated by this. | 45 class Reflector2 extends Reflectable implements AllReflectorsCapable { |
16 class Reflector2 extends Reflectable { | |
17 const Reflector2() | 46 const Reflector2() |
18 : super(invokingCapability, metadataCapability, libraryCapability); | 47 : super(invokingCapability, metadataCapability, libraryCapability); |
| 48 Reflectable get self => const Reflector2(); |
| 49 Set<String> get scopes => setOf("observe"); |
19 } | 50 } |
20 | 51 |
21 class ReflectorUpwardsClosed extends Reflectable { | 52 class ReflectorUpwardsClosed extends Reflectable |
| 53 implements AllReflectorsCapable { |
22 const ReflectorUpwardsClosed() | 54 const ReflectorUpwardsClosed() |
23 : super(superclassQuantifyCapability, invokingCapability, | 55 : super(superclassQuantifyCapability, invokingCapability, |
24 declarationsCapability, typeRelationsCapability); | 56 declarationsCapability, typeRelationsCapability); |
| 57 Reflectable get self => const ReflectorUpwardsClosed(); |
| 58 Set<String> get scopes => setOf("polymer")..add("observe"); |
25 } | 59 } |
26 | 60 |
27 class ReflectorUpwardsClosedToA extends Reflectable { | 61 class ReflectorUpwardsClosedToA extends Reflectable |
| 62 implements AllReflectorsCapable { |
28 const ReflectorUpwardsClosedToA() | 63 const ReflectorUpwardsClosedToA() |
29 : super(const SuperclassQuantifyCapability(A), invokingCapability, | 64 : super(const SuperclassQuantifyCapability(A), invokingCapability, |
30 declarationsCapability); | 65 declarationsCapability); |
| 66 Reflectable get self => const ReflectorUpwardsClosedToA(); |
| 67 Set<String> get scopes => new Set<String>(); |
31 } | 68 } |
32 | 69 |
33 class ReflectorUpwardsClosedUntilA extends Reflectable { | 70 class ReflectorUpwardsClosedUntilA extends Reflectable |
| 71 implements AllReflectorsCapable { |
34 const ReflectorUpwardsClosedUntilA() | 72 const ReflectorUpwardsClosedUntilA() |
35 : super(const SuperclassQuantifyCapability(A, excludeUpperBound: true), | 73 : super(const SuperclassQuantifyCapability(A, excludeUpperBound: true), |
36 invokingCapability, declarationsCapability); | 74 invokingCapability, declarationsCapability); |
| 75 Reflectable get self => const ReflectorUpwardsClosedUntilA(); |
| 76 Set<String> get scopes => new Set<String>(); |
37 } | 77 } |
38 | 78 |
39 @Reflector() | 79 @Reflector() |
40 @Reflector2() | 80 @Reflector2() |
41 @P() | 81 @P() |
42 class M1 { | 82 class M1 { |
43 foo() {} | 83 foo() {} |
44 var field; | 84 var field; |
45 static staticFoo(x) {} | 85 static staticFoo(x) {} |
46 } | 86 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 expect(bMirror.superclass.reflectedType, const isInstanceOf<Type>()); | 151 expect(bMirror.superclass.reflectedType, const isInstanceOf<Type>()); |
112 expect(bMirror.superclass.superclass.reflectedType, | 152 expect(bMirror.superclass.superclass.reflectedType, |
113 const isInstanceOf<Type>()); | 153 const isInstanceOf<Type>()); |
114 }); | 154 }); |
115 } | 155 } |
116 | 156 |
117 Matcher throwsANoSuchCapabilityException = | 157 Matcher throwsANoSuchCapabilityException = |
118 throwsA(const isInstanceOf<NoSuchCapabilityError>()); | 158 throwsA(const isInstanceOf<NoSuchCapabilityError>()); |
119 | 159 |
120 main() { | 160 main() { |
121 testReflector(const Reflector(), "each is annotated"); | 161 Set<Reflectable> allReflectors = const MetaReflector().allReflectors; |
122 testReflector(const ReflectorUpwardsClosed(), "upwards closed"); | 162 |
123 test("Mixin, superclasses not included", () { | 163 test("MetaReflector, set of reflectors", () { |
124 var reflector2 = const Reflector2(); | 164 expect( |
| 165 allReflectors, |
| 166 [ |
| 167 const Reflector(), |
| 168 const Reflector2(), |
| 169 const ReflectorUpwardsClosed(), |
| 170 const ReflectorUpwardsClosedToA(), |
| 171 const ReflectorUpwardsClosedUntilA() |
| 172 ].toSet()); |
| 173 expect( |
| 174 allReflectors.where((AllReflectorsCapable reflector) => |
| 175 reflector.scopes.contains("polymer")), |
| 176 [const Reflector(), const ReflectorUpwardsClosed()].toSet()); |
| 177 expect( |
| 178 allReflectors.where((AllReflectorsCapable reflector) => |
| 179 reflector.scopes.contains("observe")), |
| 180 [const Reflector2(), const ReflectorUpwardsClosed()].toSet()); |
| 181 }); |
| 182 |
| 183 allReflectors |
| 184 .where((AllReflectorsCapable reflector) => |
| 185 reflector.scopes.contains("polymer")) |
| 186 .forEach( |
| 187 (Reflectable reflector) => testReflector(reflector, "$reflector")); |
| 188 |
| 189 test("MetaReflector, select by name", () { |
| 190 var reflector2 = allReflectors |
| 191 .firstWhere((Reflectable reflector) => "$reflector".contains("2")); |
125 ClassMirror bMirror = reflector2.reflectType(B); | 192 ClassMirror bMirror = reflector2.reflectType(B); |
126 ClassMirror cMirror = reflector2.reflectType(C); | 193 ClassMirror cMirror = reflector2.reflectType(C); |
127 ClassMirror dMirror = reflector2.reflectType(D); | 194 ClassMirror dMirror = reflector2.reflectType(D); |
128 ClassMirror m1Mirror = reflector2.reflectType(M1); | 195 ClassMirror m1Mirror = reflector2.reflectType(M1); |
129 ClassMirror m2Mirror = reflector2.reflectType(M2); | 196 ClassMirror m2Mirror = reflector2.reflectType(M2); |
130 ClassMirror m3Mirror = reflector2.reflectType(M3); | 197 ClassMirror m3Mirror = reflector2.reflectType(M3); |
131 expect(bMirror.mixin, bMirror); | 198 expect(bMirror.mixin, bMirror); |
132 expect(cMirror.mixin, cMirror); | 199 expect(cMirror.mixin, cMirror); |
133 expect(dMirror.mixin, m1Mirror); | 200 expect(dMirror.mixin, m1Mirror); |
134 expect(m1Mirror.mixin, m1Mirror); | 201 expect(m1Mirror.mixin, m1Mirror); |
135 // Test that metadata is preserved. | 202 // Test that metadata is preserved. |
136 expect(m1Mirror.metadata, contains(const P())); | 203 expect(m1Mirror.metadata, contains(const P())); |
137 expect(m2Mirror.mixin, m2Mirror); | 204 expect(m2Mirror.mixin, m2Mirror); |
138 expect(m3Mirror.mixin, m3Mirror); | 205 expect(m3Mirror.mixin, m3Mirror); |
139 expect(bMirror.superclass.mixin, m1Mirror); | 206 expect(bMirror.superclass.mixin, m1Mirror); |
140 // Test that the mixin-application does not inherit the metadata from its | 207 // Test that the mixin-application does not inherit the metadata from its |
141 // mixin. | 208 // mixin. |
142 expect(bMirror.superclass.metadata, isEmpty); | 209 expect(bMirror.superclass.metadata, isEmpty); |
143 expect( | 210 expect( |
144 () => bMirror.superclass.superclass, throwsANoSuchCapabilityException); | 211 () => bMirror.superclass.superclass, throwsANoSuchCapabilityException); |
145 expect(cMirror.superclass.superclass.mixin, m2Mirror); | 212 expect(cMirror.superclass.superclass.mixin, m2Mirror); |
146 expect(cMirror.superclass.mixin, m3Mirror); | 213 expect(cMirror.superclass.mixin, m3Mirror); |
147 expect(cMirror.superclass.superclass.superclass, bMirror); | 214 expect(cMirror.superclass.superclass.superclass, bMirror); |
148 expect(() => dMirror.superclass, throwsANoSuchCapabilityException); | 215 expect(() => dMirror.superclass, throwsANoSuchCapabilityException); |
149 }); | 216 }); |
150 test("Mixin, superclasses included up to bound", () { | 217 |
151 var reflector = const ReflectorUpwardsClosedToA(); | 218 test("MetaReflector, select by capability", () { |
| 219 var reflector = allReflectors.firstWhere((AllReflectorsCapable reflector) { |
| 220 return (reflector.capabilities.any((ReflectCapability capability) => |
| 221 capability is SuperclassQuantifyCapability && |
| 222 capability.upperBound == A && |
| 223 !capability.excludeUpperBound)); |
| 224 }); |
152 ClassMirror aMirror = reflector.reflectType(A); | 225 ClassMirror aMirror = reflector.reflectType(A); |
153 ClassMirror bMirror = reflector.reflectType(B); | 226 ClassMirror bMirror = reflector.reflectType(B); |
154 ClassMirror cMirror = reflector.reflectType(C); | 227 ClassMirror cMirror = reflector.reflectType(C); |
155 ClassMirror dMirror = reflector.reflectType(D); | 228 ClassMirror dMirror = reflector.reflectType(D); |
156 expect(() => reflector.reflectType(M1), throwsANoSuchCapabilityException); | 229 expect(() => reflector.reflectType(M1), throwsANoSuchCapabilityException); |
157 expect(() => reflector.reflectType(M2), throwsANoSuchCapabilityException); | 230 expect(() => reflector.reflectType(M2), throwsANoSuchCapabilityException); |
158 expect(() => reflector.reflectType(M3), throwsANoSuchCapabilityException); | 231 expect(() => reflector.reflectType(M3), throwsANoSuchCapabilityException); |
159 expect(() => bMirror.superclass.mixin, throwsANoSuchCapabilityException); | 232 expect(() => bMirror.superclass.mixin, throwsANoSuchCapabilityException); |
160 expect(bMirror.superclass.superclass, aMirror); | 233 expect(bMirror.superclass.superclass, aMirror); |
161 expect(() => cMirror.superclass.mixin, throwsANoSuchCapabilityException); | 234 expect(() => cMirror.superclass.mixin, throwsANoSuchCapabilityException); |
162 expect(() => cMirror.superclass.superclass.mixin, | 235 expect(() => cMirror.superclass.superclass.mixin, |
163 throwsANoSuchCapabilityException); | 236 throwsANoSuchCapabilityException); |
164 expect(cMirror.superclass.superclass.superclass, bMirror); | 237 expect(cMirror.superclass.superclass.superclass, bMirror); |
165 expect(() => dMirror.mixin, throwsANoSuchCapabilityException); | 238 expect(() => dMirror.mixin, throwsANoSuchCapabilityException); |
166 expect(dMirror.superclass, aMirror); | 239 expect(dMirror.superclass, aMirror); |
167 }); | 240 }); |
168 test("Mixin, superclasses included up to but not including bound", () { | |
169 var reflector = const ReflectorUpwardsClosedUntilA(); | |
170 ClassMirror bMirror = reflector.reflectType(B); | |
171 ClassMirror cMirror = reflector.reflectType(C); | |
172 ClassMirror dMirror = reflector.reflectType(D); | |
173 expect(() => reflector.reflectType(A), throwsANoSuchCapabilityException); | |
174 expect(() => reflector.reflectType(M1), throwsANoSuchCapabilityException); | |
175 expect(() => reflector.reflectType(M2), throwsANoSuchCapabilityException); | |
176 expect(() => reflector.reflectType(M3), throwsANoSuchCapabilityException); | |
177 expect(() => cMirror.superclass.mixin, throwsANoSuchCapabilityException); | |
178 expect(() => cMirror.superclass.superclass.mixin, | |
179 throwsANoSuchCapabilityException); | |
180 expect(cMirror.superclass.superclass.superclass, bMirror); | |
181 expect(cMirror.superclass.superclass.superclass.superclass != null, true); | |
182 expect(() => cMirror.superclass.superclass.superclass.superclass.superclass, | |
183 throwsANoSuchCapabilityException); | |
184 expect(() => dMirror.mixin, throwsANoSuchCapabilityException); | |
185 expect(() => dMirror.superclass, throwsANoSuchCapabilityException); | |
186 }); | |
187 test("Mixin, naming", () { | |
188 var reflector2 = const Reflector2(); | |
189 ClassMirror bMirror = reflector2.reflectType(B); | |
190 ClassMirror cMirror = reflector2.reflectType(C); | |
191 ClassMirror dMirror = reflector2.reflectType(D); | |
192 ClassMirror aWithM1Mirror = bMirror.superclass; | |
193 ClassMirror bWithM2Mirror = cMirror.superclass.superclass; | |
194 ClassMirror bWithM2WithM3Mirror = cMirror.superclass; | |
195 expect(bMirror.simpleName, "B"); | |
196 expect(cMirror.simpleName, "C"); | |
197 expect(dMirror.simpleName, "D"); | |
198 expect( | |
199 aWithM1Mirror.simpleName, | |
200 "test_reflectable.test.mixin_test.A with " | |
201 "test_reflectable.test.mixin_test.M1"); | |
202 expect( | |
203 bWithM2Mirror.simpleName, | |
204 "test_reflectable.test.mixin_test.B with " | |
205 "test_reflectable.test.mixin_test.M2"); | |
206 expect( | |
207 bWithM2WithM3Mirror.simpleName, | |
208 "test_reflectable.test.mixin_test.B with " | |
209 "test_reflectable.test.mixin_test.M2, " | |
210 "test_reflectable.test.mixin_test.M3"); | |
211 expect(cMirror.simpleName, "C"); | |
212 expect(dMirror.simpleName, "D"); | |
213 | |
214 expect(bMirror.qualifiedName, "test_reflectable.test.mixin_test.B"); | |
215 expect(cMirror.qualifiedName, "test_reflectable.test.mixin_test.C"); | |
216 expect(dMirror.qualifiedName, "test_reflectable.test.mixin_test.D"); | |
217 expect( | |
218 aWithM1Mirror.qualifiedName, | |
219 "test_reflectable.test.mixin_test." | |
220 "test_reflectable.test.mixin_test.A with " | |
221 "test_reflectable.test.mixin_test.M1"); | |
222 expect( | |
223 bWithM2Mirror.qualifiedName, | |
224 "test_reflectable.test.mixin_test." | |
225 "test_reflectable.test.mixin_test.B with " | |
226 "test_reflectable.test.mixin_test.M2"); | |
227 expect( | |
228 bWithM2WithM3Mirror.qualifiedName, | |
229 "test_reflectable.test.mixin_test." | |
230 "test_reflectable.test.mixin_test.B with " | |
231 "test_reflectable.test.mixin_test.M2, " | |
232 "test_reflectable.test.mixin_test.M3"); | |
233 expect(cMirror.qualifiedName, "test_reflectable.test.mixin_test.C"); | |
234 expect(dMirror.qualifiedName, "test_reflectable.test.mixin_test.D"); | |
235 }); | |
236 } | 241 } |
OLD | NEW |