| 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; |
| 17 import 'common.dart'; | 18 import 'common.dart'; |
| 18 import 'common/tasks.dart' show GenericTask; | |
| 19 import 'compiler.dart'; | 19 import 'compiler.dart'; |
| 20 import 'diagnostics/messages.dart' show Message; | 20 import 'diagnostics/messages.dart' show Message; |
| 21 import 'elements/elements.dart' as elements; | 21 import 'elements/elements.dart' as elements; |
| 22 import 'environment.dart'; | 22 import 'environment.dart'; |
| 23 import 'io/source_file.dart'; | 23 import 'io/source_file.dart'; |
| 24 import 'options.dart' show CompilerOptions; | 24 import 'options.dart' show CompilerOptions; |
| 25 import 'platform_configuration.dart' as platform_configuration; | 25 import 'platform_configuration.dart' as platform_configuration; |
| 26 import 'resolved_uri_translator.dart'; |
| 26 import 'script.dart'; | 27 import 'script.dart'; |
| 27 | 28 |
| 28 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the | 29 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the |
| 29 /// sources. | 30 /// sources. |
| 30 class CompilerImpl extends Compiler { | 31 class CompilerImpl extends Compiler { |
| 31 api.CompilerInput provider; | 32 api.CompilerInput provider; |
| 32 api.CompilerDiagnostics handler; | 33 api.CompilerDiagnostics handler; |
| 33 Packages packages; | 34 Packages packages; |
| 34 bool mockableLibraryUsed = false; | |
| 35 | 35 |
| 36 /// A mapping of the dart: library-names to their location. | 36 bool get mockableLibraryUsed => resolvedUriTranslator.isSet |
| 37 /// | 37 ? resolvedUriTranslator.mockableLibraryUsed |
| 38 /// Initialized in [setupSdk]. | 38 : false; |
| 39 Map<String, Uri> sdkLibraries; | 39 |
| 40 ForwardingResolvedUriTranslator resolvedUriTranslator; |
| 40 | 41 |
| 41 GenericTask userHandlerTask; | 42 GenericTask userHandlerTask; |
| 42 GenericTask userProviderTask; | 43 GenericTask userProviderTask; |
| 43 GenericTask userPackagesDiscoveryTask; | 44 GenericTask userPackagesDiscoveryTask; |
| 44 | 45 |
| 45 Uri get libraryRoot => options.platformConfigUri.resolve("."); | 46 Uri get libraryRoot => options.platformConfigUri.resolve("."); |
| 46 | 47 |
| 47 CompilerImpl(this.provider, api.CompilerOutput outputProvider, this.handler, | 48 CompilerImpl(this.provider, api.CompilerOutput outputProvider, this.handler, |
| 48 CompilerOptions options) | 49 CompilerOptions options) |
| 49 : super( | 50 : resolvedUriTranslator = new ForwardingResolvedUriTranslator(), |
| 51 super( |
| 50 options: options, | 52 options: options, |
| 51 outputProvider: outputProvider, | 53 outputProvider: outputProvider, |
| 52 environment: new _Environment(options.environment)) { | 54 environment: new _Environment(options.environment)) { |
| 53 _Environment env = environment; | 55 _Environment env = environment; |
| 54 env.compiler = this; | 56 env.compiler = this; |
| 55 tasks.addAll([ | 57 tasks.addAll([ |
| 56 userHandlerTask = new GenericTask('Diagnostic handler', this), | 58 userHandlerTask = new GenericTask('Diagnostic handler', this), |
| 57 userProviderTask = new GenericTask('Input provider', this), | 59 userProviderTask = new GenericTask('Input provider', this), |
| 58 userPackagesDiscoveryTask = new GenericTask('Package discovery', this), | 60 userPackagesDiscoveryTask = new GenericTask('Package discovery', this), |
| 59 ]); | 61 ]); |
| 60 } | 62 } |
| 61 | 63 |
| 62 void log(message) { | 64 void log(message) { |
| 63 callUserHandler( | 65 callUserHandler( |
| 64 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); | 66 null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); |
| 65 } | 67 } |
| 66 | 68 |
| 67 /// See [Compiler.translateResolvedUri]. | |
| 68 Uri translateResolvedUri(elements.LibraryElement importingLibrary, | |
| 69 Uri resolvedUri, Spannable spannable) { | |
| 70 if (resolvedUri.scheme == 'dart') { | |
| 71 return translateDartUri(importingLibrary, resolvedUri, spannable); | |
| 72 } | |
| 73 return resolvedUri; | |
| 74 } | |
| 75 | |
| 76 /** | 69 /** |
| 77 * Reads the script designated by [readableUri]. | 70 * Reads the script designated by [readableUri]. |
| 78 */ | 71 */ |
| 79 Future<Script> readScript(Uri readableUri, [Spannable node]) { | 72 Future<Script> readScript(Uri readableUri, [Spannable node]) { |
| 80 if (!readableUri.isAbsolute) { | 73 if (!readableUri.isAbsolute) { |
| 81 if (node == null) node = NO_LOCATION_SPANNABLE; | 74 if (node == null) node = NO_LOCATION_SPANNABLE; |
| 82 reporter.internalError( | 75 reporter.internalError( |
| 83 node, 'Relative uri $readableUri provided to readScript(Uri).'); | 76 node, 'Relative uri $readableUri provided to readScript(Uri).'); |
| 84 } | 77 } |
| 85 | 78 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 135 } |
| 143 | 136 |
| 144 /** | 137 /** |
| 145 * Translates a readable URI into a resource URI. | 138 * Translates a readable URI into a resource URI. |
| 146 * | 139 * |
| 147 * See [LibraryLoader] for terminology on URIs. | 140 * See [LibraryLoader] for terminology on URIs. |
| 148 */ | 141 */ |
| 149 Uri translateUri(Spannable node, Uri uri) => | 142 Uri translateUri(Spannable node, Uri uri) => |
| 150 uri.scheme == 'package' ? translatePackageUri(node, uri) : uri; | 143 uri.scheme == 'package' ? translatePackageUri(node, uri) : uri; |
| 151 | 144 |
| 152 /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative | |
| 153 /// to `options.platformConfigUri` according to the information in the file at | |
| 154 /// `options.platformConfigUri`. | |
| 155 /// | |
| 156 /// Returns null and emits an error if the library could not be found or | |
| 157 /// imported into [importingLibrary]. | |
| 158 /// | |
| 159 /// Internal libraries (whose name starts with '_') can be only resolved if | |
| 160 /// [importingLibrary] is a platform or patch library. | |
| 161 Uri translateDartUri(elements.LibraryElement importingLibrary, | |
| 162 Uri resolvedUri, Spannable spannable) { | |
| 163 Uri location = lookupLibraryUri(resolvedUri.path); | |
| 164 | |
| 165 if (location == null) { | |
| 166 reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_FOUND, | |
| 167 {'resolvedUri': resolvedUri}); | |
| 168 return null; | |
| 169 } | |
| 170 | |
| 171 if (resolvedUri.path.startsWith('_')) { | |
| 172 bool allowInternalLibraryAccess = importingLibrary != null && | |
| 173 (importingLibrary.isPlatformLibrary || | |
| 174 importingLibrary.isPatch || | |
| 175 importingLibrary.canonicalUri.path | |
| 176 .contains('sdk/tests/compiler/dart2js_native')); | |
| 177 | |
| 178 if (!allowInternalLibraryAccess) { | |
| 179 if (importingLibrary != null) { | |
| 180 reporter.reportErrorMessage( | |
| 181 spannable, MessageKind.INTERNAL_LIBRARY_FROM, { | |
| 182 'resolvedUri': resolvedUri, | |
| 183 'importingUri': importingLibrary.canonicalUri | |
| 184 }); | |
| 185 } else { | |
| 186 reporter.reportErrorMessage(spannable, MessageKind.INTERNAL_LIBRARY, | |
| 187 {'resolvedUri': resolvedUri}); | |
| 188 registerDisallowedLibraryUse(resolvedUri); | |
| 189 } | |
| 190 return null; | |
| 191 } | |
| 192 } | |
| 193 | |
| 194 if (location.scheme == "unsupported") { | |
| 195 reporter.reportErrorMessage(spannable, MessageKind.LIBRARY_NOT_SUPPORTED, | |
| 196 {'resolvedUri': resolvedUri}); | |
| 197 registerDisallowedLibraryUse(resolvedUri); | |
| 198 return null; | |
| 199 } | |
| 200 | |
| 201 if (resolvedUri.path == 'html' || resolvedUri.path == 'io') { | |
| 202 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart | |
| 203 // supports this use case better. | |
| 204 mockableLibraryUsed = true; | |
| 205 } | |
| 206 return location; | |
| 207 } | |
| 208 | |
| 209 Uri translatePackageUri(Spannable node, Uri uri) { | 145 Uri translatePackageUri(Spannable node, Uri uri) { |
| 210 try { | 146 try { |
| 211 checkValidPackageUri(uri); | 147 checkValidPackageUri(uri); |
| 212 } on ArgumentError catch (e) { | 148 } on ArgumentError catch (e) { |
| 213 reporter.reportErrorMessage(node, MessageKind.INVALID_PACKAGE_URI, | 149 reporter.reportErrorMessage(node, MessageKind.INVALID_PACKAGE_URI, |
| 214 {'uri': uri, 'exception': e.message}); | 150 {'uri': uri, 'exception': e.message}); |
| 215 return null; | 151 return null; |
| 216 } | 152 } |
| 217 return packages.resolve(uri, notFound: (Uri notFound) { | 153 return packages.resolve(uri, notFound: (Uri notFound) { |
| 218 reporter.reportErrorMessage( | 154 reporter.reportErrorMessage( |
| 219 node, MessageKind.LIBRARY_NOT_FOUND, {'resolvedUri': uri}); | 155 node, MessageKind.LIBRARY_NOT_FOUND, {'resolvedUri': uri}); |
| 220 return null; | 156 return null; |
| 221 }); | 157 }); |
| 222 } | 158 } |
| 223 | 159 |
| 224 Future<elements.LibraryElement> analyzeUri(Uri uri, | 160 Future<elements.LibraryElement> analyzeUri(Uri uri, |
| 225 {bool skipLibraryWithPartOfTag: true}) { | 161 {bool skipLibraryWithPartOfTag: true}) { |
| 226 List<Future> setupFutures = new List<Future>(); | 162 List<Future> setupFutures = new List<Future>(); |
| 227 if (sdkLibraries == null) { | 163 if (resolvedUriTranslator.isNotSet) { |
| 228 setupFutures.add(setupSdk()); | 164 setupFutures.add(setupSdk()); |
| 229 } | 165 } |
| 230 if (packages == null) { | 166 if (packages == null) { |
| 231 setupFutures.add(setupPackages(uri)); | 167 setupFutures.add(setupPackages(uri)); |
| 232 } | 168 } |
| 233 return Future.wait(setupFutures).then((_) { | 169 return Future.wait(setupFutures).then((_) { |
| 234 return super | 170 return super |
| 235 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); | 171 .analyzeUri(uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); |
| 236 }); | 172 }); |
| 237 } | 173 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 266 } else { | 202 } else { |
| 267 return callUserPackagesDiscovery(uri).then((p) { | 203 return callUserPackagesDiscovery(uri).then((p) { |
| 268 packages = p; | 204 packages = p; |
| 269 }); | 205 }); |
| 270 } | 206 } |
| 271 } | 207 } |
| 272 return new Future.value(); | 208 return new Future.value(); |
| 273 } | 209 } |
| 274 | 210 |
| 275 Future<Null> setupSdk() { | 211 Future<Null> setupSdk() { |
| 276 if (sdkLibraries == null) { | 212 if (resolvedUriTranslator.isNotSet) { |
| 277 return platform_configuration | 213 return platform_configuration |
| 278 .load(options.platformConfigUri, provider) | 214 .load(options.platformConfigUri, provider) |
| 279 .then((Map<String, Uri> mapping) { | 215 .then((Map<String, Uri> mapping) { |
| 280 sdkLibraries = mapping; | 216 resolvedUriTranslator.resolvedUriTranslator = |
| 217 new ResolvedUriTranslator(mapping, reporter); |
| 281 }); | 218 }); |
| 282 } else { | 219 } else { |
| 283 // The incremental compiler sets up the sdk before run. | 220 // The incremental compiler sets up the sdk before run. |
| 284 // Therefore this will be called a second time. | 221 // Therefore this will be called a second time. |
| 285 return new Future.value(null); | 222 return new Future.value(null); |
| 286 } | 223 } |
| 287 } | 224 } |
| 288 | 225 |
| 289 Future<bool> run(Uri uri) { | 226 Future<bool> run(Uri uri) { |
| 290 log('Using platform configuration at ${options.platformConfigUri}'); | 227 log('Using platform configuration at ${options.platformConfigUri}'); |
| 291 | 228 |
| 292 return Future.wait([setupSdk(), setupPackages(uri)]).then((_) { | 229 return Future.wait([setupSdk(), setupPackages(uri)]).then((_) { |
| 293 assert(sdkLibraries != null); | 230 assert(resolvedUriTranslator.isSet); |
| 294 assert(packages != null); | 231 assert(packages != null); |
| 295 | 232 |
| 296 return super.run(uri).then((bool success) { | 233 return super.run(uri).then((bool success) { |
| 297 int cumulated = 0; | 234 int cumulated = 0; |
| 298 for (final task in tasks) { | 235 for (final task in tasks) { |
| 299 int elapsed = task.timing; | 236 int elapsed = task.timing; |
| 300 if (elapsed != 0) { | 237 if (elapsed != 0) { |
| 301 cumulated += elapsed; | 238 cumulated += elapsed; |
| 302 log('${task.name} took ${elapsed}msec'); | 239 log('${task.name} took ${elapsed}msec'); |
| 303 for (String subtask in task.subtasks) { | 240 for (String subtask in task.subtasks) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 | 285 |
| 349 Future callUserProvider(Uri uri) { | 286 Future callUserProvider(Uri uri) { |
| 350 return userProviderTask.measure(() => provider.readFromUri(uri)); | 287 return userProviderTask.measure(() => provider.readFromUri(uri)); |
| 351 } | 288 } |
| 352 | 289 |
| 353 Future<Packages> callUserPackagesDiscovery(Uri uri) { | 290 Future<Packages> callUserPackagesDiscovery(Uri uri) { |
| 354 return userPackagesDiscoveryTask | 291 return userPackagesDiscoveryTask |
| 355 .measure(() => options.packagesDiscoveryProvider(uri)); | 292 .measure(() => options.packagesDiscoveryProvider(uri)); |
| 356 } | 293 } |
| 357 | 294 |
| 358 Uri lookupLibraryUri(String libraryName) { | |
| 359 assert(invariant(NO_LOCATION_SPANNABLE, sdkLibraries != null, | |
| 360 message: "setupSdk() has not been run")); | |
| 361 return sdkLibraries[libraryName]; | |
| 362 } | |
| 363 | |
| 364 Uri resolvePatchUri(String libraryName) { | 295 Uri resolvePatchUri(String libraryName) { |
| 365 return backend.resolvePatchUri(libraryName, options.platformConfigUri); | 296 return backend.resolvePatchUri(libraryName, options.platformConfigUri); |
| 366 } | 297 } |
| 367 } | 298 } |
| 368 | 299 |
| 369 class _Environment implements Environment { | 300 class _Environment implements Environment { |
| 370 final Map<String, String> definitions; | 301 final Map<String, String> definitions; |
| 371 | 302 |
| 372 // TODO(sigmund): break the circularity here: Compiler needs an environment to | 303 // TODO(sigmund): break the circularity here: Compiler needs an environment to |
| 373 // intialize the library loader, but the environment here needs to know about | 304 // initialize the library loader, but the environment here needs to know about |
| 374 // how the sdk is set up and about whether the backend supports mirrors. | 305 // how the sdk is set up and about whether the backend supports mirrors. |
| 375 CompilerImpl compiler; | 306 CompilerImpl compiler; |
| 376 | 307 |
| 377 _Environment(this.definitions); | 308 _Environment(this.definitions); |
| 378 | 309 |
| 379 String valueOf(String name) { | 310 String valueOf(String name) { |
| 380 assert(invariant(NO_LOCATION_SPANNABLE, compiler.sdkLibraries != null, | 311 assert(invariant( |
| 312 NO_LOCATION_SPANNABLE, compiler.resolvedUriTranslator != null, |
| 381 message: "setupSdk() has not been run")); | 313 message: "setupSdk() has not been run")); |
| 382 | 314 |
| 383 var result = definitions[name]; | 315 var result = definitions[name]; |
| 384 if (result != null || definitions.containsKey(name)) return result; | 316 if (result != null || definitions.containsKey(name)) return result; |
| 385 if (!name.startsWith(_dartLibraryEnvironmentPrefix)) return null; | 317 if (!name.startsWith(_dartLibraryEnvironmentPrefix)) return null; |
| 386 | 318 |
| 387 String libraryName = name.substring(_dartLibraryEnvironmentPrefix.length); | 319 String libraryName = name.substring(_dartLibraryEnvironmentPrefix.length); |
| 388 | 320 |
| 389 // Private libraries are not exposed to the users. | 321 // Private libraries are not exposed to the users. |
| 390 if (libraryName.startsWith("_")) return null; | 322 if (libraryName.startsWith("_")) return null; |
| 391 | 323 |
| 392 if (compiler.sdkLibraries.containsKey(libraryName)) { | 324 if (compiler.resolvedUriTranslator.sdkLibraries.containsKey(libraryName)) { |
| 393 // Dart2js always "supports" importing 'dart:mirrors' but will abort | 325 // Dart2js always "supports" importing 'dart:mirrors' but will abort |
| 394 // the compilation at a later point if the backend doesn't support | 326 // the compilation at a later point if the backend doesn't support |
| 395 // mirrors. In this case 'mirrors' should not be in the environment. | 327 // mirrors. In this case 'mirrors' should not be in the environment. |
| 396 if (libraryName == 'mirrors') { | 328 if (libraryName == 'mirrors') { |
| 397 return compiler.backend.supportsReflection ? "true" : null; | 329 return compiler.backend.supportsReflection ? "true" : null; |
| 398 } | 330 } |
| 399 return "true"; | 331 return "true"; |
| 400 } | 332 } |
| 401 return null; | 333 return null; |
| 402 } | 334 } |
| 403 } | 335 } |
| 404 | 336 |
| 405 /// For every 'dart:' library, a corresponding environment variable is set | 337 /// For every 'dart:' library, a corresponding environment variable is set |
| 406 /// to "true". The environment variable's name is the concatenation of | 338 /// to "true". The environment variable's name is the concatenation of |
| 407 /// this prefix and the name (without the 'dart:'. | 339 /// this prefix and the name (without the 'dart:'. |
| 408 /// | 340 /// |
| 409 /// For example 'dart:html' has the environment variable 'dart.library.html' set | 341 /// For example 'dart:html' has the environment variable 'dart.library.html' set |
| 410 /// to "true". | 342 /// to "true". |
| 411 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; | 343 const String _dartLibraryEnvironmentPrefix = 'dart.library.'; |
| OLD | NEW |