OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 leg_apiimpl; | 5 library leg_apiimpl; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 | 9 |
10 import 'package:package_config/packages.dart'; | 10 import 'package:package_config/packages.dart'; |
11 import 'package:package_config/packages_file.dart' as pkgs; | 11 import 'package:package_config/packages_file.dart' as pkgs; |
12 import 'package:package_config/src/packages_impl.dart' | 12 import 'package:package_config/src/packages_impl.dart' |
13 show MapPackages, NonFilePackagesDirectoryPackages; | 13 show MapPackages, NonFilePackagesDirectoryPackages; |
14 import 'package:package_config/src/util.dart' show checkValidPackageUri; | 14 import 'package:package_config/src/util.dart' show checkValidPackageUri; |
15 | 15 |
16 import '../compiler_new.dart' as api; | 16 import '../compiler_new.dart' as api; |
17 import 'common/tasks.dart' show GenericTask, Measurer; | 17 import 'common/tasks.dart' show GenericTask, Measurer; |
18 import 'common.dart'; | 18 import 'common.dart'; |
19 import 'common/backend_api.dart' show Backend; | 19 import 'common/backend_api.dart' show Backend; |
20 import 'compiler.dart'; | 20 import 'compiler.dart'; |
21 import 'diagnostics/messages.dart' show Message; | 21 import 'diagnostics/messages.dart' show Message; |
22 import 'elements/elements.dart' as elements; | 22 import 'elements/elements.dart' as elements; |
23 import 'environment.dart'; | 23 import 'environment.dart'; |
24 import 'io/source_file.dart'; | 24 import 'io/source_file.dart'; |
25 import 'options.dart' show CompilerOptions; | 25 import 'options.dart' show CompilerOptions; |
26 import 'platform_configuration.dart' as platform_configuration; | 26 import 'platform_configuration.dart' as platform_configuration; |
27 import 'resolved_uri_translator.dart'; | 27 import 'resolved_uri_translator.dart'; |
28 import 'script.dart'; | 28 import 'script.dart'; |
| 29 import 'serialization/system.dart'; |
29 | 30 |
30 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the | 31 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the |
31 /// sources. | 32 /// sources. |
32 class CompilerImpl extends Compiler { | 33 class CompilerImpl extends Compiler { |
33 api.CompilerInput provider; | 34 api.CompilerInput provider; |
34 api.CompilerDiagnostics handler; | 35 api.CompilerDiagnostics handler; |
35 Packages packages; | 36 Packages packages; |
36 | 37 |
37 bool get mockableLibraryUsed => resolvedUriTranslator.isSet | 38 bool get mockableLibraryUsed => resolvedUriTranslator.isSet |
38 ? resolvedUriTranslator.mockableLibraryUsed | 39 ? resolvedUriTranslator.mockableLibraryUsed |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 reporter.withCurrentElement(element, () { | 106 reporter.withCurrentElement(element, () { |
106 reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED); | 107 reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED); |
107 }); | 108 }); |
108 } | 109 } |
109 return _synthesizeScript(readableUri); | 110 return _synthesizeScript(readableUri); |
110 } | 111 } |
111 | 112 |
112 // TODO(johnniwinther): Wrap the result from [provider] in a specialized | 113 // TODO(johnniwinther): Wrap the result from [provider] in a specialized |
113 // [Future] to ensure that we never execute an asynchronous action without | 114 // [Future] to ensure that we never execute an asynchronous action without |
114 // setting up the current element of the compiler. | 115 // setting up the current element of the compiler. |
115 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { | 116 return new Future.sync(() => callUserProvider(resourceUri)) |
116 SourceFile sourceFile; | 117 .then((SourceFile sourceFile) { |
117 if (data is List<int>) { | |
118 sourceFile = new Utf8BytesSourceFile(resourceUri, data); | |
119 } else if (data is String) { | |
120 sourceFile = new StringSourceFile.fromUri(resourceUri, data); | |
121 } else { | |
122 String message = "Expected a 'String' or a 'List<int>' from the input " | |
123 "provider, but got: ${Error.safeToString(data)}."; | |
124 reportReadError(message); | |
125 } | |
126 // We use [readableUri] as the URI for the script since need to preserve | 118 // We use [readableUri] as the URI for the script since need to preserve |
127 // the scheme in the script because [Script.uri] is used for resolving | 119 // the scheme in the script because [Script.uri] is used for resolving |
128 // relative URIs mentioned in the script. See the comment on | 120 // relative URIs mentioned in the script. See the comment on |
129 // [LibraryLoader] for more details. | 121 // [LibraryLoader] for more details. |
130 return new Script(readableUri, resourceUri, sourceFile); | 122 return new Script(readableUri, resourceUri, sourceFile); |
131 }).catchError((error) { | 123 }).catchError((error) { |
132 reportReadError(error); | 124 reportReadError(error); |
133 return _synthesizeScript(readableUri); | 125 return _synthesizeScript(readableUri); |
134 }); | 126 }); |
135 } | 127 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); | 167 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); |
176 }); | 168 }); |
177 } | 169 } |
178 | 170 |
179 Future setupPackages(Uri uri) { | 171 Future setupPackages(Uri uri) { |
180 if (options.packageRoot != null) { | 172 if (options.packageRoot != null) { |
181 // Use "non-file" packages because the file version requires a [Directory] | 173 // Use "non-file" packages because the file version requires a [Directory] |
182 // and we can't depend on 'dart:io' classes. | 174 // and we can't depend on 'dart:io' classes. |
183 packages = new NonFilePackagesDirectoryPackages(options.packageRoot); | 175 packages = new NonFilePackagesDirectoryPackages(options.packageRoot); |
184 } else if (options.packageConfig != null) { | 176 } else if (options.packageConfig != null) { |
185 return callUserProvider(options.packageConfig).then((configContents) { | 177 return callUserProvider(options.packageConfig) |
186 if (configContents is String) { | 178 .then((SourceFile sourceFile) { |
187 configContents = UTF8.encode(configContents); | 179 List<int> configContents = sourceFile.slowUtf8ZeroTerminatedBytes(); |
188 } | |
189 // The input provider may put a trailing 0 byte when it reads a source | 180 // The input provider may put a trailing 0 byte when it reads a source |
190 // file, which confuses the package config parser. | 181 // file, which confuses the package config parser. |
191 if (configContents.length > 0 && configContents.last == 0) { | 182 if (configContents.length > 0 && configContents.last == 0) { |
192 configContents = configContents.sublist(0, configContents.length - 1); | 183 configContents = configContents.sublist(0, configContents.length - 1); |
193 } | 184 } |
194 packages = | 185 packages = |
195 new MapPackages(pkgs.parse(configContents, options.packageConfig)); | 186 new MapPackages(pkgs.parse(configContents, options.packageConfig)); |
196 }).catchError((error) { | 187 }).catchError((error) { |
197 reporter.reportErrorMessage( | 188 reporter.reportErrorMessage( |
198 NO_LOCATION_SPANNABLE, | 189 NO_LOCATION_SPANNABLE, |
199 MessageKind.INVALID_PACKAGE_CONFIG, | 190 MessageKind.INVALID_PACKAGE_CONFIG, |
200 {'uri': options.packageConfig, 'exception': error}); | 191 {'uri': options.packageConfig, 'exception': error}); |
201 packages = Packages.noPackages; | 192 packages = Packages.noPackages; |
202 }); | 193 }); |
203 } else { | 194 } else { |
204 if (options.packagesDiscoveryProvider == null) { | 195 if (options.packagesDiscoveryProvider == null) { |
205 packages = Packages.noPackages; | 196 packages = Packages.noPackages; |
206 } else { | 197 } else { |
207 return callUserPackagesDiscovery(uri).then((p) { | 198 return callUserPackagesDiscovery(uri).then((p) { |
208 packages = p; | 199 packages = p; |
209 }); | 200 }); |
210 } | 201 } |
211 } | 202 } |
212 return new Future.value(); | 203 return new Future.value(); |
213 } | 204 } |
214 | 205 |
215 Future<Null> setupSdk() { | 206 Future<Null> setupSdk() { |
| 207 Future future = new Future.value(null); |
| 208 if (options.serializationSource != null) { |
| 209 reporter |
| 210 .log('Reading serialized data from ${options.serializationSource}'); |
| 211 future = callUserProvider(options.serializationSource) |
| 212 .then((SourceFile sourceFile) { |
| 213 serialization.deserializeFromText(sourceFile.slowText()); |
| 214 }); |
| 215 } |
216 if (resolvedUriTranslator.isNotSet) { | 216 if (resolvedUriTranslator.isNotSet) { |
217 return platform_configuration | 217 future = future.then((_) { |
218 .load(options.platformConfigUri, provider) | 218 return platform_configuration |
219 .then((Map<String, Uri> mapping) { | 219 .load(options.platformConfigUri, provider) |
220 resolvedUriTranslator.resolvedUriTranslator = | 220 .then((Map<String, Uri> mapping) { |
221 new ResolvedUriTranslator(mapping, reporter); | 221 resolvedUriTranslator.resolvedUriTranslator = |
| 222 new ResolvedUriTranslator(mapping, reporter); |
| 223 }); |
222 }); | 224 }); |
223 } else { | |
224 // The incremental compiler sets up the sdk before run. | |
225 // Therefore this will be called a second time. | |
226 return new Future.value(null); | |
227 } | 225 } |
| 226 // The incremental compiler sets up the sdk before run. |
| 227 // Therefore this will be called a second time. |
| 228 return future; |
228 } | 229 } |
229 | 230 |
230 Future<bool> run(Uri uri) { | 231 Future<bool> run(Uri uri) { |
231 Duration setupDuration = measurer.wallClock.elapsed; | 232 Duration setupDuration = measurer.wallClock.elapsed; |
232 return selfTask.measureSubtask("CompilerImpl.run", () { | 233 return selfTask.measureSubtask("CompilerImpl.run", () { |
233 log('Using platform configuration at ${options.platformConfigUri}'); | 234 log('Using platform configuration at ${options.platformConfigUri}'); |
234 | 235 |
235 return setupSdk().then((_) => setupPackages(uri)).then((_) { | 236 return setupSdk().then((_) => setupPackages(uri)).then((_) { |
236 assert(resolvedUriTranslator.isSet); | 237 assert(resolvedUriTranslator.isSet); |
237 assert(packages != null); | 238 assert(packages != null); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 try { | 310 try { |
310 userHandlerTask.measure(() { | 311 userHandlerTask.measure(() { |
311 handler.report(message, uri, begin, end, text, kind); | 312 handler.report(message, uri, begin, end, text, kind); |
312 }); | 313 }); |
313 } catch (ex, s) { | 314 } catch (ex, s) { |
314 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); | 315 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); |
315 rethrow; | 316 rethrow; |
316 } | 317 } |
317 } | 318 } |
318 | 319 |
319 Future callUserProvider(Uri uri) { | 320 Future<SourceFile> callUserProvider(Uri uri) { |
320 try { | 321 try { |
321 return userProviderTask.measureIo(() => provider.readFromUri(uri)); | 322 return userProviderTask |
| 323 .measureIo(() => provider.readFromUri(uri)) |
| 324 .then((data) { |
| 325 SourceFile sourceFile; |
| 326 if (data is List<int>) { |
| 327 sourceFile = new Utf8BytesSourceFile(uri, data); |
| 328 } else if (data is String) { |
| 329 sourceFile = new StringSourceFile.fromUri(uri, data); |
| 330 } else { |
| 331 throw "Expected a 'String' or a 'List<int>' from the input " |
| 332 "provider, but got: ${Error.safeToString(data)}."; |
| 333 } |
| 334 return sourceFile; |
| 335 }); |
322 } catch (ex, s) { | 336 } catch (ex, s) { |
323 reportCrashInUserCode('Uncaught exception in input provider', ex, s); | 337 reportCrashInUserCode('Uncaught exception in input provider', ex, s); |
324 rethrow; | 338 rethrow; |
325 } | 339 } |
326 } | 340 } |
327 | 341 |
328 Future<Packages> callUserPackagesDiscovery(Uri uri) { | 342 Future<Packages> callUserPackagesDiscovery(Uri uri) { |
329 try { | 343 try { |
330 return userPackagesDiscoveryTask | 344 return userPackagesDiscoveryTask |
331 .measureIo(() => options.packagesDiscoveryProvider(uri)); | 345 .measureIo(() => options.packagesDiscoveryProvider(uri)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 } | 391 } |
378 } | 392 } |
379 | 393 |
380 /// For every 'dart:' library, a corresponding environment variable is set | 394 /// For every 'dart:' library, a corresponding environment variable is set |
381 /// to "true". The environment variable's name is the concatenation of | 395 /// to "true". The environment variable's name is the concatenation of |
382 /// this prefix and the name (without the 'dart:'. | 396 /// this prefix and the name (without the 'dart:'. |
383 /// | 397 /// |
384 /// For example 'dart:html' has the environment variable 'dart.library.html' set | 398 /// For example 'dart:html' has the environment variable 'dart.library.html' set |
385 /// to "true". | 399 /// to "true". |
386 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; | 400 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; |
OLD | NEW |