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