| 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 | 8 |
| 9 import 'package:package_config/packages.dart'; | 9 import 'package:package_config/packages.dart'; |
| 10 import 'package:package_config/packages_file.dart' as pkgs; | 10 import 'package:package_config/packages_file.dart' as pkgs; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 userPackagesDiscoveryTask = | 66 userPackagesDiscoveryTask = |
| 67 new GenericTask('Package discovery', measurer), | 67 new GenericTask('Package discovery', measurer), |
| 68 ]); | 68 ]); |
| 69 } | 69 } |
| 70 | 70 |
| 71 void log(message) { | 71 void log(message) { |
| 72 callUserHandler( | 72 callUserHandler( |
| 73 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); | 73 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); |
| 74 } | 74 } |
| 75 | 75 |
| 76 /// Report [exception] reading [uri]. Use [element] and [node] to compute |
| 77 /// the error location. |
| 78 void _reportReadError( |
| 79 Uri uri, elements.Element element, Spannable node, exception) { |
| 80 if (element == null || node == null) { |
| 81 reporter.reportErrorMessage(new SourceSpan(uri, 0, 0), |
| 82 MessageKind.READ_SELF_ERROR, {'uri': uri, 'exception': exception}); |
| 83 } else { |
| 84 reporter.withCurrentElement(element, () { |
| 85 reporter.reportErrorMessage(node, MessageKind.READ_URI_ERROR, |
| 86 {'uri': uri, 'exception': exception}); |
| 87 }); |
| 88 } |
| 89 } |
| 90 |
| 76 /** | 91 /** |
| 77 * Reads the script designated by [readableUri]. | 92 * Reads the script designated by [readableUri]. |
| 78 */ | 93 */ |
| 79 Future<Script> readScript(Uri readableUri, [Spannable node]) { | 94 Future<Script> readScript(Uri readableUri, [Spannable node]) { |
| 80 if (!readableUri.isAbsolute) { | 95 if (!readableUri.isAbsolute) { |
| 81 if (node == null) node = NO_LOCATION_SPANNABLE; | 96 if (node == null) node = NO_LOCATION_SPANNABLE; |
| 82 reporter.internalError( | 97 reporter.internalError( |
| 83 node, 'Relative uri $readableUri provided to readScript(Uri).'); | 98 node, 'Relative uri $readableUri provided to readScript(Uri).'); |
| 84 } | 99 } |
| 85 | 100 |
| 86 // We need to store the current element since we are reporting read errors | 101 // We need to store the current element since we are reporting read errors |
| 87 // asynchronously and therefore need to restore the current element for | 102 // asynchronously and therefore need to restore the current element for |
| 88 // [node] to be valid. | 103 // [node] to be valid. |
| 89 elements.Element element = currentElement; | 104 elements.Element element = currentElement; |
| 90 void reportReadError(exception) { | |
| 91 if (element == null || node == null) { | |
| 92 reporter.reportErrorMessage( | |
| 93 new SourceSpan(readableUri, 0, 0), | |
| 94 MessageKind.READ_SELF_ERROR, | |
| 95 {'uri': readableUri, 'exception': exception}); | |
| 96 } else { | |
| 97 reporter.withCurrentElement(element, () { | |
| 98 reporter.reportErrorMessage(node, MessageKind.READ_SCRIPT_ERROR, | |
| 99 {'uri': readableUri, 'exception': exception}); | |
| 100 }); | |
| 101 } | |
| 102 } | |
| 103 | 105 |
| 104 Uri resourceUri = translateUri(node, readableUri); | 106 Uri resourceUri = translateUri(node, readableUri); |
| 105 if (resourceUri == null) return _synthesizeScript(readableUri); | 107 if (resourceUri == null) return _synthesizeScript(readableUri); |
| 106 if (resourceUri.scheme == 'dart-ext') { | 108 if (resourceUri.scheme == 'dart-ext') { |
| 107 if (!options.allowNativeExtensions) { | 109 if (!options.allowNativeExtensions) { |
| 108 reporter.withCurrentElement(element, () { | 110 reporter.withCurrentElement(element, () { |
| 109 reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED); | 111 reporter.reportErrorMessage(node, MessageKind.DART_EXT_NOT_SUPPORTED); |
| 110 }); | 112 }); |
| 111 } | 113 } |
| 112 return _synthesizeScript(readableUri); | 114 return _synthesizeScript(readableUri); |
| 113 } | 115 } |
| 114 | 116 |
| 115 // TODO(johnniwinther): Wrap the result from [provider] in a specialized | 117 // TODO(johnniwinther): Wrap the result from [provider] in a specialized |
| 116 // [Future] to ensure that we never execute an asynchronous action without | 118 // [Future] to ensure that we never execute an asynchronous action without |
| 117 // setting up the current element of the compiler. | 119 // setting up the current element of the compiler. |
| 118 return new Future.sync(() => callUserProvider(resourceUri)) | 120 return new Future.sync( |
| 121 () => callUserProvider(resourceUri, api.InputKind.utf8)) |
| 119 .then((SourceFile sourceFile) { | 122 .then((SourceFile sourceFile) { |
| 120 // We use [readableUri] as the URI for the script since need to preserve | 123 // We use [readableUri] as the URI for the script since need to preserve |
| 121 // the scheme in the script because [Script.uri] is used for resolving | 124 // the scheme in the script because [Script.uri] is used for resolving |
| 122 // relative URIs mentioned in the script. See the comment on | 125 // relative URIs mentioned in the script. See the comment on |
| 123 // [LibraryLoader] for more details. | 126 // [LibraryLoader] for more details. |
| 124 return new Script(readableUri, resourceUri, sourceFile); | 127 return new Script(readableUri, resourceUri, sourceFile); |
| 125 }).catchError((error) { | 128 }).catchError((error) { |
| 126 reportReadError(error); | 129 _reportReadError(readableUri, element, node, error); |
| 127 return _synthesizeScript(readableUri); | 130 return _synthesizeScript(readableUri); |
| 128 }); | 131 }); |
| 129 } | 132 } |
| 130 | 133 |
| 131 Future<Script> _synthesizeScript(Uri readableUri) { | 134 Future<Script> _synthesizeScript(Uri readableUri) { |
| 132 return new Future.value(new Script.synthetic(readableUri)); | 135 return new Future.value(new Script.synthetic(readableUri)); |
| 133 } | 136 } |
| 134 | 137 |
| 138 Future<Binary> readBinary(Uri resourceUri, [Spannable node]) { |
| 139 if (!resourceUri.isAbsolute) { |
| 140 if (node == null) node = NO_LOCATION_SPANNABLE; |
| 141 reporter.internalError( |
| 142 node, 'Relative uri $resourceUri provided to readScript(Uri).'); |
| 143 } |
| 144 |
| 145 // We need to store the current element since we are reporting read errors |
| 146 // asynchronously and therefore need to restore the current element for |
| 147 // [node] to be valid. |
| 148 elements.Element element = currentElement; |
| 149 |
| 150 return new Future.sync( |
| 151 () => callUserProvider(resourceUri, api.InputKind.binary)) |
| 152 .catchError((error) { |
| 153 _reportReadError(resourceUri, element, node, error); |
| 154 return new Binary(resourceUri, null); |
| 155 }); |
| 156 } |
| 157 |
| 135 /** | 158 /** |
| 136 * Translates a readable URI into a resource URI. | 159 * Translates a readable URI into a resource URI. |
| 137 * | 160 * |
| 138 * See [LibraryLoader] for terminology on URIs. | 161 * See [LibraryLoader] for terminology on URIs. |
| 139 */ | 162 */ |
| 140 Uri translateUri(Spannable node, Uri uri) => | 163 Uri translateUri(Spannable node, Uri uri) => |
| 141 uri.scheme == 'package' ? translatePackageUri(node, uri) : uri; | 164 uri.scheme == 'package' ? translatePackageUri(node, uri) : uri; |
| 142 | 165 |
| 143 Uri translatePackageUri(Spannable node, Uri uri) { | 166 Uri translatePackageUri(Spannable node, Uri uri) { |
| 144 try { | 167 try { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 169 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); | 192 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); |
| 170 }); | 193 }); |
| 171 } | 194 } |
| 172 | 195 |
| 173 Future setupPackages(Uri uri) { | 196 Future setupPackages(Uri uri) { |
| 174 if (options.packageRoot != null) { | 197 if (options.packageRoot != null) { |
| 175 // Use "non-file" packages because the file version requires a [Directory] | 198 // Use "non-file" packages because the file version requires a [Directory] |
| 176 // and we can't depend on 'dart:io' classes. | 199 // and we can't depend on 'dart:io' classes. |
| 177 packages = new NonFilePackagesDirectoryPackages(options.packageRoot); | 200 packages = new NonFilePackagesDirectoryPackages(options.packageRoot); |
| 178 } else if (options.packageConfig != null) { | 201 } else if (options.packageConfig != null) { |
| 179 return callUserProvider(options.packageConfig) | 202 return callUserProvider(options.packageConfig, api.InputKind.binary) |
| 180 .then((SourceFile sourceFile) { | 203 .then((Binary binary) { |
| 181 List<int> configContents = sourceFile.slowUtf8ZeroTerminatedBytes(); | |
| 182 // The input provider may put a trailing 0 byte when it reads a source | |
| 183 // file, which confuses the package config parser. | |
| 184 if (configContents.length > 0 && configContents.last == 0) { | |
| 185 configContents = configContents.sublist(0, configContents.length - 1); | |
| 186 } | |
| 187 packages = | 204 packages = |
| 188 new MapPackages(pkgs.parse(configContents, options.packageConfig)); | 205 new MapPackages(pkgs.parse(binary.data, options.packageConfig)); |
| 189 }).catchError((error) { | 206 }).catchError((error) { |
| 190 reporter.reportErrorMessage( | 207 reporter.reportErrorMessage( |
| 191 NO_LOCATION_SPANNABLE, | 208 NO_LOCATION_SPANNABLE, |
| 192 MessageKind.INVALID_PACKAGE_CONFIG, | 209 MessageKind.INVALID_PACKAGE_CONFIG, |
| 193 {'uri': options.packageConfig, 'exception': error}); | 210 {'uri': options.packageConfig, 'exception': error}); |
| 194 packages = Packages.noPackages; | 211 packages = Packages.noPackages; |
| 195 }); | 212 }); |
| 196 } else { | 213 } else { |
| 197 if (options.packagesDiscoveryProvider == null) { | 214 if (options.packagesDiscoveryProvider == null) { |
| 198 packages = Packages.noPackages; | 215 packages = Packages.noPackages; |
| 199 } else { | 216 } else { |
| 200 return callUserPackagesDiscovery(uri).then((p) { | 217 return callUserPackagesDiscovery(uri).then((p) { |
| 201 packages = p; | 218 packages = p; |
| 202 }); | 219 }); |
| 203 } | 220 } |
| 204 } | 221 } |
| 205 return new Future.value(); | 222 return new Future.value(); |
| 206 } | 223 } |
| 207 | 224 |
| 208 Future<Null> setupSdk() { | 225 Future<Null> setupSdk() { |
| 209 Future future = new Future.value(null); | 226 Future future = new Future.value(null); |
| 210 if (options.resolutionInputs != null) { | 227 if (options.resolutionInputs != null) { |
| 211 future = Future.forEach(options.resolutionInputs, (Uri resolutionInput) { | 228 future = Future.forEach(options.resolutionInputs, (Uri resolutionInput) { |
| 212 reporter.log('Reading serialized data from ${resolutionInput}'); | 229 reporter.log('Reading serialized data from ${resolutionInput}'); |
| 213 return callUserProvider(resolutionInput).then((SourceFile sourceFile) { | 230 return callUserProvider(resolutionInput, api.InputKind.utf8) |
| 231 .then((SourceFile sourceFile) { |
| 214 serialization.deserializeFromText( | 232 serialization.deserializeFromText( |
| 215 resolutionInput, sourceFile.slowText()); | 233 resolutionInput, sourceFile.slowText()); |
| 216 }); | 234 }); |
| 217 }); | 235 }); |
| 218 } | 236 } |
| 219 if (resolvedUriTranslator.isNotSet) { | 237 if (resolvedUriTranslator.isNotSet) { |
| 220 future = future.then((_) { | 238 future = future.then((_) { |
| 221 return platform_configuration | 239 return platform_configuration |
| 222 .load(options.platformConfigUri, provider) | 240 .load(options.platformConfigUri, provider) |
| 223 .then((Map<String, Uri> mapping) { | 241 .then((Map<String, Uri> mapping) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 try { | 333 try { |
| 316 userHandlerTask.measure(() { | 334 userHandlerTask.measure(() { |
| 317 handler.report(message, uri, begin, end, text, kind); | 335 handler.report(message, uri, begin, end, text, kind); |
| 318 }); | 336 }); |
| 319 } catch (ex, s) { | 337 } catch (ex, s) { |
| 320 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); | 338 reportCrashInUserCode('Uncaught exception in diagnostic handler', ex, s); |
| 321 rethrow; | 339 rethrow; |
| 322 } | 340 } |
| 323 } | 341 } |
| 324 | 342 |
| 325 Future<SourceFile> callUserProvider(Uri uri) { | 343 Future<api.Input> callUserProvider(Uri uri, api.InputKind inputKind) { |
| 326 try { | 344 try { |
| 327 return userProviderTask | 345 return userProviderTask |
| 328 .measureIo(() => provider.readFromUri(uri)) | 346 .measureIo(() => provider.readFromUri(uri, inputKind: inputKind)); |
| 329 .then((data) { | |
| 330 SourceFile sourceFile; | |
| 331 if (data is List<int>) { | |
| 332 sourceFile = new Utf8BytesSourceFile(uri, data); | |
| 333 } else if (data is String) { | |
| 334 sourceFile = new StringSourceFile.fromUri(uri, data); | |
| 335 } else { | |
| 336 throw "Expected a 'String' or a 'List<int>' from the input " | |
| 337 "provider, but got: ${Error.safeToString(data)}."; | |
| 338 } | |
| 339 return sourceFile; | |
| 340 }); | |
| 341 } catch (ex, s) { | 347 } catch (ex, s) { |
| 342 reportCrashInUserCode('Uncaught exception in input provider', ex, s); | 348 reportCrashInUserCode('Uncaught exception in input provider', ex, s); |
| 343 rethrow; | 349 rethrow; |
| 344 } | 350 } |
| 345 } | 351 } |
| 346 | 352 |
| 347 Future<Packages> callUserPackagesDiscovery(Uri uri) { | 353 Future<Packages> callUserPackagesDiscovery(Uri uri) { |
| 348 try { | 354 try { |
| 349 return userPackagesDiscoveryTask | 355 return userPackagesDiscoveryTask |
| 350 .measureIo(() => options.packagesDiscoveryProvider(uri)); | 356 .measureIo(() => options.packagesDiscoveryProvider(uri)); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 } | 417 } |
| 412 } | 418 } |
| 413 | 419 |
| 414 /// For every 'dart:' library, a corresponding environment variable is set | 420 /// For every 'dart:' library, a corresponding environment variable is set |
| 415 /// to "true". The environment variable's name is the concatenation of | 421 /// to "true". The environment variable's name is the concatenation of |
| 416 /// this prefix and the name (without the 'dart:'. | 422 /// this prefix and the name (without the 'dart:'. |
| 417 /// | 423 /// |
| 418 /// For example 'dart:html' has the environment variable 'dart.library.html' set | 424 /// For example 'dart:html' has the environment variable 'dart.library.html' set |
| 419 /// to "true". | 425 /// to "true". |
| 420 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; | 426 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; |
| OLD | NEW |