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 pub.load_transformers; | 5 library pub.load_transformers; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:isolate'; | 9 import 'dart:isolate'; |
10 | 10 |
11 import 'package:barback/barback.dart'; | |
12 | |
13 import '../../../asset/dart/serialize.dart'; | 11 import '../../../asset/dart/serialize.dart'; |
14 import '../barback.dart'; | 12 import '../barback.dart'; |
15 import '../dart.dart' as dart; | 13 import '../dart.dart' as dart; |
16 import '../log.dart' as log; | 14 import '../log.dart' as log; |
17 import '../utils.dart'; | 15 import '../utils.dart'; |
18 import 'asset_environment.dart'; | 16 import 'asset_environment.dart'; |
19 import 'excluding_transformer.dart'; | 17 import 'foreign_transformer.dart'; |
20 import 'barback_server.dart'; | 18 import 'barback_server.dart'; |
21 | 19 |
22 /// Load and return all transformers and groups from the library identified by | 20 /// Load and return all transformers and groups from the library identified by |
23 /// [id]. | 21 /// [id]. |
24 Future<Set> loadTransformers(AssetEnvironment environment, | 22 Future<Set> loadTransformers(AssetEnvironment environment, |
25 BarbackServer transformerServer, TransformerId id) { | 23 BarbackServer transformerServer, TransformerId id) { |
26 return id.getAssetId(environment.barback).then((assetId) { | 24 return id.getAssetId(environment.barback).then((assetId) { |
27 var path = assetId.path.replaceFirst('lib/', ''); | 25 var path = assetId.path.replaceFirst('lib/', ''); |
28 // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed. | 26 // TODO(nweiz): load from a "package:" URI when issue 12474 is fixed. |
29 | 27 |
(...skipping 14 matching lines...) Expand all Loading... |
44 return dart.runInIsolate(code, port.sendPort) | 42 return dart.runInIsolate(code, port.sendPort) |
45 .then((_) => port.first) | 43 .then((_) => port.first) |
46 .then((sendPort) { | 44 .then((sendPort) { |
47 return call(sendPort, { | 45 return call(sendPort, { |
48 'library': uri.toString(), | 46 'library': uri.toString(), |
49 'mode': environment.mode.name, | 47 'mode': environment.mode.name, |
50 // TODO(nweiz): support non-JSON-encodable configuration maps. | 48 // TODO(nweiz): support non-JSON-encodable configuration maps. |
51 'configuration': JSON.encode(id.configuration) | 49 'configuration': JSON.encode(id.configuration) |
52 }).then((transformers) { | 50 }).then((transformers) { |
53 transformers = transformers.map( | 51 transformers = transformers.map( |
54 (transformer) => _deserializeTransformerOrGroup(transformer, id)) | 52 (transformer) => deserializeTransformerOrGroup(transformer, id)) |
55 .toSet(); | 53 .toSet(); |
56 log.fine("Transformers from $assetId: $transformers"); | 54 log.fine("Transformers from $assetId: $transformers"); |
57 return transformers; | 55 return transformers; |
58 }); | 56 }); |
59 }).catchError((error, stackTrace) { | 57 }).catchError((error, stackTrace) { |
60 if (error is! CrossIsolateException) throw error; | 58 if (error is! CrossIsolateException) throw error; |
61 if (error.type != 'IsolateSpawnException') throw error; | 59 if (error.type != 'IsolateSpawnException') throw error; |
62 // TODO(nweiz): don't parse this as a string once issues 12617 and 12689 | 60 // TODO(nweiz): don't parse this as a string once issues 12617 and 12689 |
63 // are fixed. | 61 // are fixed. |
64 if (!error.message.split('\n')[1].endsWith("import '$uri';")) { | 62 if (!error.message.split('\n')[1].endsWith("import '$uri';")) { |
65 throw error; | 63 throw error; |
66 } | 64 } |
67 | 65 |
68 // If there was an IsolateSpawnException and the import that actually | 66 // If there was an IsolateSpawnException and the import that actually |
69 // failed was the one we were loading transformers from, throw an | 67 // failed was the one we were loading transformers from, throw an |
70 // application exception with a more user-friendly message. | 68 // application exception with a more user-friendly message. |
71 fail('Transformer library "package:${id.package}/$path" not found.', | 69 fail('Transformer library "package:${id.package}/$path" not found.', |
72 error, stackTrace); | 70 error, stackTrace); |
73 }); | 71 }); |
74 }); | 72 }); |
75 } | 73 } |
76 | |
77 /// A wrapper for a transformer that's in a different isolate. | |
78 class _ForeignTransformer extends Transformer { | |
79 /// The port with which we communicate with the child isolate. | |
80 /// | |
81 /// This port and all messages sent across it are specific to this | |
82 /// transformer. | |
83 final SendPort _port; | |
84 | |
85 /// The result of calling [toString] on the transformer in the isolate. | |
86 final String _toString; | |
87 | |
88 _ForeignTransformer(Map map) | |
89 : _port = map['port'], | |
90 _toString = map['toString']; | |
91 | |
92 Future<bool> isPrimary(AssetId id) { | |
93 return call(_port, { | |
94 'type': 'isPrimary', | |
95 'id': serializeId(id) | |
96 }); | |
97 } | |
98 | |
99 Future apply(Transform transform) { | |
100 return call(_port, { | |
101 'type': 'apply', | |
102 'transform': serializeTransform(transform) | |
103 }); | |
104 } | |
105 | |
106 String toString() => _toString; | |
107 } | |
108 | |
109 /// A wrapper for a transformer group that's in a different isolate. | |
110 class _ForeignGroup implements TransformerGroup { | |
111 final Iterable<Iterable> phases; | |
112 | |
113 /// The result of calling [toString] on the transformer group in the isolate. | |
114 final String _toString; | |
115 | |
116 _ForeignGroup(TransformerId id, Map map) | |
117 : phases = map['phases'].map((phase) { | |
118 return phase.map((transformer) => _deserializeTransformerOrGroup( | |
119 transformer, id)).toList(); | |
120 }).toList(), | |
121 _toString = map['toString']; | |
122 | |
123 String toString() => _toString; | |
124 } | |
125 | |
126 /// Converts a serializable map into a [Transformer] or a [TransformerGroup]. | |
127 _deserializeTransformerOrGroup(Map map, TransformerId id) { | |
128 if (map['type'] == 'Transformer') { | |
129 var transformer = new _ForeignTransformer(map); | |
130 return ExcludingTransformer.wrap(transformer, id.includes, id.excludes); | |
131 } | |
132 | |
133 assert(map['type'] == 'TransformerGroup'); | |
134 return new _ForeignGroup(id, map); | |
135 } | |
OLD | NEW |