| 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 |