Chromium Code Reviews| Index: pkg/compiler/lib/src/apiimpl.dart |
| diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart |
| index 7620392ddc90c2896b8ae80714893a0355bd682f..0e8466ff40add93db85c5fcfe415cc1d07b589c2 100644 |
| --- a/pkg/compiler/lib/src/apiimpl.dart |
| +++ b/pkg/compiler/lib/src/apiimpl.dart |
| @@ -14,7 +14,6 @@ import 'package:package_config/src/packages_impl.dart' show |
| NonFilePackagesDirectoryPackages; |
| import 'package:package_config/src/util.dart' show |
| checkValidPackageUri; |
| -import 'package:sdk_library_metadata/libraries.dart' as library_info; |
| import '../compiler_new.dart' as api; |
| import 'commandline_options.dart'; |
| @@ -28,17 +27,24 @@ import 'diagnostics/messages.dart' show |
| Message; |
| import 'elements/elements.dart' as elements; |
| import 'io/source_file.dart'; |
| +import 'platform_configuration.dart' as platform_configuration; |
| import 'script.dart'; |
| const bool forceIncrementalSupport = |
| const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
| +/// Locations of the platform descriptor files relative to the library root. |
| +const String _clientPlatform = "lib/dart_client.platform"; |
| +const String _serverPlatform = "lib/dart_server.platform"; |
| +const String _sharedPlatform = "lib/dart_shared.platform"; |
| +const String _dart2dartPlatform = "lib/dart2dart.platform"; |
| + |
| /// Implements the [Compiler] using a [api.CompilerInput] for supplying the |
| /// sources. |
| class CompilerImpl extends Compiler { |
| api.CompilerInput provider; |
| api.CompilerDiagnostics handler; |
| - final Uri libraryRoot; |
| + final Uri platformConfigUri; |
| final Uri packageConfig; |
| final Uri packageRoot; |
| final api.PackagesDiscoveryProvider packagesDiscoveryProvider; |
| @@ -46,23 +52,29 @@ class CompilerImpl extends Compiler { |
| List<String> options; |
| Map<String, dynamic> environment; |
| bool mockableLibraryUsed = false; |
| - final Set<library_info.Category> allowedLibraryCategories; |
| + |
| + /// A mapping of the dart: library-names to their location. |
| + /// |
| + /// Initialized in [setupSdk]. |
| + Map<String, Uri> sdkLibraries; |
| GenericTask userHandlerTask; |
| GenericTask userProviderTask; |
| GenericTask userPackagesDiscoveryTask; |
| + Uri get libraryRoot => platformConfigUri.resolve("."); |
| + |
| CompilerImpl(this.provider, |
| api.CompilerOutput outputProvider, |
| this.handler, |
| - this.libraryRoot, |
| + Uri libraryRoot, |
| this.packageRoot, |
| List<String> options, |
| this.environment, |
| [this.packageConfig, |
| this.packagesDiscoveryProvider]) |
| : this.options = options, |
| - this.allowedLibraryCategories = getAllowedLibraryCategories(options), |
| + this.platformConfigUri = resolvePlatformConfig(libraryRoot, options), |
| super( |
| outputProvider: outputProvider, |
| enableTypeAssertions: hasOption(options, Flags.enableCheckedMode), |
| @@ -175,31 +187,35 @@ class CompilerImpl extends Compiler { |
| return const <String>[]; |
| } |
| - static Set<library_info.Category> getAllowedLibraryCategories( |
| - List<String> options) { |
| - Iterable<library_info.Category> categories = |
| - extractCsvOption(options, '--categories=') |
| - .map(library_info.parseCategory) |
| - .where((x) => x != null); |
| - if (categories.isEmpty) { |
| - return new Set.from([library_info.Category.client]); |
| + static Uri resolvePlatformConfig(Uri libraryRoot, |
| + List<String> options) { |
| + String platformConfigPath = |
| + extractStringOption(options, "--platform-config=", null); |
| + if (platformConfigPath != null) { |
| + return libraryRoot.resolve(platformConfigPath); |
| + } else if (hasOption(options, '--output-type=dart')) { |
| + return libraryRoot.resolve(_dart2dartPlatform); |
| + } else { |
| + Iterable<String> categories = extractCsvOption(options, '--categories='); |
| + if (categories.length == 0) { |
| + return libraryRoot.resolve(_clientPlatform); |
| + } |
| + assert(categories.length <= 2); |
| + if (categories.contains("Client")) { |
| + if (categories.contains("Server")) { |
| + return libraryRoot.resolve(_sharedPlatform); |
| + } |
| + return libraryRoot.resolve(_clientPlatform); |
| + } |
| + assert(categories.contains("Server")); |
| + return libraryRoot.resolve(_serverPlatform); |
| } |
| - return new Set.from(categories); |
| } |
| static bool hasOption(List<String> options, String option) { |
| return options.indexOf(option) >= 0; |
| } |
| - String lookupPatchPath(String dartLibraryName) { |
| - library_info.LibraryInfo info = lookupLibraryInfo(dartLibraryName); |
| - if (info == null) return null; |
| - if (!info.isDart2jsLibrary) return null; |
| - String path = info.dart2jsPatchPath; |
| - if (path == null) return null; |
| - return "lib/$path"; |
| - } |
| - |
| void log(message) { |
| callUserHandler( |
| null, null, null, null, message, api.Diagnostic.VERBOSE_INFO); |
| @@ -304,81 +320,62 @@ class CompilerImpl extends Compiler { |
| } |
| /// Translates "resolvedUri" with scheme "dart" to a [uri] resolved relative |
| - /// to [libraryRoot] according to the information in [library_info.libraries]. |
| + /// to [platformConfigUri] according to the information in the file at |
| + /// [platformConfigUri]. |
| /// |
| /// Returns null and emits an error if the library could not be found or |
| /// imported into [importingLibrary]. |
| /// |
| - /// If [importingLibrary] is a platform or patch library all dart2js libraries |
| - /// can be resolved. Otherwise only libraries with categories in |
| - /// [allowedLibraryCategories] can be resolved. |
| + /// Internal libraries (whose name starts with '_') can be only resolved if |
| + /// [importingLibrary] is a platform or patch library. |
| Uri translateDartUri(elements.LibraryElement importingLibrary, |
| Uri resolvedUri, Spannable spannable) { |
| - library_info.LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); |
| + Uri location = lookupLibraryUri(resolvedUri.path); |
| - bool allowInternalLibraryAccess = false; |
| - if (importingLibrary != null) { |
| - if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
| - allowInternalLibraryAccess = true; |
| - } else if (importingLibrary.canonicalUri.path.contains( |
| - 'sdk/tests/compiler/dart2js_native')) { |
| - allowInternalLibraryAccess = true; |
| - } |
| + if (location == null) { |
| + reporter.reportErrorMessage( |
| + spannable, |
| + MessageKind.LIBRARY_NOT_FOUND, |
| + {'resolvedUri': resolvedUri}); |
| + return null; |
| } |
| - String computePath() { |
| - if (libraryInfo == null) { |
| - return null; |
| - } else if (!libraryInfo.isDart2jsLibrary) { |
| - return null; |
| - } else { |
| - if (libraryInfo.isInternal && |
| - !allowInternalLibraryAccess) { |
| - if (importingLibrary != null) { |
| - reporter.reportErrorMessage( |
| - spannable, |
| - MessageKind.INTERNAL_LIBRARY_FROM, |
| - {'resolvedUri': resolvedUri, |
| - 'importingUri': importingLibrary.canonicalUri}); |
| - } else { |
| - reporter.reportErrorMessage( |
| - spannable, |
| - MessageKind.INTERNAL_LIBRARY, |
| - {'resolvedUri': resolvedUri}); |
| - registerDisallowedLibraryUse(resolvedUri); |
| - } |
| - return null; |
| - } else if (!allowInternalLibraryAccess && |
| - !allowedLibraryCategories.any(libraryInfo.categories.contains)) { |
| - registerDisallowedLibraryUse(resolvedUri); |
| - // TODO(sigurdm): Currently we allow the sdk libraries to import |
| - // libraries from any category. We might want to revisit this. |
| - return null; |
| + if (resolvedUri.path.startsWith('_') ) { |
| + bool allowInternalLibraryAccess = false; |
|
floitsch
2015/10/30 20:43:07
bool allowInternalLibraryAccess = importingLibrary
sigurdm
2015/11/02 10:06:39
Done.
|
| + if (importingLibrary != null) { |
| + if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
| + allowInternalLibraryAccess = true; |
| + } else if (importingLibrary.canonicalUri.path.contains( |
| + 'sdk/tests/compiler/dart2js_native')) { |
| + allowInternalLibraryAccess = true; |
| + } |
| + } |
| + |
| + if (!allowInternalLibraryAccess) { |
| + if (importingLibrary != null) { |
| + reporter.reportErrorMessage( |
| + spannable, |
| + MessageKind.INTERNAL_LIBRARY_FROM, |
| + {'resolvedUri': resolvedUri, |
| + 'importingUri': importingLibrary.canonicalUri}); |
| } else { |
| - return (libraryInfo.dart2jsPath != null) |
| - ? libraryInfo.dart2jsPath |
| - : libraryInfo.path; |
| + reporter.reportErrorMessage( |
| + spannable, |
| + MessageKind.INTERNAL_LIBRARY, |
| + {'resolvedUri': resolvedUri}); |
| + registerDisallowedLibraryUse(resolvedUri); |
| } |
| + return null; |
| } |
| } |
| - String path = computePath(); |
| - |
| - if (path == null) { |
| - if (libraryInfo == null) { |
| - reporter.reportErrorMessage( |
| - spannable, |
| - MessageKind.LIBRARY_NOT_FOUND, |
| - {'resolvedUri': resolvedUri}); |
| - } else { |
| - reporter.reportErrorMessage( |
| - spannable, |
| - MessageKind.LIBRARY_NOT_SUPPORTED, |
| - {'resolvedUri': resolvedUri}); |
| - } |
| - // TODO(johnniwinther): Support signaling the error through the returned |
| - // value. |
| + if (location.scheme == "unsupported") { |
| + reporter.reportErrorMessage( |
| + spannable, |
| + MessageKind.LIBRARY_NOT_SUPPORTED, |
| + {'resolvedUri': resolvedUri}); |
| + registerDisallowedLibraryUse(resolvedUri); |
| return null; |
| } |
| @@ -388,13 +385,7 @@ class CompilerImpl extends Compiler { |
| // supports this use case better. |
| mockableLibraryUsed = true; |
| } |
| - return libraryRoot.resolve("lib/$path"); |
| - } |
| - |
| - Uri resolvePatchUri(String dartLibraryPath) { |
| - String patchPath = lookupPatchPath(dartLibraryPath); |
| - if (patchPath == null) return null; |
| - return libraryRoot.resolve(patchPath); |
| + return location; |
| } |
| Uri translatePackageUri(Spannable node, Uri uri) { |
| @@ -420,11 +411,14 @@ class CompilerImpl extends Compiler { |
| Future<elements.LibraryElement> analyzeUri( |
| Uri uri, |
| {bool skipLibraryWithPartOfTag: true}) { |
| + List<Future> setupFunctions = new List<Future>(); |
|
floitsch
2015/10/30 20:43:07
These are not functions.
I find even "setupFutures
sigurdm
2015/11/02 10:06:39
Done.
|
| + if (sdkLibraries == null) { |
| + setupFunctions.add(setupSdk()); |
| + } |
| if (packages == null) { |
| - return setupPackages(uri).then((_) => super.analyzeUri(uri)); |
| + setupFunctions.add(setupPackages(uri)); |
| } |
| - return super.analyzeUri( |
| - uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); |
| + return Future.wait(setupFunctions).then((_) => super.analyzeUri(uri)); |
| } |
| Future setupPackages(Uri uri) { |
| @@ -465,10 +459,24 @@ class CompilerImpl extends Compiler { |
| return new Future.value(); |
| } |
| + Future<Null> setupSdk() { |
| + if (sdkLibraries == null) { |
| + return platform_configuration.load(platformConfigUri, provider) |
| + .then((Map<String, Uri> mapping) { |
| + sdkLibraries = mapping; |
| + }); |
| + } else { |
| + // The incremental compiler sets up the sdk before run. |
| + // Therefore this will be called a second time. |
| + return new Future.value(null); |
| + } |
| + } |
| + |
| Future<bool> run(Uri uri) { |
| - log('Allowed library categories: $allowedLibraryCategories'); |
| + log('Using platform configuration at ${platformConfigUri}'); |
| - return setupPackages(uri).then((_) { |
| + return Future.wait([setupSdk(), setupPackages(uri)]).then((_) { |
| + assert(sdkLibraries != null); |
| assert(packages != null); |
| return super.run(uri).then((bool success) { |
| @@ -559,10 +567,15 @@ class CompilerImpl extends Compiler { |
| } |
| } |
| - |
| fromEnvironment(String name) => environment[name]; |
| - library_info.LibraryInfo lookupLibraryInfo(String libraryName) { |
| - return library_info.libraries[libraryName]; |
| + Uri lookupLibraryUri(String libraryName) { |
| + assert(invariant(NO_LOCATION_SPANNABLE, |
| + sdkLibraries != null, message: "setupSdk() has not been run")); |
| + return sdkLibraries[libraryName]; |
| + } |
| + |
| + Uri resolvePatchUri(String libraryName) { |
| + return backend.resolvePatchUri(libraryName, platformConfigUri); |
| } |
| } |