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.resolutionInput != null) { |
| 209 reporter.log('Reading serialized data from ${options.resolutionInput}'); |
| 210 future = callUserProvider(options.resolutionInput) |
| 211 .then((SourceFile sourceFile) { |
| 212 serialization.deserializeFromText(sourceFile.slowText()); |
| 213 }); |
| 214 } |
216 if (resolvedUriTranslator.isNotSet) { | 215 if (resolvedUriTranslator.isNotSet) { |
217 return platform_configuration | 216 future = future.then((_) { |
218 .load(options.platformConfigUri, provider) | 217 return platform_configuration |
219 .then((Map<String, Uri> mapping) { | 218 .load(options.platformConfigUri, provider) |
220 resolvedUriTranslator.resolvedUriTranslator = | 219 .then((Map<String, Uri> mapping) { |
221 new ResolvedUriTranslator(mapping, reporter); | 220 resolvedUriTranslator.resolvedUriTranslator = |
| 221 new ResolvedUriTranslator(mapping, reporter); |
| 222 }); |
222 }); | 223 }); |
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 } | 224 } |
| 225 // The incremental compiler sets up the sdk before run. |
| 226 // Therefore this will be called a second time. |
| 227 return future; |
228 } | 228 } |
229 | 229 |
230 Future<bool> run(Uri uri) { | 230 Future<bool> run(Uri uri) { |
231 Duration setupDuration = measurer.wallClock.elapsed; | 231 Duration setupDuration = measurer.wallClock.elapsed; |
232 return selfTask.measureSubtask("CompilerImpl.run", () { | 232 return selfTask.measureSubtask("CompilerImpl.run", () { |
233 log('Using platform configuration at ${options.platformConfigUri}'); | 233 log('Using platform configuration at ${options.platformConfigUri}'); |
234 | 234 |
235 return setupSdk().then((_) => setupPackages(uri)).then((_) { | 235 return setupSdk().then((_) => setupPackages(uri)).then((_) { |
236 assert(resolvedUriTranslator.isSet); | 236 assert(resolvedUriTranslator.isSet); |
237 assert(packages != null); | 237 assert(packages != null); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 try { | 309 try { |
310 userHandlerTask.measure(() { | 310 userHandlerTask.measure(() { |
311 handler.report(message, uri, begin, end, text, kind); | 311 handler.report(message, uri, begin, end, text, kind); |
312 }); | 312 }); |
313 } catch (ex, s) { | 313 } catch (ex, s) { |
314 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); | 314 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); |
315 rethrow; | 315 rethrow; |
316 } | 316 } |
317 } | 317 } |
318 | 318 |
319 Future callUserProvider(Uri uri) { | 319 Future<SourceFile> callUserProvider(Uri uri) { |
320 try { | 320 try { |
321 return userProviderTask.measureIo(() => provider.readFromUri(uri)); | 321 return userProviderTask |
| 322 .measureIo(() => provider.readFromUri(uri)) |
| 323 .then((data) { |
| 324 SourceFile sourceFile; |
| 325 if (data is List<int>) { |
| 326 sourceFile = new Utf8BytesSourceFile(uri, data); |
| 327 } else if (data is String) { |
| 328 sourceFile = new StringSourceFile.fromUri(uri, data); |
| 329 } else { |
| 330 throw "Expected a 'String' or a 'List<int>' from the input " |
| 331 "provider, but got: ${Error.safeToString(data)}."; |
| 332 } |
| 333 return sourceFile; |
| 334 }); |
322 } catch (ex, s) { | 335 } catch (ex, s) { |
323 reportCrashInUserCode('Uncaught exception in input provider', ex, s); | 336 reportCrashInUserCode('Uncaught exception in input provider', ex, s); |
324 rethrow; | 337 rethrow; |
325 } | 338 } |
326 } | 339 } |
327 | 340 |
328 Future<Packages> callUserPackagesDiscovery(Uri uri) { | 341 Future<Packages> callUserPackagesDiscovery(Uri uri) { |
329 try { | 342 try { |
330 return userPackagesDiscoveryTask | 343 return userPackagesDiscoveryTask |
331 .measureIo(() => options.packagesDiscoveryProvider(uri)); | 344 .measureIo(() => options.packagesDiscoveryProvider(uri)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 } | 390 } |
378 } | 391 } |
379 | 392 |
380 /// For every 'dart:' library, a corresponding environment variable is set | 393 /// For every 'dart:' library, a corresponding environment variable is set |
381 /// to "true". The environment variable's name is the concatenation of | 394 /// to "true". The environment variable's name is the concatenation of |
382 /// this prefix and the name (without the 'dart:'. | 395 /// this prefix and the name (without the 'dart:'. |
383 /// | 396 /// |
384 /// For example 'dart:html' has the environment variable 'dart.library.html' set | 397 /// For example 'dart:html' has the environment variable 'dart.library.html' set |
385 /// to "true". | 398 /// to "true". |
386 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; | 399 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; |
OLD | NEW |