| // Copyright (c) 2017, 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. |
| |
| /// Common compiler options and helper functions used for testing. |
| library front_end.testing.compiler_options_common; |
| |
| import 'dart:async' show Future; |
| |
| import 'package:kernel/ast.dart' show Library, Component; |
| |
| import '../api_prototype/front_end.dart' |
| show CompilerOptions, kernelForComponent, kernelForProgram, summaryFor; |
| |
| import '../api_prototype/memory_file_system.dart' show MemoryFileSystem; |
| |
| import '../compute_platform_binaries_location.dart' |
| show computePlatformBinariesLocation; |
| |
| import '../testing/hybrid_file_system.dart' show HybridFileSystem; |
| |
| /// Generate kernel for a script. |
| /// |
| /// [scriptOrSources] can be a String, in which case it is the script to be |
| /// compiled, or a Map containing source files. In which case, this function |
| /// compiles the entry whose name is [fileName]. |
| /// |
| /// Wraps [kernelForProgram] with some default testing options (see [setup]). |
| Future<Component> compileScript(dynamic scriptOrSources, |
| {fileName: 'main.dart', |
| List<String> inputSummaries: const [], |
| List<String> linkedDependencies: const [], |
| CompilerOptions options}) async { |
| options ??= new CompilerOptions(); |
| Map<String, dynamic> sources; |
| if (scriptOrSources is String) { |
| sources = {fileName: scriptOrSources}; |
| } else { |
| assert(scriptOrSources is Map); |
| sources = scriptOrSources; |
| } |
| await setup(options, sources, |
| inputSummaries: inputSummaries, linkedDependencies: linkedDependencies); |
| return await kernelForProgram(toTestUri(fileName), options); |
| } |
| |
| /// Generate a component for a modular complation unit. |
| /// |
| /// Wraps [kernelForComponent] with some default testing options (see [setup]). |
| Future<Component> compileUnit(List<String> inputs, Map<String, dynamic> sources, |
| {List<String> inputSummaries: const [], |
| List<String> linkedDependencies: const [], |
| CompilerOptions options}) async { |
| options ??= new CompilerOptions(); |
| await setup(options, sources, |
| inputSummaries: inputSummaries, linkedDependencies: linkedDependencies); |
| return await kernelForComponent(inputs.map(toTestUri).toList(), options); |
| } |
| |
| /// Generate a summary for a modular complation unit. |
| /// |
| /// Wraps [summaryFor] with some default testing options (see [setup]). |
| Future<List<int>> summarize(List<String> inputs, Map<String, dynamic> sources, |
| {List<String> inputSummaries: const [], |
| CompilerOptions options, |
| bool truncate: false}) async { |
| options ??= new CompilerOptions(); |
| await setup(options, sources, inputSummaries: inputSummaries); |
| return await summaryFor(inputs.map(toTestUri).toList(), options, |
| truncate: truncate); |
| } |
| |
| /// Defines a default set of options for testing: |
| /// |
| /// * create a hybrid file system that stores [sources] in memory but allows |
| /// access to the physical file system to load the SDK. [sources] can |
| /// contain either source files (value is [String]) or .dill files (value |
| /// is [List<int>]). |
| /// |
| /// * define an empty .packages file |
| /// |
| /// * specify the location of the sdk summaries. |
| Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources, |
| {List<String> inputSummaries: const [], |
| List<String> linkedDependencies: const []}) async { |
| var fs = new MemoryFileSystem(_defaultDir); |
| sources.forEach((name, data) { |
| var entity = fs.entityForUri(toTestUri(name)); |
| if (data is String) { |
| entity.writeAsStringSync(data); |
| } else { |
| entity.writeAsBytesSync(data); |
| } |
| }); |
| fs.entityForUri(toTestUri('.packages')).writeAsStringSync(''); |
| fs |
| .entityForUri(invalidCoreLibsSpecUri) |
| .writeAsStringSync(_invalidLibrariesSpec); |
| options |
| ..verify = true |
| ..fileSystem = new HybridFileSystem(fs) |
| ..inputSummaries = inputSummaries.map(toTestUri).toList() |
| ..linkedDependencies = linkedDependencies.map(toTestUri).toList() |
| ..packagesFileUri = toTestUri('.packages'); |
| |
| if (options.sdkSummary == null) { |
| options.sdkRoot = computePlatformBinariesLocation(); |
| } |
| } |
| |
| /// A fake absolute directory used as the root of a memory-file system in the |
| /// helpers above. |
| Uri _defaultDir = Uri.parse('org-dartlang-test:///a/b/c/'); |
| |
| /// Convert relative file paths into an absolute Uri as expected by the test |
| /// helpers above. |
| Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath); |
| |
| /// Uri to a libraries specification file that purposely provides |
| /// invalid Uris to dart:core and dart:async. Used by tests that want to ensure |
| /// that the sdk libraries are not loaded from sources, but read from a .dill |
| /// file. |
| Uri invalidCoreLibsSpecUri = toTestUri('invalid_sdk_libraries.json'); |
| |
| String _invalidLibrariesSpec = ''' |
| { |
| "vm": { |
| "libraries": { |
| "core": {"uri": "/non_existing_file/core.dart"}, |
| "async": {"uri": "/non_existing_file/async.dart"} |
| } |
| } |
| } |
| '''; |
| |
| bool isDartCoreLibrary(Library lib) => isDartCore(lib.importUri); |
| bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core'; |
| |
| /// Find a library in [component] whose Uri ends with the given [suffix] |
| Library findLibrary(Component component, String suffix) { |
| return component.libraries |
| .firstWhere((lib) => lib.importUri.path.endsWith(suffix)); |
| } |