diff --git a/create_sdk.gyp b/create_sdk.gyp index 769f502e289..749cda561a3 100644 --- a/create_sdk.gyp +++ b/create_sdk.gyp @@ -20,14 +20,15 @@ { 'action_name': 'create_sdk_py', 'inputs': [ - # This is neccessary because we have all the pub test files inside - # the pub directory instead of in tests/pub. Xcode can only handle - # a certain amount of files in one list (also depending on the - # length of the path from where you run). This regexp excludes - # pub/test + # Xcode can only handle a certain amount of files in one list + # (also depending on the length of the path from where you run). ' options; Map environment; bool mockableLibraryUsed = false; - final Set allowedLibraryCategories; + + /// A mapping of the dart: library-names to their location. + /// + /// Initialized in [setupSdk]. + Map 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 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 []; } - static Set getAllowedLibraryCategories( - List options) { - Iterable 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 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 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 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,58 @@ 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 = importingLibrary != null && + (importingLibrary.isPlatformLibrary || + importingLibrary.isPatch || + importingLibrary.canonicalUri.path + .contains('sdk/tests/compiler/dart2js_native')); + + 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 +381,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 +407,14 @@ class CompilerImpl extends Compiler { Future analyzeUri( Uri uri, {bool skipLibraryWithPartOfTag: true}) { - if (packages == null) { - return setupPackages(uri).then((_) => super.analyzeUri(uri)); + List setupFutures = new List(); + if (sdkLibraries == null) { + setupFutures.add(setupSdk()); } - return super.analyzeUri( - uri, skipLibraryWithPartOfTag: skipLibraryWithPartOfTag); + if (packages == null) { + setupFutures.add(setupPackages(uri)); + } + return Future.wait(setupFutures).then((_) => super.analyzeUri(uri)); } Future setupPackages(Uri uri) { @@ -465,10 +455,24 @@ class CompilerImpl extends Compiler { return new Future.value(); } - Future run(Uri uri) { - log('Allowed library categories: $allowedLibraryCategories'); + Future setupSdk() { + if (sdkLibraries == null) { + return platform_configuration.load(platformConfigUri, provider) + .then((Map 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); + } + } - return setupPackages(uri).then((_) { + Future run(Uri uri) { + log('Using platform configuration at ${platformConfigUri}'); + + return Future.wait([setupSdk(), setupPackages(uri)]).then((_) { + assert(sdkLibraries != null); assert(packages != null); return super.run(uri).then((bool success) { @@ -559,10 +563,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); } } diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart index bdfcf79d0ed..04caaf8f47c 100644 --- a/pkg/compiler/lib/src/common/backend_api.dart +++ b/pkg/compiler/lib/src/common/backend_api.dart @@ -412,6 +412,12 @@ abstract class Backend { Element element, CallStructure callStructure, ForeignResolver resolver) {} + + /// Returns the location of the patch-file associated with [libraryName] + /// resolved from [plaformConfigUri]. + /// + /// Returns null if there is none. + Uri resolvePatchUri(String libraryName, Uri plaformConfigUri); } /// Interface for resolving calls to foreign functions. diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart index d07dbd2ac86..271136aa645 100644 --- a/pkg/compiler/lib/src/compiler.dart +++ b/pkg/compiler/lib/src/compiler.dart @@ -929,7 +929,7 @@ abstract class Compiler { } } - /// Analyze all member of the library in [libraryUri]. + /// Analyze all members of the library in [libraryUri]. /// /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the /// library has a `part of` tag, assuming it is a part and not a library. diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart index 5db667a7cec..de758c125cd 100644 --- a/pkg/compiler/lib/src/dart_backend/backend.dart +++ b/pkg/compiler/lib/src/dart_backend/backend.dart @@ -355,6 +355,12 @@ class DartBackend extends Backend { node, MessageKind.DEFERRED_LIBRARY_DART_2_DART); return false; } + + @override + Uri resolvePatchUri(String libraryName, Uri) { + // Dart2dart does not use patches. + return null; + } } class DartImpactTransformer extends ImpactTransformer { diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart index 6236ed0202a..62c863cd519 100644 --- a/pkg/compiler/lib/src/js_backend/backend.dart +++ b/pkg/compiler/lib/src/js_backend/backend.dart @@ -2577,6 +2577,28 @@ class JavaScriptBackend extends Backend { } return rewriter.rewrite(code); } + + /// The locations of js patch-files relative to the sdk-descriptors. + static const _patchLocations = const { + "async": "_internal/js_runtime/lib/async_patch.dart", + "collection": "_internal/js_runtime/lib/collection_patch.dart", + "convert": "_internal/js_runtime/lib/convert_patch.dart", + "core": "_internal/js_runtime/lib/core_patch.dart", + "developer": "_internal/js_runtime/lib/developer_patch.dart", + "io": "_internal/js_runtime/lib/io_patch.dart", + "isolate": "_internal/js_runtime/lib/isolate_patch.dart", + "math": "_internal/js_runtime/lib/math_patch.dart", + "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart", + "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart", + "_internal": "_internal/js_runtime/lib/internal_patch.dart" + }; + + @override + Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { + String patchLocation = _patchLocations[libraryName]; + if (patchLocation == null) return null; + return platformConfigUri.resolve(patchLocation); + } } /// Handling of special annotations for tests. diff --git a/pkg/compiler/lib/src/platform_configuration.dart b/pkg/compiler/lib/src/platform_configuration.dart new file mode 100644 index 00000000000..41da852868b --- /dev/null +++ b/pkg/compiler/lib/src/platform_configuration.dart @@ -0,0 +1,142 @@ +// Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE.md file. + +/// Tools for loading and parsing platform-configuration files. +library plaform_configuration; + +import "dart:async"; +import "package:charcode/ascii.dart"; +import "../compiler_new.dart" as api; + +/// Parses an Ini-like format. +/// +/// Sections are initialized with a name enclosed in brackets. +/// Each section contain zero or more properties of the form "name:value". +/// Empty lines are ignored. +/// Lines starting with # are ignored. +/// Duplicate names are not allowed. +/// All keys and values will be passed through [String.trim]. +/// +/// If an error is found, a [FormatException] is thrown, using [sourceUri] in +/// the error message. +/// +/// Example +/// ``` +/// [a] +/// b:c +/// +/// [d] +/// e:file:///tmp/bla +/// ``` +/// Will parse to {"a": {"b":"c"}, "d": {"e": "file:///tmp/bla"}}. + +Map> parseIni(List source, + {Set allowedSections, Uri sourceUri}) { + int startOfLine = 0; + int currentLine = 0; + + error(String message, int index) { + int column = index - startOfLine + 1; + throw new FormatException( + "$sourceUri:$currentLine:$column: $message", sourceUri, index); + } + + Map> result = + new Map>(); + Map currentSection = null; + + if (source.length == 0) return result; + bool endOfFile = false; + + // Iterate once per $lf in file. + while (!endOfFile) { + currentLine += 1; + int endOfLine = source.indexOf($lf, startOfLine); + if (endOfLine == -1) { + // The dart2js provider adds a final 0 to the file. + endOfLine = source.last == 0 ? source.length - 1 : source.length; + endOfFile = true; + } + if (startOfLine != endOfLine) { + int firstChar = source[startOfLine]; + if (firstChar == $hash) { + // Comment, do nothing. + } else if (firstChar == $open_bracket) { + // Section header + int endOfHeader = source.indexOf($close_bracket, startOfLine); + if (endOfHeader == -1) { + error("'[' must be matched by ']' on the same line.", startOfLine); + } + if (endOfHeader == startOfLine + 1) { + error("Empty header name", startOfLine + 1); + } + if (endOfHeader != endOfLine - 1) { + error("Section heading lines must end with ']'", endOfHeader + 1); + } + int startOfSectionName = startOfLine + 1; + String sectionName = new String.fromCharCodes( + source, startOfSectionName, endOfHeader).trim(); + currentSection = new Map(); + if (result.containsKey(sectionName)) { + error("Duplicate section name '$sectionName'", startOfSectionName); + } + if (allowedSections != null && !allowedSections.contains(sectionName)) { + error("Unrecognized section name '$sectionName'", startOfSectionName); + } + result[sectionName] = currentSection; + } else { + // Property line + if (currentSection == null) { + error("Property outside section", startOfLine); + } + int separator = source.indexOf($colon, startOfLine); + if (separator == startOfLine) { + error("Empty property name", startOfLine); + } + if (separator == -1 || separator > endOfLine) { + error("Property line without ':'", startOfLine); + } + String propertyName = + new String.fromCharCodes(source, startOfLine, separator).trim(); + if (currentSection.containsKey(propertyName)) { + error("Duplicate property name '$propertyName'", startOfLine); + } + String propertyValue = + new String.fromCharCodes(source, separator + 1, endOfLine).trim(); + currentSection[propertyName] = propertyValue; + } + } + startOfLine = endOfLine + 1; + } + return result; +} + +const String librariesSection = "libraries"; +const String dartSpecSection = "dart-spec"; +const String featuresSection = "features"; + +Map libraryMappings( + Map> sections, Uri baseLocation) { + assert(sections.containsKey(librariesSection)); + Map result = new Map(); + sections[librariesSection].forEach((String name, String value) { + result[name] = baseLocation.resolve(value); + }); + return result; +} + +final Set allowedSections = + new Set.from([librariesSection, dartSpecSection, featuresSection]); + +Future> load(Uri location, api.CompilerInput provider) { + return provider.readFromUri(location).then((contents) { + if (contents is String) { + contents = contents.codeUnits; + } + return libraryMappings( + parseIni(contents, + allowedSections: allowedSections, sourceUri: location), + location); + }); +} diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart index 2000b9be843..84b7562fc6c 100644 --- a/pkg/compiler/samples/darttags/darttags.dart +++ b/pkg/compiler/samples/darttags/darttags.dart @@ -87,10 +87,11 @@ main(List arguments) { // Prepend "dart:" to the names. uris.addAll(names.map((String name) => Uri.parse('dart:$name'))); - Uri libraryRoot = myLocation.resolve(SDK_ROOT); + Uri platformConfigUri = myLocation.resolve(SDK_ROOT) + .resolve("lib/dart2js_shared_sdk"); Uri packageRoot = Uri.base.resolve(Platform.packageRoot); - analyze(uris, libraryRoot, packageRoot, handler.provider, handler) + analyze(uris, platformConfigUri, packageRoot, handler.provider, handler) .then(processMirrors); } diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart index e2307dcdd4b..4185df1c46b 100644 --- a/pkg/dart2js_incremental/lib/caching_compiler.dart +++ b/pkg/dart2js_incremental/lib/caching_compiler.dart @@ -76,13 +76,16 @@ Future reuseCompiler( ..needsStructuredMemberInfo = true; Uri core = Uri.parse("dart:core"); - return compiler.libraryLoader.loadLibrary(core).then((_) { - // Likewise, always be prepared for runtimeType support. - // TODO(johnniwinther): Add global switch to force RTI. - compiler.enabledRuntimeType = true; - backend.registerRuntimeType( - compiler.enqueuer.resolution, compiler.globalDependencies); - return compiler; + + return compiler.setupSdk().then((_) { + return compiler.libraryLoader.loadLibrary(core).then((_) { + // Likewise, always be prepared for runtimeType support. + // TODO(johnniwinther): Add global switch to force RTI. + compiler.enabledRuntimeType = true; + backend.registerRuntimeType( + compiler.enqueuer.resolution, compiler.globalDependencies); + return compiler; + }); }); } else { for (final task in compiler.tasks) { diff --git a/pkg/dart2js_incremental/lib/dart2js_incremental.dart b/pkg/dart2js_incremental/lib/dart2js_incremental.dart index a03829defa9..1ce8039c6b6 100644 --- a/pkg/dart2js_incremental/lib/dart2js_incremental.dart +++ b/pkg/dart2js_incremental/lib/dart2js_incremental.dart @@ -124,7 +124,7 @@ class IncrementalCompiler { } Future mappingInputProvider(Uri uri) { Uri updatedFile = updatedFiles[uri]; - return inputProvider(updatedFile == null ? uri : updatedFile); + return inputProvider.readFromUri(updatedFile == null ? uri : updatedFile); } LibraryUpdater updater = new LibraryUpdater( _compiler, @@ -134,7 +134,7 @@ class IncrementalCompiler { _context); _context.registerUriWithUpdates(updatedFiles.keys); Future future = _reuseCompiler(updater.reuseLibrary); - return future.then((Compiler compiler) { + return future.then((CompilerImpl compiler) { _compiler = compiler; if (compiler.compilationFailed) { return null; @@ -157,9 +157,7 @@ function dartMainRunner(main, args) { return main(args); }""", {'updates': updates, 'helper': backend.namer.accessIncrementalHelper}); - jsAst.Printer printer = new jsAst.Printer(_compiler, null); - printer.blockOutWithoutBraces(mainRunner); - return printer.outBuffer.getText(); + return jsAst.prettyPrint(mainRunner, _compiler).getText(); } } diff --git a/sdk/lib/dart2dart.platform b/sdk/lib/dart2dart.platform new file mode 100644 index 00000000000..fd9d8ed0d9d --- /dev/null +++ b/sdk/lib/dart2dart.platform @@ -0,0 +1,48 @@ +# Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +# The platform when compiling with dart2js for dart2dart. +# +# Includes the _mirror_helpers private libraries + +[dart-spec] +spec:3rd edition. + +[features] +# No extra features. + +[libraries] +async: async/async.dart +_chrome: _chrome/dart2js/chrome_dart2js.dart +collection: collection/collection.dart +convert: convert/convert.dart +core: core/core.dart +developer: developer/developer.dart +html: html/dart2js/html_dart2js.dart +html_common: html/html_common/html_common_dart2js.dart +indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart +io: io/io.dart +isolate: isolate/isolate.dart +js: js/dart2js/js_dart2js.dart +math: math/math.dart +mirrors: mirrors/mirrors.dart +nativewrappers: html/dart2js/nativewrappers.dart +typed_data: typed_data/typed_data.dart +_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart +svg: svg/dart2js/svg_dart2js.dart +web_audio: web_audio/dart2js/web_audio_dart2js.dart +web_gl: web_gl/dart2js/web_gl_dart2js.dart +web_sql: web_sql/dart2js/web_sql_dart2js.dart +_internal: internal/internal.dart +_js_helper: _internal/js_runtime/lib/js_helper.dart +_interceptors: _internal/js_runtime/lib/interceptors.dart +_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart +_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart +_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart +_js_names: _internal/js_runtime/lib/js_names.dart +_js_primitives: _internal/js_runtime/lib/js_primitives.dart +_mirror_helper: _internal/js_runtime/lib/mirror_helper.dart +_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart +_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart +_metadata: html/html_common/metadata.dart diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform new file mode 100644 index 00000000000..2e01cd991bc --- /dev/null +++ b/sdk/lib/dart_client.platform @@ -0,0 +1,49 @@ +# Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +# The platform for running dart on the web with dart2js. +# +# Includes dart:html and associated libraries. +# Does not include dart:io. + +[dart-spec] +spec: 3rd edition. + +[features] +# No extra features. + +[libraries] +async: async/async.dart +_chrome: _chrome/dart2js/chrome_dart2js.dart +collection: collection/collection.dart +convert: convert/convert.dart +core: core/core.dart +developer: developer/developer.dart +html: html/dart2js/html_dart2js.dart +html_common: html/html_common/html_common_dart2js.dart +indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart +io: unsupported: +isolate: isolate/isolate.dart +js: js/dart2js/js_dart2js.dart +math: math/math.dart +mirrors: mirrors/mirrors.dart +nativewrappers: html/dart2js/nativewrappers.dart +typed_data: typed_data/typed_data.dart +_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart +svg: svg/dart2js/svg_dart2js.dart +web_audio: web_audio/dart2js/web_audio_dart2js.dart +web_gl: web_gl/dart2js/web_gl_dart2js.dart +web_sql: web_sql/dart2js/web_sql_dart2js.dart +_internal: internal/internal.dart +_js_helper: _internal/js_runtime/lib/js_helper.dart +_interceptors: _internal/js_runtime/lib/interceptors.dart +_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart +_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart +_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart +_js_names: _internal/js_runtime/lib/js_names.dart +_js_primitives: _internal/js_runtime/lib/js_primitives.dart +_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart +_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart +_metadata: html/html_common/metadata.dart +_mirror_helper: unsupported: diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform new file mode 100644 index 00000000000..821a1753ac6 --- /dev/null +++ b/sdk/lib/dart_server.platform @@ -0,0 +1,49 @@ +# Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +# The platform for dart on the server with dart2js. +# +# Includes dart:io. +# Does not include dart:html and associated libraries. + +[dart-spec] +spec:3rd edition. + +[features] +# No extra features. + +[libraries] +async: async/async.dart +collection: collection/collection.dart +convert: convert/convert.dart +core: core/core.dart +developer: developer/developer.dart +io: io/io.dart +isolate: isolate/isolate.dart +math: math/math.dart +mirrors: mirrors/mirrors.dart +nativewrappers: html/dart2js/nativewrappers.dart +typed_data: typed_data/typed_data.dart +_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart +html: unsupported: +html_common: unsupported: +indexed_db: unsupported: +svg: unsupported: +web_audio: unsupported: +web_gl: unsupported: +web_sql: unsupported: +_chrome: unsupported: +js: unsupported: +_mirror_helper: unsupported: +_internal: internal/internal.dart +_js_helper: _internal/js_runtime/lib/js_helper.dart +_interceptors: _internal/js_runtime/lib/interceptors.dart +_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart +_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart +_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart +_js_names: _internal/js_runtime/lib/js_names.dart +_js_primitives: _internal/js_runtime/lib/js_primitives.dart +_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart +_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart +_metadata: html/html_common/metadata.dart diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform new file mode 100644 index 00000000000..539b8688966 --- /dev/null +++ b/sdk/lib/dart_shared.platform @@ -0,0 +1,47 @@ +# Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +# A combination of the libraries for dart on the server and client. +# For testing purposes only. + +[dart-spec] +spec:3rd edition. + +[features] +# No extra features. + +[libraries] +async: async/async.dart +_chrome: _chrome/dart2js/chrome_dart2js.dart +collection: collection/collection.dart +convert: convert/convert.dart +core: core/core.dart +developer: developer/developer.dart +html: html/dart2js/html_dart2js.dart +html_common: html/html_common/html_common_dart2js.dart +indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart +io: io/io.dart +isolate: isolate/isolate.dart +js: js/dart2js/js_dart2js.dart +math: math/math.dart +mirrors: mirrors/mirrors.dart +nativewrappers: html/dart2js/nativewrappers.dart +typed_data: typed_data/typed_data.dart +_native_typed_data: _internal/js_runtime/lib/native_typed_data.dart +svg: svg/dart2js/svg_dart2js.dart +web_audio: web_audio/dart2js/web_audio_dart2js.dart +web_gl: web_gl/dart2js/web_gl_dart2js.dart +web_sql: web_sql/dart2js/web_sql_dart2js.dart +_internal: internal/internal.dart +_js_helper: _internal/js_runtime/lib/js_helper.dart +_interceptors: _internal/js_runtime/lib/interceptors.dart +_foreign_helper: _internal/js_runtime/lib/foreign_helper.dart +_isolate_helper: _internal/js_runtime/lib/isolate_helper.dart +_js_mirrors: _internal/js_runtime/lib/js_mirrors.dart +_js_names: _internal/js_runtime/lib/js_names.dart +_js_primitives: _internal/js_runtime/lib/js_primitives.dart +_js_embedded_names: _internal/js_runtime/lib/shared/embedded_names.dart +_async_await_error_codes: _internal/js_runtime/lib/shared/async_await_error_codes.dart +_metadata: html/html_common/metadata.dart +_mirror_helper: unsupported: diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart index 08100a62d39..2d771fb5349 100644 --- a/tests/compiler/dart2js/analyze_only_test.dart +++ b/tests/compiler/dart2js/analyze_only_test.dart @@ -49,8 +49,8 @@ runCompiler(String main, List options, localProvider, localHandler, options, outputCollector); result.then((_) { onValue(outputCollector.getOutput('', 'js'), errors, warnings); - }, onError: (e) { - throw 'Compilation failed: ${Error.safeToString(e)}'; + }, onError: (e, st) { + throw 'Compilation failed: ${e} ${st}'; }).then(asyncSuccess).catchError((error, stack) { print('\n\n-----------------------------------------------'); print('main source:\n$main'); diff --git a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart index 597f056807c..5db41609dec 100644 --- a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart +++ b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart @@ -4,6 +4,7 @@ import "package:expect/expect.dart"; import 'dart:async'; +import 'dart:io' as io; import "package:async_helper/async_helper.dart"; import '../mock_compiler.dart'; import '../mock_libraries.dart'; @@ -58,7 +59,9 @@ testDart2Dart(String mainSrc, {String librarySrc, if (uri.toString() == libUri.toString()) { return new Future.value(librarySrc); } - if (uri.path.endsWith('/core.dart')) { + if (uri.path.endsWith('/dart2dart.platform')) { + return new io.File.fromUri(uri).readAsBytes(); + } else if (uri.path.endsWith('/core.dart')) { return new Future.value(buildLibrarySource(DEFAULT_CORE_LIBRARY)); } else if (uri.path.endsWith('/core_patch.dart')) { return new Future.value(DEFAULT_PATCH_CORE_SOURCE); @@ -87,7 +90,6 @@ testDart2Dart(String mainSrc, {String librarySrc, final options = ['--output-type=dart']; // Some tests below are using dart:io. - options.add('--categories=Client,Server'); if (minify) options.add('--minify'); if (stripTypes) options.add('--force-strip=types'); @@ -95,7 +97,7 @@ testDart2Dart(String mainSrc, {String librarySrc, OutputCollector outputCollector = new OutputCollector(); return compile( scriptUri, - fileUri('libraryRoot/'), + Uri.base.resolve('sdk/'), fileUri('packageRoot/'), provider, handler, diff --git a/tests/compiler/dart2js/categories_test.dart b/tests/compiler/dart2js/categories_test.dart index 3b22453112c..677d1a83a60 100644 --- a/tests/compiler/dart2js/categories_test.dart +++ b/tests/compiler/dart2js/categories_test.dart @@ -19,17 +19,13 @@ runTest(String source, String categories, int expectedErrors) async { void main() { asyncTest(() async { - await runTest("import 'dart:async'; main() {}", "Embedded", 1); await runTest("import 'dart:async'; main() {}", "Client", 0); await runTest("import 'dart:async'; main() {}", "Server", 0); - await runTest("import 'dart:html'; main() {}", "Embedded", 1); await runTest("import 'dart:html'; main() {}", "Client", 0); await runTest("import 'dart:html'; main() {}", "Server", 1); - await runTest("import 'dart:io'; main() {}", "Embedded", 1); await runTest("import 'dart:io'; main() {}", "Client", 1); await runTest("import 'dart:io'; main() {}", "Server", 0); - await runTest("import 'dart:_internal'; main() {}", "Embedded", 2); - await runTest("import 'dart:_internal'; main() {}", "Client", 2); - await runTest("import 'dart:_internal'; main() {}", "Server", 2); + await runTest("import 'dart:_internal'; main() {}", "Client", 1); + await runTest("import 'dart:_internal'; main() {}", "Server", 1); }); } diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart index d45431236d5..28ad567248c 100644 --- a/tests/compiler/dart2js/library_resolution_test.dart +++ b/tests/compiler/dart2js/library_resolution_test.dart @@ -14,92 +14,58 @@ import "memory_source_file_helper.dart"; import "package:async_helper/async_helper.dart"; -import 'package:expect/expect.dart' show - Expect; +import 'package:expect/expect.dart' show Expect; -import 'package:compiler/src/diagnostics/messages.dart' show - MessageKind, - MessageTemplate; +import 'package:compiler/src/diagnostics/messages.dart' + show MessageKind, MessageTemplate; -import 'package:compiler/src/elements/elements.dart' show - LibraryElement; +import 'package:compiler/src/elements/elements.dart' show LibraryElement; -import 'package:compiler/src/null_compiler_output.dart' show - NullCompilerOutput; +import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput; -import 'package:compiler/src/old_to_new_api.dart' show - LegacyCompilerDiagnostics, - LegacyCompilerInput; - -import 'package:sdk_library_metadata/libraries.dart' show - DART2JS_PLATFORM, - LibraryInfo; - -const LibraryInfo mock1LibraryInfo = const LibraryInfo( - "mock1.dart", - categories: "Client,Embedded", - documented: false, - platforms: DART2JS_PLATFORM); - -const LibraryInfo mock2LibraryInfo = const LibraryInfo( - "mock2.dart", - categories: "Client,Embedded", - documented: false, - platforms: DART2JS_PLATFORM); +import 'package:compiler/src/old_to_new_api.dart' + show LegacyCompilerDiagnostics, LegacyCompilerInput; +Uri sdkRoot = Uri.base.resolve("sdk/"); +Uri mock1LibraryUri = sdkRoot.resolve("lib/mock1.dart"); +Uri mock2LibraryUri = sdkRoot.resolve("lib/mock2.dart"); class CustomCompiler extends CompilerImpl { - final Map customLibraryInfo; + CustomCompiler(provider, handler, libraryRoot, + packageRoot, options, environment) + : super(provider, const NullCompilerOutput(), handler, libraryRoot, + packageRoot, options, environment); - CustomCompiler( - this.customLibraryInfo, - provider, - handler, - libraryRoot, - packageRoot, - options, - environment) - : super( - provider, - const NullCompilerOutput(), - handler, - libraryRoot, - packageRoot, - options, - environment); - - LibraryInfo lookupLibraryInfo(String name) { - if (name == "m_o_c_k_1") return mock1LibraryInfo; - if (name == "m_o_c_k_2") return mock2LibraryInfo; - return super.lookupLibraryInfo(name); + Uri lookupLibraryUri(String libraryName) { + if (libraryName == "m_o_c_k_1") return mock1LibraryUri; + if (libraryName == "m_o_c_k_2") return mock2LibraryUri; + return super.lookupLibraryUri(libraryName); } } -main() { - Uri sdkRoot = Uri.base.resolve("sdk/"); +main() async { Uri packageRoot = Uri.base.resolve(Platform.packageRoot); var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES); var handler = new FormattingDiagnosticHandler(provider); Future wrappedProvider(Uri uri) { - if (uri == sdkRoot.resolve('lib/mock1.dart')) { + if (uri == mock1LibraryUri) { return provider.readStringFromUri(Uri.parse('memory:mock1.dart')); } - if (uri == sdkRoot.resolve('lib/mock2.dart')) { + if (uri == mock2LibraryUri) { return provider.readStringFromUri(Uri.parse('memory:mock2.dart')); } return provider.readStringFromUri(uri); } - String expectedMessage = - MessageTemplate.TEMPLATES[MessageKind.LIBRARY_NOT_FOUND].message( - {'resolvedUri': 'dart:mock2.dart'}).computeMessage(); + String expectedMessage = MessageTemplate.TEMPLATES[ + MessageKind.LIBRARY_NOT_FOUND] + .message({'resolvedUri': 'dart:mock2.dart'}).computeMessage(); int actualMessageCount = 0; - wrappedHandler( - Uri uri, int begin, int end, String message, kind) { + wrappedHandler(Uri uri, int begin, int end, String message, kind) { if (message == expectedMessage) { actualMessageCount++; } else { @@ -112,7 +78,6 @@ main() { } CompilerImpl compiler = new CustomCompiler( - {}, new LegacyCompilerInput(wrappedProvider), new LegacyCompilerDiagnostics(wrappedHandler), sdkRoot, @@ -121,9 +86,11 @@ main() { {}); asyncStart(); - compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1")) - .then(checkLibrary) - .then(asyncSuccess); + await compiler.setupSdk(); + var library = + await compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1")); + await checkLibrary(library); + asyncSuccess(null); } const Map MEMORY_SOURCE_FILES = const { diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart index 37135b2274d..e73586c0cc0 100644 --- a/tests/compiler/dart2js/mock_libraries.dart +++ b/tests/compiler/dart2js/mock_libraries.dart @@ -6,6 +6,15 @@ library mock_libraries; +const DEFAULT_PLATFORM_CONFIG = """ +[libraries] +core:core/core.dart +async:async/async.dart +_js_helper:_internal/js_runtime/lib/js_helper.dart +_interceptors:_internal/js_runtime/lib/interceptors.dart +_isolate_helper:_internal/js_runtime/lib/isolate_helper.dart +"""; + String buildLibrarySource( Map elementMap, [Map additionalElementMap = const {}]) { diff --git a/tests/compiler/dart2js/platform_config_parser_test.dart b/tests/compiler/dart2js/platform_config_parser_test.dart new file mode 100644 index 00000000000..a25e2da1d6c --- /dev/null +++ b/tests/compiler/dart2js/platform_config_parser_test.dart @@ -0,0 +1,130 @@ +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import "package:compiler/src/platform_configuration.dart"; +import "package:expect/expect.dart"; + +/// Runs the parser on [input] and compares it with [expectedResult] +/// +/// A '*' in [input] indicates that the parser will report an error at the +/// given point (On [input] with the "*" removed). +test(String input, [Map> expectedOutput]) { + int starIndex = input.indexOf("*"); + String inputWithoutStar = input.replaceFirst("*", ""); + + parse() => parseIni(inputWithoutStar.codeUnits, + allowedSections: new Set.from(["AA", "BB"])); + + if (starIndex != -1) { + Expect.equals(expectedOutput, null); + Expect.throws(parse, (e) { + Expect.isTrue(e is FormatException); + Expect.equals(starIndex, e.offset); + return e is FormatException; + }); + } else { + Map> result = parse(); + Expect.equals(expectedOutput.length, result.length); + expectedOutput.forEach((String name, Map properties) { + Expect.isTrue(expectedOutput.containsKey(name), "Missing section $name"); + Expect.mapEquals(expectedOutput[name], properties); + }); + } +} + +main() { + // Empty file. + test( + """ +# Nothing here +""", + {}); + + // Text outside section. + test(""" +*aaa +"""); + + // Malformed header. + test(""" +*[AABC +name:value +"""); + + // Text after header. + test(""" +[AABC]*abcde +"""); + + // Empty section name. + test(""" +[*] +"""); + + // Duplicate section name. + test(""" +[AA] +[BB] +[*AA] +"""); + + // Unrecognized section name. + test(""" +[*CC] +"""); + + // Empty property name. + test(""" +[AA] +*:value +name:value +"""); + + // Ok. + test( + """ +[AA] +name:value +[BB] +name:value +name2:value2 +""", + { + "AA": {"name": "value"}, + "BB": {"name": "value", "name2": "value2"} + }); + + // Ok, file not ending in newline. + test( + """ +[AA] +name:value""", + { + "A": {"name": "value"} + }); + + // Ok, whitespace is trimmed away. + test( + """ +[ AA ] + name\t: value """, + { + "A": {"name": "value"} + }); + + // Duplicate property name. + test(""" +[AA] +a:b +b:c +*a:c +"""); + + // No ':' on property line. + test(""" +[AA] +*name1 +name2:value +"""); +} diff --git a/tests/compiler/dart2js/platform_consistency_test.dart b/tests/compiler/dart2js/platform_consistency_test.dart new file mode 100644 index 00000000000..e946c167e29 --- /dev/null +++ b/tests/compiler/dart2js/platform_consistency_test.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2015, the Fletch project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE.md file. + +import "package:compiler/src/platform_configuration.dart"; +import "package:compiler/src/source_file_provider.dart"; +import "package:compiler/compiler_new.dart"; +import "package:expect/expect.dart"; + +Uri unsupported = Uri.parse("unsupported:"); + +main() async { + CompilerInput input = new CompilerSourceFileProvider(); + Map client = await load( + Uri.base.resolve("sdk/lib/dart_client.platform"), + input); + Map server = await load( + Uri.base.resolve("sdk/lib/dart_server.platform"), + input); + Map shared = await load( + Uri.base.resolve("sdk/lib/dart_shared.platform"), + input); + Map dart2dart = await load( + Uri.base.resolve("sdk/lib/dart2dart.platform"), + input); + Expect.setEquals(new Set.from(shared.keys), new Set.from(client.keys)); + Expect.setEquals(new Set.from(shared.keys), new Set.from(server.keys)); + Expect.setEquals(new Set.from(shared.keys), new Set.from(dart2dart.keys)); + + for (String libraryName in shared.keys) { + test(Map m) { + if (m[libraryName] != unsupported && + shared[libraryName] != unsupported) { + Expect.equals(shared[libraryName], m[libraryName]); + } + } + test(client); + test(server); + test(dart2dart); + } + } diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart index 43a79c58c51..608e0996686 100644 --- a/tests/utils/dummy_compiler_test.dart +++ b/tests/utils/dummy_compiler_test.dart @@ -15,7 +15,9 @@ import 'package:compiler/compiler.dart'; import '../compiler/dart2js/mock_libraries.dart'; String libProvider(Uri uri) { - if (uri.path.endsWith("/core.dart")) { + if (uri.path.endsWith(".platform")) { + return DEFAULT_PLATFORM_CONFIG; + } if (uri.path.endsWith("/core.dart")) { return buildLibrarySource(DEFAULT_CORE_LIBRARY); } else if (uri.path.endsWith('core_patch.dart')) { return DEFAULT_PATCH_CORE_SOURCE; diff --git a/tools/create_sdk.py b/tools/create_sdk.py index bdb69f237ef..11ff386ae83 100755 --- a/tools/create_sdk.py +++ b/tools/create_sdk.py @@ -39,6 +39,10 @@ # ......dart_native_api.h # ......dart_tools_api.h # ....lib/ +# ......dart_client.platform +# ......dart_server.platform +# ......dart_shared.platform +# ......dart2dart.platform # ......_internal/ # ......async/ # ......collection/ @@ -241,6 +245,13 @@ def Main(): ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh', '.gitignore')) + # Copy the platform descriptors. + for file_name in ["dart_client.platform", + "dart_server.platform", + "dart_shared.platform", + "dart2dart.platform"]: + copyfile(join(HOME, 'sdk', 'lib', file_name), join(LIB, file_name)); + # Copy libraries.dart to lib/_internal/libraries.dart for backwards # compatibility. #