OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 pub.asset.transformer_isolate; | 5 library pub.asset.transformer_isolate; |
6 | 6 |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 import 'dart:isolate'; | 8 import 'dart:isolate'; |
9 import 'dart:mirrors'; | 9 import 'dart:mirrors'; |
10 | 10 |
(...skipping 11 matching lines...) Expand all Loading... |
22 var configuration = JSON.decode(message['configuration']); | 22 var configuration = JSON.decode(message['configuration']); |
23 var mode = new BarbackMode(message['mode']); | 23 var mode = new BarbackMode(message['mode']); |
24 return _initialize(library, configuration, mode). | 24 return _initialize(library, configuration, mode). |
25 map(serializeTransformerOrGroup).toList(); | 25 map(serializeTransformerOrGroup).toList(); |
26 }); | 26 }); |
27 }); | 27 }); |
28 } | 28 } |
29 | 29 |
30 /// Loads all the transformers and groups defined in [uri]. | 30 /// Loads all the transformers and groups defined in [uri]. |
31 /// | 31 /// |
32 /// Loads the library, finds any Transformer or TransformerGroup subclasses in | 32 /// Loads the library, finds any [Transformer] or [TransformerGroup] subclasses |
33 /// it, instantiates them with [configuration] and [mode], and returns them. | 33 /// in it, instantiates them with [configuration] and [mode], and returns them. |
34 Iterable _initialize(Uri uri, Map configuration, BarbackMode mode) { | 34 List _initialize(Uri uri, Map configuration, BarbackMode mode) { |
35 var mirrors = currentMirrorSystem(); | 35 var mirrors = currentMirrorSystem(); |
36 var transformerClass = reflectClass(Transformer); | 36 var transformerClass = reflectClass(Transformer); |
37 var groupClass = reflectClass(TransformerGroup); | 37 var groupClass = reflectClass(TransformerGroup); |
38 | 38 |
39 // TODO(nweiz): if no valid transformers are found, throw an error message | 39 var seen = new Set(); |
40 // describing candidates and why they were rejected. | 40 var transformers = []; |
41 return mirrors.libraries[uri].declarations.values.map((declaration) { | 41 |
42 if (declaration is! ClassMirror) return null; | 42 loadFromLibrary(library) { |
43 var classMirror = declaration; | 43 if (seen.contains(library)) return; |
44 if (classMirror.isPrivate) return null; | 44 seen.add(library); |
45 if (classMirror.isAbstract) return null; | 45 |
46 if (!classMirror.isSubtypeOf(transformerClass) && | 46 // Load transformers from libraries exported by [library]. |
47 !classMirror.isSubtypeOf(groupClass)) { | 47 for (var dependency in library.libraryDependencies) { |
48 return null; | 48 if (!dependency.isExport) continue; |
| 49 loadFromLibrary(dependency.targetLibrary); |
49 } | 50 } |
50 | 51 |
51 var constructor = _getConstructor(classMirror, 'asPlugin'); | 52 // TODO(nweiz): if no valid transformers are found, throw an error message |
52 if (constructor == null) return null; | 53 // describing candidates and why they were rejected. |
53 if (constructor.parameters.isEmpty) { | 54 transformers.addAll(library.declarations.values.map((declaration) { |
54 if (configuration.isNotEmpty) return null; | 55 if (declaration is! ClassMirror) return null; |
55 return classMirror.newInstance(const Symbol('asPlugin'), []).reflectee; | 56 var classMirror = declaration; |
56 } | 57 if (classMirror.isPrivate) return null; |
57 if (constructor.parameters.length != 1) return null; | 58 if (classMirror.isAbstract) return null; |
| 59 if (!classMirror.isSubtypeOf(transformerClass) && |
| 60 !classMirror.isSubtypeOf(groupClass)) { |
| 61 return null; |
| 62 } |
58 | 63 |
59 return classMirror.newInstance(const Symbol('asPlugin'), | 64 var constructor = _getConstructor(classMirror, 'asPlugin'); |
60 [new BarbackSettings(configuration, mode)]).reflectee; | 65 if (constructor == null) return null; |
61 }).where((classMirror) => classMirror != null); | 66 if (constructor.parameters.isEmpty) { |
| 67 if (configuration.isNotEmpty) return null; |
| 68 return classMirror.newInstance(const Symbol('asPlugin'), []).reflectee; |
| 69 } |
| 70 if (constructor.parameters.length != 1) return null; |
| 71 |
| 72 return classMirror.newInstance(const Symbol('asPlugin'), |
| 73 [new BarbackSettings(configuration, mode)]).reflectee; |
| 74 }).where((classMirror) => classMirror != null)); |
| 75 } |
| 76 |
| 77 loadFromLibrary(mirrors.libraries[uri]); |
| 78 return transformers; |
62 } | 79 } |
63 | 80 |
64 // TODO(nweiz): clean this up when issue 13248 is fixed. | 81 // TODO(nweiz): clean this up when issue 13248 is fixed. |
65 MethodMirror _getConstructor(ClassMirror classMirror, String constructor) { | 82 MethodMirror _getConstructor(ClassMirror classMirror, String constructor) { |
66 var name = new Symbol("${MirrorSystem.getName(classMirror.simpleName)}" | 83 var name = new Symbol("${MirrorSystem.getName(classMirror.simpleName)}" |
67 ".$constructor"); | 84 ".$constructor"); |
68 var candidate = classMirror.declarations[name]; | 85 var candidate = classMirror.declarations[name]; |
69 if (candidate is MethodMirror && candidate.isConstructor) return candidate; | 86 if (candidate is MethodMirror && candidate.isConstructor) return candidate; |
70 return null; | 87 return null; |
71 } | 88 } |
OLD | NEW |