mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 12:13:01 +00:00
Switch FE to use the libraries.json format.
This CL:
* introduces the Dart API to operate over libraries specifications and describes
the format we intend to use (see libraries_spec.dart)
* implements serialization/deserialization for this API
* switches over the front_end to use these APIs
* public options accept a URI to the JSON file and no longer
accept a `dartLibraries` map
* internal code uses the LibrariesSpecification API
* switches other dependencies on these APIs (resynthesizer_test and patch_sdk.dart)
This is the first step in migrating over to use the libraries.json format and
eventually remove the patched_sdk step. In particular, some of the next steps
include:
* add a build step to generate .json files from .yaml files
* add a libraries.yaml file for the sdk
* split the patched_sdk step in two:
* patching files
* generating .dill files
* add any missing support for patch-files in fasta
* finally remove the patching files step, and only have a build step for generating
.dill files
BUG=
R=ahe@google.com, paulberry@google.com, scheglov@google.com
Committed: abf2d23af2
Review-Url: https://codereview.chromium.org/2986303003 .
This commit is contained in:
parent
dbe482caac
commit
b48584d3d0
|
@ -15,6 +15,7 @@ import 'package:analyzer/src/summary/resynthesize.dart';
|
||||||
import 'package:front_end/compiler_options.dart';
|
import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/file_system.dart';
|
import 'package:front_end/file_system.dart';
|
||||||
import 'package:front_end/src/base/performace_logger.dart';
|
import 'package:front_end/src/base/performace_logger.dart';
|
||||||
|
import 'package:front_end/src/base/libraries_specification.dart';
|
||||||
import 'package:front_end/src/base/processed_options.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
||||||
import 'package:front_end/src/incremental/byte_store.dart';
|
import 'package:front_end/src/incremental/byte_store.dart';
|
||||||
|
@ -74,13 +75,16 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
|
||||||
Uri testUri = testFile.toUri();
|
Uri testUri = testFile.toUri();
|
||||||
String testUriStr = testUri.toString();
|
String testUriStr = testUri.toString();
|
||||||
|
|
||||||
Map<String, Uri> dartLibraries = {};
|
Map<String, LibraryInfo> dartLibraries = {};
|
||||||
MockSdk.FULL_URI_MAP.forEach((dartUri, path) {
|
MockSdk.FULL_URI_MAP.forEach((dartUri, path) {
|
||||||
dartLibraries[Uri.parse(dartUri).path] = Uri.parse('file://$path');
|
var name = Uri.parse(dartUri).path;
|
||||||
|
dartLibraries[name] =
|
||||||
|
new LibraryInfo(name, Uri.parse('file://$path'), const []);
|
||||||
});
|
});
|
||||||
|
|
||||||
var uriTranslator =
|
var uriTranslator = new UriTranslatorImpl(
|
||||||
new UriTranslatorImpl(dartLibraries, {}, Packages.noPackages);
|
new TargetLibrariesSpecification('none', dartLibraries),
|
||||||
|
Packages.noPackages);
|
||||||
var options = new ProcessedOptions(new CompilerOptions()
|
var options = new ProcessedOptions(new CompilerOptions()
|
||||||
..target = new NoneTarget(new TargetFlags(strongMode: isStrongMode))
|
..target = new NoneTarget(new TargetFlags(strongMode: isStrongMode))
|
||||||
..reportMessages = false
|
..reportMessages = false
|
||||||
|
|
|
@ -858,7 +858,6 @@ class KernelLibraryLoaderTask extends CompilerTask
|
||||||
var options = new fe.CompilerOptions()
|
var options = new fe.CompilerOptions()
|
||||||
..fileSystem = new CompilerFileSystem(compilerInput)
|
..fileSystem = new CompilerFileSystem(compilerInput)
|
||||||
..target = new Dart2jsTarget(new TargetFlags())
|
..target = new Dart2jsTarget(new TargetFlags())
|
||||||
..compileSdk = true
|
|
||||||
..linkedDependencies = [
|
..linkedDependencies = [
|
||||||
sdkRoot.resolve('_internal/dart2js_platform.dill')
|
sdkRoot.resolve('_internal/dart2js_platform.dill')
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,7 +9,6 @@ library front_end.example.incremental_reload.compiler_with_invalidation;
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert' show JSON;
|
|
||||||
|
|
||||||
import 'package:front_end/compiler_options.dart';
|
import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/incremental_kernel_generator.dart';
|
import 'package:front_end/incremental_kernel_generator.dart';
|
||||||
|
@ -33,7 +32,6 @@ Future<IncrementalCompiler> createIncrementalCompiler(String entry,
|
||||||
..sdkRoot = sdkRoot
|
..sdkRoot = sdkRoot
|
||||||
..packagesFileUri = Uri.base.resolve('.packages')
|
..packagesFileUri = Uri.base.resolve('.packages')
|
||||||
..strongMode = false
|
..strongMode = false
|
||||||
..dartLibraries = loadDartLibraries(sdkRoot)
|
|
||||||
// Note: we do not report error on the console because the incremental
|
// Note: we do not report error on the console because the incremental
|
||||||
// compiler is an ongoing background service that shouldn't polute stdout.
|
// compiler is an ongoing background service that shouldn't polute stdout.
|
||||||
// TODO(sigmund): do something with the errors.
|
// TODO(sigmund): do something with the errors.
|
||||||
|
@ -43,18 +41,6 @@ Future<IncrementalCompiler> createIncrementalCompiler(String entry,
|
||||||
return IncrementalCompiler.create(options, entryUri);
|
return IncrementalCompiler.create(options, entryUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads the `libraries.json` file for an SDK to provide the location of the
|
|
||||||
/// SDK files.
|
|
||||||
// TODO(sigmund): this should be handled by package:front_end internally.
|
|
||||||
Map<String, Uri> loadDartLibraries(Uri sdkRoot) {
|
|
||||||
var libraries = sdkRoot.resolve('lib/libraries.json');
|
|
||||||
var map =
|
|
||||||
JSON.decode(new File.fromUri(libraries).readAsStringSync())['libraries'];
|
|
||||||
var dartLibraries = <String, Uri>{};
|
|
||||||
map.forEach((k, v) => dartLibraries[k] = libraries.resolve(v));
|
|
||||||
return dartLibraries;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An incremental compiler that monitors file modifications on disk and
|
/// An incremental compiler that monitors file modifications on disk and
|
||||||
/// invalidates only files that have been modified since the previous time the
|
/// invalidates only files that have been modified since the previous time the
|
||||||
/// compiler was invoked.
|
/// compiler was invoked.
|
||||||
|
|
|
@ -25,18 +25,17 @@ class CompilerOptions {
|
||||||
/// [Platform.resolvedExecutable] as a starting point.
|
/// [Platform.resolvedExecutable] as a starting point.
|
||||||
Uri sdkRoot;
|
Uri sdkRoot;
|
||||||
|
|
||||||
/// Map of `dart:*` libraries to URIs in the [fileSystem].
|
/// Uri to a platform libraries specification file.
|
||||||
///
|
///
|
||||||
/// Keys in the map are the name of the library with no `dart:` prefix, for
|
/// A libraries specification file is a JSON file that describes how to map
|
||||||
/// example:
|
/// `dart:*` libraries to URIs in the underlying [fileSystem]. See
|
||||||
|
/// `package:front_end/src/base/libraries_specification.dart` for details on
|
||||||
|
/// the format.
|
||||||
///
|
///
|
||||||
/// {'core': 'file:///sdk/lib/core/core.dart'}
|
/// If a value is not specified and `compileSdk = true`, the compiler will
|
||||||
///
|
/// infer at a default location under [sdkRoot], typically under
|
||||||
/// If `null`, the default set of libraries will be loaded from
|
/// `lib/libraries.json`.
|
||||||
/// `sdkRoot/lib/libraries.json`.
|
Uri librariesSpecificationUri;
|
||||||
// TODO(sigmund): also provide an option to specify the .json file, then
|
|
||||||
// consider dropping this option.
|
|
||||||
Map<String, Uri> dartLibraries;
|
|
||||||
|
|
||||||
/// Callback to which compilation errors should be delivered.
|
/// Callback to which compilation errors should be delivered.
|
||||||
///
|
///
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:front_end/src/base/processed_options.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/incremental_kernel_generator_impl.dart';
|
import 'package:front_end/src/incremental_kernel_generator_impl.dart';
|
||||||
|
import 'package:front_end/src/fasta/compiler_context.dart';
|
||||||
import 'package:kernel/kernel.dart';
|
import 'package:kernel/kernel.dart';
|
||||||
|
|
||||||
import 'compiler_options.dart';
|
import 'compiler_options.dart';
|
||||||
|
@ -100,9 +101,11 @@ abstract class IncrementalKernelGenerator {
|
||||||
CompilerOptions options, Uri entryPoint,
|
CompilerOptions options, Uri entryPoint,
|
||||||
{WatchUsedFilesFn watch}) async {
|
{WatchUsedFilesFn watch}) async {
|
||||||
var processedOptions = new ProcessedOptions(options, false, [entryPoint]);
|
var processedOptions = new ProcessedOptions(options, false, [entryPoint]);
|
||||||
var uriTranslator = await processedOptions.getUriTranslator();
|
return await CompilerContext.runWithOptions(processedOptions, (_) async {
|
||||||
return new IncrementalKernelGeneratorImpl(
|
var uriTranslator = await processedOptions.getUriTranslator();
|
||||||
processedOptions, uriTranslator, entryPoint,
|
return new IncrementalKernelGeneratorImpl(
|
||||||
watch: watch);
|
processedOptions, uriTranslator, entryPoint,
|
||||||
|
watch: watch);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
221
pkg/front_end/lib/src/base/libraries_specification.dart
Normal file
221
pkg/front_end/lib/src/base/libraries_specification.dart
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
/// Library specification in-memory representation.
|
||||||
|
///
|
||||||
|
/// Many dart tools are configurable to support different target platforms. For
|
||||||
|
/// a given target, they need to know what libraries are available and where are
|
||||||
|
/// the sources and target-specific patches.
|
||||||
|
///
|
||||||
|
/// Here we define APIs to represent this specification and implement
|
||||||
|
/// serialization to (and deserialization from) a JSON file.
|
||||||
|
///
|
||||||
|
/// Here is an example specification JSON file:
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// "vm": {
|
||||||
|
/// "libraries": {
|
||||||
|
/// "core": {
|
||||||
|
/// "uri": "async/core.dart",
|
||||||
|
/// "patches": [
|
||||||
|
/// "path/to/core_patch.dart",
|
||||||
|
/// "path/to/list_patch.dart"
|
||||||
|
/// ]
|
||||||
|
/// }
|
||||||
|
/// "async": {
|
||||||
|
/// "uri": "async/async.dart",
|
||||||
|
/// "patches": "path/to/async_patch.dart"
|
||||||
|
/// }
|
||||||
|
/// "convert": {
|
||||||
|
/// "uri": "convert/convert.dart",
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// The format contains:
|
||||||
|
/// - a top level entry for each target. Keys are target names (e.g. "vm"
|
||||||
|
/// above), and values contain the entire specification of a target.
|
||||||
|
///
|
||||||
|
/// - each target specification is a map. Today only one key ("libraries") is
|
||||||
|
/// supported, but this may be extended in the future to add more
|
||||||
|
/// information on each target.
|
||||||
|
///
|
||||||
|
/// - The "libraries" entry contains details for how each platform library is
|
||||||
|
/// implemented. The entry is a map, where keys are the name of the platform
|
||||||
|
/// library and values contain details for where to find the implementation
|
||||||
|
/// fo that library.
|
||||||
|
///
|
||||||
|
/// - The name of the library is a single token (e.g. "core") that matches the
|
||||||
|
/// Uri path used after `dart:` (e.g. "dart:core").
|
||||||
|
///
|
||||||
|
/// - The "uri" entry on the library information is mandatory. The value is a
|
||||||
|
/// string URI reference. The "patches" entry is optional and may have as a
|
||||||
|
/// value a string URI reference or a list of URI references.
|
||||||
|
///
|
||||||
|
/// All URI references can either be a file URI or a relative URI path,
|
||||||
|
/// which will be resolved relative to the location of the library
|
||||||
|
/// specification file.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// Note: we currently have several different files that need to be updated
|
||||||
|
/// when changing libraries, sources, and patch files:
|
||||||
|
/// * .platform files (for dart2js)
|
||||||
|
/// * .gypi files (for vm)
|
||||||
|
/// * sdk_library_metadata/lib/libraries.dart (for analyzer, ddc)
|
||||||
|
///
|
||||||
|
/// we are in the process of unifying them all under this format (see
|
||||||
|
/// https://github.com/dart-lang/sdk/issues/28836), but for now we need to pay
|
||||||
|
/// close attention to change them consistently.
|
||||||
|
|
||||||
|
// TODO(sigmund): move this file to a shared package.
|
||||||
|
import 'dart:convert' show JSON;
|
||||||
|
|
||||||
|
import '../fasta/util/relativize.dart';
|
||||||
|
|
||||||
|
/// Contents from a single library specification file.
|
||||||
|
///
|
||||||
|
/// Contains information about all libraries on all target platforms defined in
|
||||||
|
/// that file.
|
||||||
|
class LibrariesSpecification {
|
||||||
|
final Map<String, TargetLibrariesSpecification> _targets;
|
||||||
|
|
||||||
|
const LibrariesSpecification(
|
||||||
|
[this._targets = const <String, TargetLibrariesSpecification>{}]);
|
||||||
|
|
||||||
|
/// The library specification for a given [target], or null if none is
|
||||||
|
/// available.
|
||||||
|
TargetLibrariesSpecification specificationFor(String target) =>
|
||||||
|
_targets[target];
|
||||||
|
|
||||||
|
/// Parse the given [json] as a library specification, resolving any relative
|
||||||
|
/// paths from [baseUri].
|
||||||
|
///
|
||||||
|
/// May throw an exception if [json] is not properly formatted or contains
|
||||||
|
/// invalid values.
|
||||||
|
static LibrariesSpecification parse(Uri baseUri, String json) {
|
||||||
|
if (json == null) return const LibrariesSpecification();
|
||||||
|
var jsonData;
|
||||||
|
try {
|
||||||
|
var data = JSON.decode(json);
|
||||||
|
if (data is! Map) {
|
||||||
|
return _reportError('top-level specification is not a map');
|
||||||
|
}
|
||||||
|
jsonData = data as Map;
|
||||||
|
} on FormatException catch (e) {
|
||||||
|
throw new LibrariesSpecificationException(e);
|
||||||
|
}
|
||||||
|
var targets = <String, TargetLibrariesSpecification>{};
|
||||||
|
jsonData.forEach((String targetName, targetData) {
|
||||||
|
Map<String, LibraryInfo> libraries = <String, LibraryInfo>{};
|
||||||
|
if (targetData is! Map) {
|
||||||
|
return _reportError(
|
||||||
|
"target specification for '$targetName' is not a map");
|
||||||
|
}
|
||||||
|
if (!targetData.containsKey("libraries")) {
|
||||||
|
return _reportError("target specification "
|
||||||
|
"for '$targetName' doesn't have a libraries entry");
|
||||||
|
}
|
||||||
|
var librariesData = targetData["libraries"];
|
||||||
|
if (librariesData is! Map) {
|
||||||
|
return _reportError("libraries entry for '$targetName' is not a map");
|
||||||
|
}
|
||||||
|
librariesData.forEach((String name, data) {
|
||||||
|
if (data is! Map) {
|
||||||
|
return _reportError(
|
||||||
|
"library data for '$name' in target '$targetName' is not a map");
|
||||||
|
}
|
||||||
|
Uri checkAndResolve(uriString) {
|
||||||
|
if (uriString is! String) {
|
||||||
|
return _reportError("uri value '$uriString' is not a string"
|
||||||
|
"(from library '$name' in target '$targetName')");
|
||||||
|
}
|
||||||
|
var uri = Uri.parse(uriString);
|
||||||
|
if (uri.scheme != '' && uri.scheme != 'file') {
|
||||||
|
return _reportError("uri scheme in '$uriString' is not supported.");
|
||||||
|
}
|
||||||
|
return baseUri.resolveUri(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
var uri = checkAndResolve(data['uri']);
|
||||||
|
var patches;
|
||||||
|
if (data['patches'] is List) {
|
||||||
|
patches = data['patches'].map(baseUri.resolve).toList();
|
||||||
|
} else if (data['patches'] is String) {
|
||||||
|
patches = [checkAndResolve(data['patches'])];
|
||||||
|
} else if (data['patches'] == null) {
|
||||||
|
patches = const [];
|
||||||
|
} else {
|
||||||
|
return _reportError(
|
||||||
|
"patches entry for '$name' is not a list or a string");
|
||||||
|
}
|
||||||
|
libraries[name] = new LibraryInfo(name, uri, patches);
|
||||||
|
});
|
||||||
|
targets[targetName] =
|
||||||
|
new TargetLibrariesSpecification(targetName, libraries);
|
||||||
|
});
|
||||||
|
return new LibrariesSpecification(targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
static _reportError(String error) =>
|
||||||
|
throw new LibrariesSpecificationException(error);
|
||||||
|
|
||||||
|
/// Serialize this specification to json.
|
||||||
|
///
|
||||||
|
/// If possible serializes paths relative to [outputUri].
|
||||||
|
String toJsonString(Uri outputUri) => JSON.encode(toJsonMap(outputUri));
|
||||||
|
|
||||||
|
Map toJsonMap(Uri outputUri) {
|
||||||
|
var result = {};
|
||||||
|
var dir = outputUri.resolve('.');
|
||||||
|
String pathFor(Uri uri) => relativizeUri(uri, base: dir);
|
||||||
|
_targets.forEach((targetName, target) {
|
||||||
|
var libraries = {};
|
||||||
|
target._libraries.forEach((name, lib) {
|
||||||
|
libraries[name] = {
|
||||||
|
'uri': pathFor(lib.uri),
|
||||||
|
'patches': lib.patches.map(pathFor).toList(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
result[targetName] = {'libraries': libraries};
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specifies information about all libraries supported by a given target.
|
||||||
|
class TargetLibrariesSpecification {
|
||||||
|
/// Name of the target platform.
|
||||||
|
final String targetName;
|
||||||
|
|
||||||
|
final Map<String, LibraryInfo> _libraries;
|
||||||
|
|
||||||
|
const TargetLibrariesSpecification(this.targetName,
|
||||||
|
[this._libraries = const <String, LibraryInfo>{}]);
|
||||||
|
|
||||||
|
/// Details about a library whose import is `dart:$name`.
|
||||||
|
LibraryInfo libraryInfoFor(String name) => _libraries[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information about a `dart:` library in a specific target platform.
|
||||||
|
class LibraryInfo {
|
||||||
|
/// The name of the library, which is the path developers use to import this
|
||||||
|
/// library (as `dart:$name`).
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The file defining the main implementation of the library.
|
||||||
|
final Uri uri;
|
||||||
|
|
||||||
|
/// Patch files used for this library in the target platform, if any.
|
||||||
|
final List<Uri> patches;
|
||||||
|
|
||||||
|
const LibraryInfo(this.name, this.uri, this.patches);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LibrariesSpecificationException {
|
||||||
|
Object error;
|
||||||
|
LibrariesSpecificationException(this.error);
|
||||||
|
|
||||||
|
String toString() => '$error';
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ import 'package:source_span/source_span.dart' show SourceSpan, SourceLocation;
|
||||||
import 'package:front_end/src/fasta/command_line_reporting.dart'
|
import 'package:front_end/src/fasta/command_line_reporting.dart'
|
||||||
as command_line_reporting;
|
as command_line_reporting;
|
||||||
|
|
||||||
|
import 'libraries_specification.dart';
|
||||||
|
|
||||||
/// All options needed for the front end implementation.
|
/// All options needed for the front end implementation.
|
||||||
///
|
///
|
||||||
/// This includes: all of [CompilerOptions] in a form useful to the
|
/// This includes: all of [CompilerOptions] in a form useful to the
|
||||||
|
@ -76,10 +78,22 @@ class ProcessedOptions {
|
||||||
/// The location of the SDK, or `null` if the location hasn't been determined
|
/// The location of the SDK, or `null` if the location hasn't been determined
|
||||||
/// yet.
|
/// yet.
|
||||||
Uri _sdkRoot;
|
Uri _sdkRoot;
|
||||||
Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot();
|
Uri get sdkRoot {
|
||||||
|
_ensureSdkDefaults();
|
||||||
|
return _sdkRoot;
|
||||||
|
}
|
||||||
|
|
||||||
Uri _sdkSummary;
|
Uri _sdkSummary;
|
||||||
Uri get sdkSummary => _sdkSummary ??= _computeSdkSummaryUri();
|
Uri get sdkSummary {
|
||||||
|
_ensureSdkDefaults();
|
||||||
|
return _sdkSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri _librariesSpecificationUri;
|
||||||
|
Uri get librariesSpecificationUri {
|
||||||
|
_ensureSdkDefaults();
|
||||||
|
return _librariesSpecificationUri;
|
||||||
|
}
|
||||||
|
|
||||||
Ticker ticker;
|
Ticker ticker;
|
||||||
|
|
||||||
|
@ -274,20 +288,45 @@ class ProcessedOptions {
|
||||||
/// required to locate/read the packages file as well as SDK metadata.
|
/// required to locate/read the packages file as well as SDK metadata.
|
||||||
Future<UriTranslatorImpl> getUriTranslator() async {
|
Future<UriTranslatorImpl> getUriTranslator() async {
|
||||||
if (_uriTranslator == null) {
|
if (_uriTranslator == null) {
|
||||||
await _getPackages();
|
ticker.logMs("Started building UriTranslator");
|
||||||
// TODO(scheglov) Load SDK libraries from whatever format we decide.
|
var libraries = await _computeLibrarySpecification();
|
||||||
// TODO(scheglov) Remove the field "_raw.dartLibraries".
|
ticker.logMs("Read libraries file");
|
||||||
var libraries = _raw.dartLibraries ?? await _parseDartLibraries();
|
var packages = await _getPackages();
|
||||||
_uriTranslator = new UriTranslatorImpl(
|
|
||||||
libraries, const <String, List<Uri>>{}, _packages);
|
|
||||||
ticker.logMs("Read packages file");
|
ticker.logMs("Read packages file");
|
||||||
|
_uriTranslator = new UriTranslatorImpl(libraries, packages);
|
||||||
}
|
}
|
||||||
return _uriTranslator;
|
return _uriTranslator;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, Uri>> _parseDartLibraries() async {
|
Future<TargetLibrariesSpecification> _computeLibrarySpecification() async {
|
||||||
Uri librariesJson = _raw.sdkRoot?.resolve("lib/libraries.json");
|
var name = target.name;
|
||||||
return await computeDartLibraries(fileSystem, librariesJson);
|
// TODO(sigmund): Eek! We should get to the point where there is no
|
||||||
|
// fasta-specific targets and the target names are meaningful.
|
||||||
|
if (name.endsWith('_fasta')) name = name.substring(0, name.length - 6);
|
||||||
|
|
||||||
|
if (librariesSpecificationUri == null ||
|
||||||
|
!await fileSystem.entityForUri(librariesSpecificationUri).exists()) {
|
||||||
|
if (compileSdk) {
|
||||||
|
reportWithoutLocation(
|
||||||
|
templateSdkSpecificationNotFound
|
||||||
|
.withArguments(librariesSpecificationUri),
|
||||||
|
Severity.error);
|
||||||
|
}
|
||||||
|
return new TargetLibrariesSpecification(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var json =
|
||||||
|
await fileSystem.entityForUri(librariesSpecificationUri).readAsString();
|
||||||
|
try {
|
||||||
|
var spec =
|
||||||
|
await LibrariesSpecification.parse(librariesSpecificationUri, json);
|
||||||
|
return spec.specificationFor(name);
|
||||||
|
} on LibrariesSpecificationException catch (e) {
|
||||||
|
reportWithoutLocation(
|
||||||
|
templateCannotReadSdkSpecification.withArguments('${e.error}'),
|
||||||
|
Severity.error);
|
||||||
|
return new TargetLibrariesSpecification(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the package map which maps package names to URIs.
|
/// Get the package map which maps package names to URIs.
|
||||||
|
@ -398,32 +437,42 @@ class ProcessedOptions {
|
||||||
return Packages.noPackages;
|
return Packages.noPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the location of the SDK.
|
bool _computedSdkDefaults = false;
|
||||||
Uri _normalizeSdkRoot() {
|
|
||||||
// If an SDK summary location was provided, the SDK itself should not be
|
/// Ensure [_sdkRoot], [_sdkSummary] and [_librarySpecUri] are initialized.
|
||||||
// needed.
|
///
|
||||||
assert(_raw.sdkSummary == null);
|
/// If they are not set explicitly, they are infered based on the default
|
||||||
if (_raw.sdkRoot == null) {
|
/// behavior described in [CompilerOptions].
|
||||||
|
void _ensureSdkDefaults() {
|
||||||
|
if (_computedSdkDefaults) return;
|
||||||
|
_computedSdkDefaults = true;
|
||||||
|
var root = _raw.sdkRoot;
|
||||||
|
if (root != null) {
|
||||||
|
// Normalize to always end in '/'
|
||||||
|
if (!root.path.endsWith('/')) {
|
||||||
|
root = root.replace(path: root.path + '/');
|
||||||
|
}
|
||||||
|
_sdkRoot = root;
|
||||||
|
} else if (compileSdk) {
|
||||||
// TODO(paulberry): implement the algorithm for finding the SDK
|
// TODO(paulberry): implement the algorithm for finding the SDK
|
||||||
// automagically.
|
// automagically.
|
||||||
return unimplemented('infer the default sdk location', -1, null);
|
unimplemented('infer the default sdk location', -1, null);
|
||||||
}
|
}
|
||||||
var root = _raw.sdkRoot;
|
|
||||||
if (!root.path.endsWith('/')) {
|
if (_raw.sdkSummary != null) {
|
||||||
root = root.replace(path: root.path + '/');
|
_sdkSummary = _raw.sdkSummary;
|
||||||
|
} else if (!compileSdk) {
|
||||||
|
// Infer based on the sdkRoot, but only when `compileSdk` is false,
|
||||||
|
// otherwise the default intent was to compile the sdk from sources and
|
||||||
|
// not to load an sdk summary file.
|
||||||
|
_sdkSummary = root?.resolve('outline.dill');
|
||||||
}
|
}
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get or infer the location of the SDK summary.
|
if (_raw.librariesSpecificationUri != null) {
|
||||||
Uri _computeSdkSummaryUri() {
|
_librariesSpecificationUri = _raw.librariesSpecificationUri;
|
||||||
if (_raw.sdkSummary != null) return _raw.sdkSummary;
|
} else if (compileSdk) {
|
||||||
|
_librariesSpecificationUri = sdkRoot.resolve('lib/libraries.json');
|
||||||
// Infer based on the sdkRoot, but only when `compileSdk` is false,
|
}
|
||||||
// otherwise the default intent was to compile the sdk from sources and not
|
|
||||||
// to load an sdk summary file.
|
|
||||||
if (_raw.compileSdk) return null;
|
|
||||||
return sdkRoot.resolve('outline.dill');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [FileSystem] specific to the current options.
|
/// Create a [FileSystem] specific to the current options.
|
||||||
|
@ -494,6 +543,8 @@ class ProcessedOptions {
|
||||||
|
|
||||||
sb.writeln('Compile SDK: ${compileSdk}');
|
sb.writeln('Compile SDK: ${compileSdk}');
|
||||||
sb.writeln('SDK root: ${_sdkRoot} (provided: ${_raw.sdkRoot})');
|
sb.writeln('SDK root: ${_sdkRoot} (provided: ${_raw.sdkRoot})');
|
||||||
|
sb.writeln('SDK specification: ${_librariesSpecificationUri} '
|
||||||
|
'(provided: ${_raw.librariesSpecificationUri})');
|
||||||
sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})');
|
sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})');
|
||||||
|
|
||||||
sb.writeln('Strong: ${strongMode}');
|
sb.writeln('Strong: ${strongMode}');
|
||||||
|
|
|
@ -201,6 +201,29 @@ Message _withArgumentsCannotReadPackagesFile(String string) {
|
||||||
$string.""", arguments: {'string': string});
|
$string.""", arguments: {'string': string});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const Template<Message Function(String string)>
|
||||||
|
templateCannotReadSdkSpecification =
|
||||||
|
const Template<Message Function(String string)>(
|
||||||
|
messageTemplate:
|
||||||
|
r"""Unable to read the 'libraries.json' specification file:
|
||||||
|
#string.""",
|
||||||
|
withArguments: _withArgumentsCannotReadSdkSpecification);
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const Code<Message Function(String string)> codeCannotReadSdkSpecification =
|
||||||
|
const Code<Message Function(String string)>(
|
||||||
|
"CannotReadSdkSpecification",
|
||||||
|
templateCannotReadSdkSpecification,
|
||||||
|
);
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
Message _withArgumentsCannotReadSdkSpecification(String string) {
|
||||||
|
return new Message(codeCannotReadSdkSpecification,
|
||||||
|
message: """Unable to read the 'libraries.json' specification file:
|
||||||
|
$string.""", arguments: {'string': string});
|
||||||
|
}
|
||||||
|
|
||||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
const Code<Null> codeCantInferPackagesFromManyInputs =
|
const Code<Null> codeCantInferPackagesFromManyInputs =
|
||||||
messageCantInferPackagesFromManyInputs;
|
messageCantInferPackagesFromManyInputs;
|
||||||
|
@ -2489,6 +2512,34 @@ Message _withArgumentsSdkRootNotFound(Uri uri_) {
|
||||||
arguments: {'uri': uri_});
|
arguments: {'uri': uri_});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const Template<
|
||||||
|
Message Function(
|
||||||
|
Uri
|
||||||
|
uri_)> templateSdkSpecificationNotFound = const Template<
|
||||||
|
Message Function(Uri uri_)>(
|
||||||
|
messageTemplate: r"""SDK libraries specification not found: #uri.""",
|
||||||
|
tipTemplate:
|
||||||
|
r"""Normally, the specification is a file named 'libraries.json' in the Dart SDK install location.""",
|
||||||
|
withArguments: _withArgumentsSdkSpecificationNotFound);
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const Code<Message Function(Uri uri_)> codeSdkSpecificationNotFound =
|
||||||
|
const Code<Message Function(Uri uri_)>(
|
||||||
|
"SdkSpecificationNotFound",
|
||||||
|
templateSdkSpecificationNotFound,
|
||||||
|
);
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
Message _withArgumentsSdkSpecificationNotFound(Uri uri_) {
|
||||||
|
String uri = relativizeUri(uri_);
|
||||||
|
return new Message(codeSdkSpecificationNotFound,
|
||||||
|
message: """SDK libraries specification not found: $uri.""",
|
||||||
|
tip:
|
||||||
|
"""Normally, the specification is a file named 'libraries.json' in the Dart SDK install location.""",
|
||||||
|
arguments: {'uri': uri_});
|
||||||
|
}
|
||||||
|
|
||||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
const Template<Message Function(Uri uri_)> templateSdkSummaryNotFound =
|
const Template<Message Function(Uri uri_)> templateSdkSummaryNotFound =
|
||||||
const Template<Message Function(Uri uri_)>(
|
const Template<Message Function(Uri uri_)>(
|
||||||
|
|
|
@ -4,65 +4,33 @@
|
||||||
|
|
||||||
library fasta.uri_translator_impl;
|
library fasta.uri_translator_impl;
|
||||||
|
|
||||||
import 'dart:async' show Future;
|
import 'package:front_end/src/base/libraries_specification.dart'
|
||||||
import 'dart:convert' show JSON;
|
show TargetLibrariesSpecification;
|
||||||
|
|
||||||
import 'package:front_end/file_system.dart'
|
|
||||||
show FileSystem, FileSystemException;
|
|
||||||
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
|
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
|
||||||
import 'package:front_end/src/fasta/fasta_codes.dart';
|
import 'package:front_end/src/fasta/fasta_codes.dart';
|
||||||
import 'package:front_end/src/fasta/severity.dart' show Severity;
|
import 'package:front_end/src/fasta/severity.dart' show Severity;
|
||||||
import 'package:front_end/src/fasta/uri_translator.dart';
|
import 'package:front_end/src/fasta/uri_translator.dart';
|
||||||
import 'package:package_config/packages_file.dart' as packages_file show parse;
|
|
||||||
import 'package:package_config/packages.dart' show Packages;
|
import 'package:package_config/packages.dart' show Packages;
|
||||||
import 'package:package_config/src/packages_impl.dart' show MapPackages;
|
|
||||||
|
|
||||||
import 'deprecated_problems.dart' show deprecated_inputError;
|
|
||||||
|
|
||||||
/// Read the JSON file with defined SDK libraries from the given [uri] in the
|
|
||||||
/// [fileSystem] and return the mapping from parsed Dart library names (e.g.
|
|
||||||
/// `math`) to file URIs.
|
|
||||||
Future<Map<String, Uri>> computeDartLibraries(
|
|
||||||
FileSystem fileSystem, Uri uri) async {
|
|
||||||
if (uri == null) return const <String, Uri>{};
|
|
||||||
Map<String, String> libraries = JSON
|
|
||||||
.decode(await fileSystem.entityForUri(uri).readAsString())["libraries"];
|
|
||||||
Map<String, Uri> result = <String, Uri>{};
|
|
||||||
libraries.forEach((String name, String path) {
|
|
||||||
result[name] = uri.resolveUri(new Uri.file(path));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, List<Uri>>> computeDartPatches(
|
|
||||||
FileSystem fileSystem, Uri uri) async {
|
|
||||||
// TODO(ahe): Read patch information.
|
|
||||||
return const <String, List<Uri>>{};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of [UriTranslator] for absolute `dart` and `package` URIs.
|
/// Implementation of [UriTranslator] for absolute `dart` and `package` URIs.
|
||||||
class UriTranslatorImpl implements UriTranslator {
|
class UriTranslatorImpl implements UriTranslator {
|
||||||
/// Mapping from Dart library names (e.g. `math`) to file URIs.
|
/// Library information for platform libraries.
|
||||||
final Map<String, Uri> dartLibraries;
|
final TargetLibrariesSpecification dartLibraries;
|
||||||
|
|
||||||
// TODO(ahe): We probably want this to be `Map<String, Uri>`, that is, just
|
|
||||||
// one patch library (with parts).
|
|
||||||
/// Mapping from Dart library names to the file URIs of patches to apply.
|
|
||||||
final Map<String, List<Uri>> dartPatches;
|
|
||||||
|
|
||||||
/// Mapping from package names (e.g. `angular`) to the file URIs.
|
/// Mapping from package names (e.g. `angular`) to the file URIs.
|
||||||
final Packages packages;
|
final Packages packages;
|
||||||
|
|
||||||
UriTranslatorImpl(this.dartLibraries, this.dartPatches, this.packages);
|
UriTranslatorImpl(this.dartLibraries, this.packages);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Uri> getDartPatches(String libraryName) => dartPatches[libraryName];
|
List<Uri> getDartPatches(String libraryName) =>
|
||||||
|
dartLibraries.libraryInfoFor(libraryName)?.patches;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isPlatformImplementation(Uri uri) {
|
bool isPlatformImplementation(Uri uri) {
|
||||||
if (uri.scheme != "dart") return false;
|
if (uri.scheme != "dart") return false;
|
||||||
String path = uri.path;
|
String path = uri.path;
|
||||||
return dartLibraries[path] == null || path.startsWith("_");
|
return dartLibraries.libraryInfoFor(path) == null || path.startsWith("_");
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -82,11 +50,11 @@ class UriTranslatorImpl implements UriTranslator {
|
||||||
String path = uri.path;
|
String path = uri.path;
|
||||||
|
|
||||||
int index = path.indexOf('/');
|
int index = path.indexOf('/');
|
||||||
if (index == -1) return dartLibraries[path];
|
if (index == -1) return dartLibraries.libraryInfoFor(path)?.uri;
|
||||||
|
|
||||||
String libraryName = path.substring(0, index);
|
String libraryName = path.substring(0, index);
|
||||||
String relativePath = path.substring(index + 1);
|
String relativePath = path.substring(index + 1);
|
||||||
Uri libraryFileUri = dartLibraries[libraryName];
|
Uri libraryFileUri = dartLibraries.libraryInfoFor(libraryName).uri;
|
||||||
return libraryFileUri?.resolve(relativePath);
|
return libraryFileUri?.resolve(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,32 +84,4 @@ class UriTranslatorImpl implements UriTranslator {
|
||||||
// compiler.
|
// compiler.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<UriTranslator> parse(FileSystem fileSystem, Uri sdk,
|
|
||||||
{Uri packages}) async {
|
|
||||||
Uri librariesJson = sdk?.resolve("lib/libraries.json");
|
|
||||||
|
|
||||||
// TODO(ahe): Provide a value for this file.
|
|
||||||
Uri patches = null;
|
|
||||||
|
|
||||||
packages ??= Uri.base.resolve(".packages");
|
|
||||||
|
|
||||||
List<int> bytes;
|
|
||||||
try {
|
|
||||||
bytes = await fileSystem.entityForUri(packages).readAsBytes();
|
|
||||||
} on FileSystemException catch (e) {
|
|
||||||
deprecated_inputError(packages, -1, e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Packages parsedPackages;
|
|
||||||
try {
|
|
||||||
parsedPackages = new MapPackages(packages_file.parse(bytes, packages));
|
|
||||||
} on FormatException catch (e) {
|
|
||||||
return deprecated_inputError(packages, e.offset, e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var dartLibraries = await computeDartLibraries(fileSystem, librariesJson);
|
|
||||||
return new UriTranslatorImpl(dartLibraries,
|
|
||||||
await computeDartPatches(fileSystem, patches), parsedPackages);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,9 @@ Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
|
fs.entityForUri(toTestUri('.packages')).writeAsStringSync('');
|
||||||
|
fs
|
||||||
|
.entityForUri(invalidCoreLibsSpecUri)
|
||||||
|
.writeAsStringSync(_invalidLibrariesSpec);
|
||||||
options
|
options
|
||||||
..verify = true
|
..verify = true
|
||||||
..fileSystem = new HybridFileSystem(fs)
|
..fileSystem = new HybridFileSystem(fs)
|
||||||
|
@ -105,13 +108,22 @@ Uri _defaultDir = Uri.parse('file:///a/b/c/');
|
||||||
/// helpers above.
|
/// helpers above.
|
||||||
Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath);
|
Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath);
|
||||||
|
|
||||||
/// A map defining the location of core libraries that purposely provides
|
/// Uri to a libraries specification file that purposely provides
|
||||||
/// invalid Uris. Used by tests that want to ensure that the sdk libraries are
|
/// invalid Uris to dart:core and dart:async. Used by tests that want to ensure
|
||||||
/// not loaded from sources, but read from a .dill file.
|
/// that the sdk libraries are not loaded from sources, but read from a .dill
|
||||||
Map<String, Uri> invalidCoreLibs = {
|
/// file.
|
||||||
'core': Uri.parse('file:///non_existing_file/core.dart'),
|
Uri invalidCoreLibsSpecUri = toTestUri('invalid_sdk_libraries.json');
|
||||||
'async': Uri.parse('file:///non_existing_file/async.dart'),
|
|
||||||
};
|
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 isDartCoreLibrary(Library lib) => isDartCore(lib.importUri);
|
||||||
bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core';
|
bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core';
|
||||||
|
|
|
@ -823,6 +823,10 @@ SdkRootNotFound:
|
||||||
SdkSummaryNotFound:
|
SdkSummaryNotFound:
|
||||||
template: "SDK summary not found: #uri."
|
template: "SDK summary not found: #uri."
|
||||||
|
|
||||||
|
SdkSpecificationNotFound:
|
||||||
|
template: "SDK libraries specification not found: #uri."
|
||||||
|
tip: "Normally, the specification is a file named 'libraries.json' in the Dart SDK install location."
|
||||||
|
|
||||||
ThisAccessInFieldInitializer:
|
ThisAccessInFieldInitializer:
|
||||||
template: "Can't access 'this' in a field initializer to read '#name'."
|
template: "Can't access 'this' in a field initializer to read '#name'."
|
||||||
|
|
||||||
|
@ -883,6 +887,9 @@ NotAnLvalue:
|
||||||
CannotReadPackagesFile:
|
CannotReadPackagesFile:
|
||||||
template: "Unable to read '.packages' file:\n #string."
|
template: "Unable to read '.packages' file:\n #string."
|
||||||
|
|
||||||
|
CannotReadSdkSpecification:
|
||||||
|
template: "Unable to read the 'libraries.json' specification file:\n #string."
|
||||||
|
|
||||||
CantInferPackagesFromManyInputs:
|
CantInferPackagesFromManyInputs:
|
||||||
template: "Can't infer a .packages file when compiling multiple inputs."
|
template: "Can't infer a .packages file when compiling multiple inputs."
|
||||||
tip: "Try specifying the file explicitly with the --packages option."
|
tip: "Try specifying the file explicitly with the --packages option."
|
||||||
|
|
|
@ -12,6 +12,9 @@ import 'dart:convert' show JSON;
|
||||||
|
|
||||||
import 'package:front_end/physical_file_system.dart' show PhysicalFileSystem;
|
import 'package:front_end/physical_file_system.dart' show PhysicalFileSystem;
|
||||||
|
|
||||||
|
import 'package:front_end/src/base/libraries_specification.dart'
|
||||||
|
show TargetLibrariesSpecification;
|
||||||
|
|
||||||
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
||||||
show ValidatingInstrumentation;
|
show ValidatingInstrumentation;
|
||||||
|
|
||||||
|
@ -155,8 +158,10 @@ class FastaContext extends ChainContext {
|
||||||
Uri sdk = await computePatchedSdk();
|
Uri sdk = await computePatchedSdk();
|
||||||
Uri vm = computeDartVm(sdk);
|
Uri vm = computeDartVm(sdk);
|
||||||
Uri packages = Uri.base.resolve(".packages");
|
Uri packages = Uri.base.resolve(".packages");
|
||||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
var options = new ProcessedOptions(new CompilerOptions()
|
||||||
.parse(PhysicalFileSystem.instance, sdk, packages: packages);
|
..sdkRoot = sdk
|
||||||
|
..packagesFileUri = packages);
|
||||||
|
UriTranslator uriTranslator = await options.getUriTranslator();
|
||||||
bool strongMode = environment.containsKey(STRONG_MODE);
|
bool strongMode = environment.containsKey(STRONG_MODE);
|
||||||
bool updateExpectations = environment["updateExpectations"] == "true";
|
bool updateExpectations = environment["updateExpectations"] == "true";
|
||||||
bool updateComments = environment["updateComments"] == "true";
|
bool updateComments = environment["updateComments"] == "true";
|
||||||
|
@ -242,8 +247,7 @@ class Outline extends Step<TestDescription, Program, FastaContext> {
|
||||||
// We create a new URI translator to avoid reading platform libraries from
|
// We create a new URI translator to avoid reading platform libraries from
|
||||||
// file system.
|
// file system.
|
||||||
UriTranslatorImpl uriTranslator = new UriTranslatorImpl(
|
UriTranslatorImpl uriTranslator = new UriTranslatorImpl(
|
||||||
const <String, Uri>{},
|
const TargetLibrariesSpecification('vm'),
|
||||||
const <String, List<Uri>>{},
|
|
||||||
context.uriTranslator.packages);
|
context.uriTranslator.packages);
|
||||||
KernelTarget sourceTarget = astKind == AstKind.Analyzer
|
KernelTarget sourceTarget = astKind == AstKind.Analyzer
|
||||||
? new AnalyzerTarget(dillTarget, uriTranslator, strongMode)
|
? new AnalyzerTarget(dillTarget, uriTranslator, strongMode)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:front_end/src/base/libraries_specification.dart';
|
||||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
||||||
import 'package:package_config/packages.dart';
|
import 'package:package_config/packages.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
@ -15,12 +16,16 @@ main() {
|
||||||
|
|
||||||
@reflectiveTest
|
@reflectiveTest
|
||||||
class UriTranslatorImplTest {
|
class UriTranslatorImplTest {
|
||||||
void test_isPlatformImplementation() {
|
UriTranslatorImpl translator = new UriTranslatorImpl(
|
||||||
var translator = new UriTranslatorImpl({
|
new TargetLibrariesSpecification('vm', {
|
||||||
'core': Uri.parse('file:///sdk/core/core.dart'),
|
'core': new LibraryInfo(
|
||||||
'math': Uri.parse('file:///sdk/math/math.dart')
|
'core', Uri.parse('file:///sdk/core/core.dart'), const []),
|
||||||
}, {}, Packages.noPackages);
|
'math': new LibraryInfo(
|
||||||
|
'core', Uri.parse('file:///sdk/math/math.dart'), const []),
|
||||||
|
}),
|
||||||
|
Packages.noPackages);
|
||||||
|
|
||||||
|
void test_isPlatformImplementation() {
|
||||||
bool isPlatform(String uriStr) {
|
bool isPlatform(String uriStr) {
|
||||||
var uri = Uri.parse(uriStr);
|
var uri = Uri.parse(uriStr);
|
||||||
return translator.isPlatformImplementation(uri);
|
return translator.isPlatformImplementation(uri);
|
||||||
|
@ -33,11 +38,6 @@ class UriTranslatorImplTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_translate_dart() {
|
void test_translate_dart() {
|
||||||
var translator = new UriTranslatorImpl({
|
|
||||||
'core': Uri.parse('file:///sdk/core/core.dart'),
|
|
||||||
'math': Uri.parse('file:///sdk/math/math.dart')
|
|
||||||
}, {}, Packages.noPackages);
|
|
||||||
|
|
||||||
expect(translator.translate(Uri.parse('dart:core')),
|
expect(translator.translate(Uri.parse('dart:core')),
|
||||||
Uri.parse('file:///sdk/core/core.dart'));
|
Uri.parse('file:///sdk/core/core.dart'));
|
||||||
expect(translator.translate(Uri.parse('dart:core/string.dart')),
|
expect(translator.translate(Uri.parse('dart:core/string.dart')),
|
||||||
|
|
|
@ -36,18 +36,16 @@ class IncrementalKernelGeneratorTest {
|
||||||
/// Compute the initial [Program] for the given [entryPoint].
|
/// Compute the initial [Program] for the given [entryPoint].
|
||||||
Future<Program> getInitialState(Uri entryPoint,
|
Future<Program> getInitialState(Uri entryPoint,
|
||||||
{bool setPackages: true}) async {
|
{bool setPackages: true}) async {
|
||||||
Map<String, Uri> dartLibraries = createSdkFiles(fileSystem);
|
createSdkFiles(fileSystem);
|
||||||
// TODO(scheglov) Builder the SDK kernel and set it into the options.
|
// TODO(scheglov) Builder the SDK kernel and set it into the options.
|
||||||
|
|
||||||
// TODO(scheglov) Make `.packages` file optional.
|
|
||||||
|
|
||||||
var compilerOptions = new CompilerOptions()
|
var compilerOptions = new CompilerOptions()
|
||||||
..fileSystem = fileSystem
|
..fileSystem = fileSystem
|
||||||
..byteStore = new MemoryByteStore()
|
..byteStore = new MemoryByteStore()
|
||||||
// ..logger = new PerformanceLog(stdout)
|
// ..logger = new PerformanceLog(stdout)
|
||||||
..strongMode = true
|
..strongMode = true
|
||||||
..chaseDependencies = true
|
..chaseDependencies = true
|
||||||
..dartLibraries = dartLibraries;
|
..librariesSpecificationUri = Uri.parse('file:///sdk/lib/libraries.json');
|
||||||
|
|
||||||
if (setPackages) {
|
if (setPackages) {
|
||||||
compilerOptions.packagesFileUri = Uri.parse('file:///test/.packages');
|
compilerOptions.packagesFileUri = Uri.parse('file:///test/.packages');
|
||||||
|
|
|
@ -17,7 +17,7 @@ main() {
|
||||||
test('compiler fails if it cannot find sdk sources', () async {
|
test('compiler fails if it cannot find sdk sources', () async {
|
||||||
var errors = [];
|
var errors = [];
|
||||||
var options = new CompilerOptions()
|
var options = new CompilerOptions()
|
||||||
..dartLibraries = invalidCoreLibs
|
..librariesSpecificationUri = invalidCoreLibsSpecUri
|
||||||
..sdkSummary = null
|
..sdkSummary = null
|
||||||
..compileSdk = true // To prevent FE from loading an sdk-summary.
|
..compileSdk = true // To prevent FE from loading an sdk-summary.
|
||||||
..onError = (e) => errors.add(e);
|
..onError = (e) => errors.add(e);
|
||||||
|
@ -42,9 +42,10 @@ main() {
|
||||||
|
|
||||||
test('by default program is compiled using summaries', () async {
|
test('by default program is compiled using summaries', () async {
|
||||||
var options = new CompilerOptions()
|
var options = new CompilerOptions()
|
||||||
// Note: we define [dartLibraries] with broken URIs to ensure we do not
|
// Note: we define [librariesSpecificationUri] with a specification that
|
||||||
// attempt to lookup for sources of the sdk directly.
|
// contains broken URIs to ensure we do not attempt to lookup for
|
||||||
..dartLibraries = invalidCoreLibs;
|
// sources of the sdk directly.
|
||||||
|
..librariesSpecificationUri = invalidCoreLibsSpecUri;
|
||||||
var program =
|
var program =
|
||||||
await compileScript('main() => print("hi");', options: options);
|
await compileScript('main() => print("hi");', options: options);
|
||||||
var core = program.libraries.firstWhere(isDartCoreLibrary);
|
var core = program.libraries.firstWhere(isDartCoreLibrary);
|
||||||
|
|
309
pkg/front_end/test/src/base/libraries_specification_test.dart
Normal file
309
pkg/front_end/test/src/base/libraries_specification_test.dart
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
import 'package:front_end/src/base/libraries_specification.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
main() {
|
||||||
|
group('parse', () {
|
||||||
|
test('top-level must be a map', () async {
|
||||||
|
var jsonString = '[]';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
jsonString = '""';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('target entry must be a map', () async {
|
||||||
|
var jsonString = '{"vm" : []}';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
jsonString = '{"vm" : ""}';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('library entry must exist', () async {
|
||||||
|
var jsonString = '{"vm" : {}}';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('library entry must be a map', () async {
|
||||||
|
var jsonString = '{"vm" : {"libraries": []}}';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('uri must be a string', () async {
|
||||||
|
var jsonString = '{"vm" : {"libraries": {"core": {"uri": 3}}}';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('patches must be a string or list of string', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart",
|
||||||
|
"patches": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
expect(
|
||||||
|
() => LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString),
|
||||||
|
throwsA((e) => e is LibrariesSpecificationException));
|
||||||
|
|
||||||
|
jsonString = '''
|
||||||
|
{
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart",
|
||||||
|
"patches": "a.dart"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString);
|
||||||
|
expect(spec.specificationFor("none").libraryInfoFor("c").patches.first,
|
||||||
|
Uri.parse('org-dartlang-custom:///a.dart'));
|
||||||
|
|
||||||
|
jsonString = '''
|
||||||
|
{
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart",
|
||||||
|
"patches": ["a.dart"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///f.json'), jsonString);
|
||||||
|
expect(spec.specificationFor("none").libraryInfoFor("c").patches.first,
|
||||||
|
Uri.parse('org-dartlang-custom:///a.dart'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('patches are optional in the format', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{ "none": { "libraries": {"c" : { "uri": "c/main.dart" }}}}
|
||||||
|
''';
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
expect(spec, isNotNull);
|
||||||
|
expect(
|
||||||
|
spec.specificationFor('none').libraryInfoFor('c').patches, isEmpty);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('library paths are resolved from spec uri', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{ "none": { "libraries": {"c" : { "uri": "c/main.dart" }}}}
|
||||||
|
''';
|
||||||
|
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
expect(spec.specificationFor('none').libraryInfoFor('c').uri,
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/c/main.dart'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('patches paths are resolved from spec uri', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"../a/p1.dart",
|
||||||
|
"../a/p2.dart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
expect(spec.specificationFor('none').libraryInfoFor('c').patches[0],
|
||||||
|
Uri.parse('org-dartlang-custom:///one/a/p1.dart'));
|
||||||
|
expect(spec.specificationFor('none').libraryInfoFor('c').patches[1],
|
||||||
|
Uri.parse('org-dartlang-custom:///one/a/p2.dart'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('multiple targets are supported', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{
|
||||||
|
"vm": {
|
||||||
|
"libraries": {
|
||||||
|
"foo" : {
|
||||||
|
"uri": "a/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"a/p1.dart",
|
||||||
|
"a/p2.dart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bar" : {
|
||||||
|
"uri": "b/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"b/p3.dart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
|
||||||
|
expect(spec.specificationFor('vm').libraryInfoFor('foo').uri,
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/a/main.dart'));
|
||||||
|
expect(spec.specificationFor('vm').libraryInfoFor('bar').uri,
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/b/main.dart'));
|
||||||
|
expect(spec.specificationFor('none').libraryInfoFor('c').uri,
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/c/main.dart'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('toJson', () {
|
||||||
|
test('serialization produces same data that was parsed', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{
|
||||||
|
"vm": {
|
||||||
|
"libraries": {
|
||||||
|
"foo" : {
|
||||||
|
"uri": "a/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"a/p1.dart",
|
||||||
|
"a/p2.dart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bar" : {
|
||||||
|
"uri": "b/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"b/p3.dart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart",
|
||||||
|
"patches": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
var newJson =
|
||||||
|
spec.toJsonString(Uri.parse('org-dartlang-custom:///one/two/g.json'));
|
||||||
|
expect(jsonString.replaceAll(new RegExp('\\s'), ''), newJson);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('serialization can adapt to new file location', () async {
|
||||||
|
var jsonString = '''
|
||||||
|
{
|
||||||
|
"vm": {
|
||||||
|
"libraries": {
|
||||||
|
"foo" : {
|
||||||
|
"uri": "a/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"a/p1.dart",
|
||||||
|
"a/p2.dart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bar" : {
|
||||||
|
"uri": "b/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"b/p3.dart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "c/main.dart"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
var spec = LibrariesSpecification.parse(
|
||||||
|
Uri.parse('org-dartlang-custom:///one/two/f.json'), jsonString);
|
||||||
|
var newJson =
|
||||||
|
spec.toJsonString(Uri.parse('org-dartlang-custom:///one/g.json'));
|
||||||
|
|
||||||
|
var expected = '''
|
||||||
|
{
|
||||||
|
"vm": {
|
||||||
|
"libraries": {
|
||||||
|
"foo" : {
|
||||||
|
"uri": "two/a/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"two/a/p1.dart",
|
||||||
|
"two/a/p2.dart"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"bar" : {
|
||||||
|
"uri": "two/b/main.dart",
|
||||||
|
"patches": [
|
||||||
|
"two/b/p3.dart"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"none": {
|
||||||
|
"libraries": {
|
||||||
|
"c" : {
|
||||||
|
"uri": "two/c/main.dart",
|
||||||
|
"patches": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
|
||||||
|
expect(expected.replaceAll(new RegExp('\\s'), ''), newJson);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/memory_file_system.dart';
|
import 'package:front_end/memory_file_system.dart';
|
||||||
import 'package:front_end/src/base/processed_options.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/fasta/fasta.dart' show ByteSink;
|
import 'package:front_end/src/fasta/fasta.dart' show ByteSink;
|
||||||
|
import 'package:front_end/src/fasta/compiler_context.dart';
|
||||||
import 'package:front_end/src/fasta/fasta_codes.dart';
|
import 'package:front_end/src/fasta/fasta_codes.dart';
|
||||||
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
|
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
|
||||||
import 'package:kernel/kernel.dart' show Program, Library, CanonicalName;
|
import 'package:kernel/kernel.dart' show Program, Library, CanonicalName;
|
||||||
|
@ -17,8 +18,10 @@ import 'package:test/test.dart';
|
||||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
defineReflectiveSuite(() {
|
CompilerContext.runWithDefaultOptions((_) {
|
||||||
defineReflectiveTests(ProcessedOptionsTest);
|
defineReflectiveSuite(() {
|
||||||
|
defineReflectiveTests(ProcessedOptionsTest);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +87,58 @@ class ProcessedOptionsTest {
|
||||||
mockSummary.libraries.single.importUri);
|
mockSummary.libraries.single.importUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_getUriTranslator_explicitLibrariesSpec() async {
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///.packages'))
|
||||||
|
.writeAsStringSync('');
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///libraries.json'))
|
||||||
|
.writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
|
||||||
|
var raw = new CompilerOptions()
|
||||||
|
..packagesFileUri = Uri.parse('file:///.packages')
|
||||||
|
..fileSystem = fileSystem
|
||||||
|
..librariesSpecificationUri = Uri.parse('file:///libraries.json');
|
||||||
|
var processed = new ProcessedOptions(raw);
|
||||||
|
var uriTranslator = await processed.getUriTranslator();
|
||||||
|
expect(uriTranslator.dartLibraries.libraryInfoFor('foo').uri.path,
|
||||||
|
'/bar.dart');
|
||||||
|
}
|
||||||
|
|
||||||
|
test_getUriTranslator_inferredLibrariesSpec() async {
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///.packages'))
|
||||||
|
.writeAsStringSync('');
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///mysdk/lib/libraries.json'))
|
||||||
|
.writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
|
||||||
|
var raw = new CompilerOptions()
|
||||||
|
..fileSystem = fileSystem
|
||||||
|
..packagesFileUri = Uri.parse('file:///.packages')
|
||||||
|
..compileSdk = true
|
||||||
|
..sdkRoot = Uri.parse('file:///mysdk/');
|
||||||
|
var processed = new ProcessedOptions(raw);
|
||||||
|
var uriTranslator = await processed.getUriTranslator();
|
||||||
|
expect(uriTranslator.dartLibraries.libraryInfoFor('foo').uri.path,
|
||||||
|
'/mysdk/lib/bar.dart');
|
||||||
|
}
|
||||||
|
|
||||||
|
test_getUriTranslator_notInferredLibrariesSpec() async {
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///.packages'))
|
||||||
|
.writeAsStringSync('');
|
||||||
|
fileSystem
|
||||||
|
.entityForUri(Uri.parse('file:///mysdk/lib/libraries.json'))
|
||||||
|
.writeAsStringSync('{"vm":{"libraries":{"foo":{"uri":"bar.dart"}}}}');
|
||||||
|
var raw = new CompilerOptions()
|
||||||
|
..fileSystem = fileSystem
|
||||||
|
..packagesFileUri = Uri.parse('file:///.packages')
|
||||||
|
..compileSdk = false // libraries.json is only inferred if true
|
||||||
|
..sdkRoot = Uri.parse('file:///mysdk/');
|
||||||
|
var processed = new ProcessedOptions(raw);
|
||||||
|
var uriTranslator = await processed.getUriTranslator();
|
||||||
|
expect(uriTranslator.dartLibraries.libraryInfoFor('foo'), isNull);
|
||||||
|
}
|
||||||
|
|
||||||
checkPackageExpansion(
|
checkPackageExpansion(
|
||||||
String packageName, String packageDir, Packages packages) {
|
String packageName, String packageDir, Packages packages) {
|
||||||
var input = Uri.parse('package:$packageName/a.dart');
|
var input = Uri.parse('package:$packageName/a.dart');
|
||||||
|
|
|
@ -24,16 +24,14 @@ main() {
|
||||||
class FileSystemStateTest {
|
class FileSystemStateTest {
|
||||||
final byteStore = new MemoryByteStore();
|
final byteStore = new MemoryByteStore();
|
||||||
final fileSystem = new MemoryFileSystem(Uri.parse('file:///'));
|
final fileSystem = new MemoryFileSystem(Uri.parse('file:///'));
|
||||||
final UriTranslatorImpl uriTranslator =
|
|
||||||
new UriTranslatorImpl({}, {}, Packages.noPackages);
|
|
||||||
FileSystemState fsState;
|
FileSystemState fsState;
|
||||||
|
|
||||||
Uri _coreUri;
|
Uri _coreUri;
|
||||||
List<Uri> _newFileUris = <Uri>[];
|
List<Uri> _newFileUris = <Uri>[];
|
||||||
|
|
||||||
void setUp() {
|
void setUp() {
|
||||||
Map<String, Uri> dartLibraries = createSdkFiles(fileSystem);
|
var uriTranslator =
|
||||||
uriTranslator.dartLibraries.addAll(dartLibraries);
|
new UriTranslatorImpl(createSdkFiles(fileSystem), Packages.noPackages);
|
||||||
_coreUri = Uri.parse('dart:core');
|
_coreUri = Uri.parse('dart:core');
|
||||||
expect(_coreUri, isNotNull);
|
expect(_coreUri, isNotNull);
|
||||||
fsState = new FileSystemState(byteStore, fileSystem, uriTranslator, <int>[],
|
fsState = new FileSystemState(byteStore, fileSystem, uriTranslator, <int>[],
|
||||||
|
|
|
@ -175,24 +175,14 @@ Future<IncrementalKernelGenerator> createIncrementalCompiler(
|
||||||
var entryUri = Uri.base.resolve(entry);
|
var entryUri = Uri.base.resolve(entry);
|
||||||
var options = new CompilerOptions()
|
var options = new CompilerOptions()
|
||||||
..sdkRoot = sdkRoot
|
..sdkRoot = sdkRoot
|
||||||
..sdkSummary = sdkRoot.resolve('outline.dill')
|
|
||||||
..packagesFileUri = Uri.parse('file:///.packages')
|
..packagesFileUri = Uri.parse('file:///.packages')
|
||||||
..strongMode = false
|
..strongMode = false
|
||||||
..dartLibraries = loadDartLibraries()
|
..compileSdk = true // the incremental generator requires the sdk sources
|
||||||
..fileSystem = fs
|
..fileSystem = fs
|
||||||
..byteStore = new MemoryByteStore();
|
..byteStore = new MemoryByteStore();
|
||||||
return IncrementalKernelGenerator.newInstance(options, entryUri);
|
return IncrementalKernelGenerator.newInstance(options, entryUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Uri> loadDartLibraries() {
|
|
||||||
var libraries = sdkRoot.resolve('lib/libraries.json');
|
|
||||||
var map =
|
|
||||||
JSON.decode(new File.fromUri(libraries).readAsStringSync())['libraries'];
|
|
||||||
var dartLibraries = <String, Uri>{};
|
|
||||||
map.forEach((k, v) => dartLibraries[k] = libraries.resolve(v));
|
|
||||||
return dartLibraries;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> rebuild(IncrementalKernelGenerator compiler, Uri outputUri) async {
|
Future<bool> rebuild(IncrementalKernelGenerator compiler, Uri outputUri) async {
|
||||||
compiler.invalidate(Uri.parse("file:///a.dart"));
|
compiler.invalidate(Uri.parse("file:///a.dart"));
|
||||||
compiler.invalidate(Uri.parse("file:///b.dart"));
|
compiler.invalidate(Uri.parse("file:///b.dart"));
|
||||||
|
|
|
@ -650,9 +650,8 @@ import 'b.dart';
|
||||||
/// Create new [KernelDriver] instance and put it into the [driver] field.
|
/// Create new [KernelDriver] instance and put it into the [driver] field.
|
||||||
void _createDriver(
|
void _createDriver(
|
||||||
{Map<String, Uri> packages, KernelDriverFileAddedFn fileAddedFn}) {
|
{Map<String, Uri> packages, KernelDriverFileAddedFn fileAddedFn}) {
|
||||||
Map<String, Uri> dartLibraries = createSdkFiles(fileSystem);
|
var uriTranslator = new UriTranslatorImpl(
|
||||||
var uriTranslator =
|
createSdkFiles(fileSystem), new MapPackages(packages));
|
||||||
new UriTranslatorImpl(dartLibraries, {}, new MapPackages(packages));
|
|
||||||
driver = new KernelDriver(
|
driver = new KernelDriver(
|
||||||
new ProcessedOptions(new CompilerOptions()
|
new ProcessedOptions(new CompilerOptions()
|
||||||
..logger = new PerformanceLog(null)
|
..logger = new PerformanceLog(null)
|
||||||
|
|
|
@ -3,18 +3,21 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:front_end/memory_file_system.dart';
|
import 'package:front_end/memory_file_system.dart';
|
||||||
|
import 'package:front_end/src/base/libraries_specification.dart';
|
||||||
|
|
||||||
/// Create SDK libraries which are used by Fasta to perform kernel generation.
|
/// Create SDK libraries which are used by Fasta to perform kernel generation.
|
||||||
/// Return the mapping from the simple names of these library to the URIs
|
/// The root of the SDK is `file:///sdk`, it will contain a libraries
|
||||||
/// in the given [fileSystem]. The root of the SDK is `file:///sdk`.
|
/// specification file at `lib/libraries.json`.
|
||||||
Map<String, Uri> createSdkFiles(MemoryFileSystem fileSystem) {
|
///
|
||||||
Map<String, Uri> dartLibraries = {};
|
/// Returns the [TargetLibrariesSpecification] whose contents are in
|
||||||
|
/// libraries.json.
|
||||||
|
TargetLibrariesSpecification createSdkFiles(MemoryFileSystem fileSystem) {
|
||||||
|
Map<String, LibraryInfo> dartLibraries = {};
|
||||||
void addSdkLibrary(String name, String contents) {
|
void addSdkLibrary(String name, String contents) {
|
||||||
String path = '$name/$name.dart';
|
String path = '$name/$name.dart';
|
||||||
Uri uri = Uri.parse('file:///sdk/lib/$path');
|
Uri uri = Uri.parse('file:///sdk/lib/$path');
|
||||||
fileSystem.entityForUri(uri).writeAsStringSync(contents);
|
fileSystem.entityForUri(uri).writeAsStringSync(contents);
|
||||||
dartLibraries[name] = uri;
|
dartLibraries[name] = new LibraryInfo(name, uri, const []);
|
||||||
}
|
}
|
||||||
|
|
||||||
addSdkLibrary('core', r'''
|
addSdkLibrary('core', r'''
|
||||||
|
@ -265,5 +268,10 @@ class ExternalName {
|
||||||
''');
|
''');
|
||||||
addSdkLibrary('_vmservice', 'library dart._vmservice;');
|
addSdkLibrary('_vmservice', 'library dart._vmservice;');
|
||||||
|
|
||||||
return dartLibraries;
|
var targetSpec = new TargetLibrariesSpecification('vm', dartLibraries);
|
||||||
|
var spec = new LibrariesSpecification({'vm': targetSpec});
|
||||||
|
|
||||||
|
Uri uri = Uri.parse('file:///sdk/lib/libraries.json');
|
||||||
|
fileSystem.entityForUri(uri).writeAsStringSync(spec.toJsonString(uri));
|
||||||
|
return targetSpec;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ final subpackageRules = {
|
||||||
'lib',
|
'lib',
|
||||||
'lib/src',
|
'lib/src',
|
||||||
'lib/src/fasta',
|
'lib/src/fasta',
|
||||||
|
'lib/src/fasta/util',
|
||||||
'lib/src/incremental'
|
'lib/src/incremental'
|
||||||
]),
|
]),
|
||||||
'lib/src/codegen': new SubpackageRules(),
|
'lib/src/codegen': new SubpackageRules(),
|
||||||
|
|
|
@ -10,7 +10,7 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:analyzer/src/fasta/ast_builder.dart';
|
import 'package:analyzer/src/fasta/ast_builder.dart';
|
||||||
import 'package:front_end/front_end.dart';
|
import 'package:front_end/front_end.dart';
|
||||||
import 'package:front_end/physical_file_system.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/fasta/parser.dart';
|
import 'package:front_end/src/fasta/parser.dart';
|
||||||
import 'package:front_end/src/fasta/scanner.dart';
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
import 'package:front_end/src/fasta/scanner/io.dart' show readBytesFromFileSync;
|
import 'package:front_end/src/fasta/scanner/io.dart' show readBytesFromFileSync;
|
||||||
|
@ -18,7 +18,6 @@ import 'package:front_end/src/fasta/source/directive_listener.dart';
|
||||||
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
|
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
|
||||||
import 'package:front_end/src/fasta/parser/native_support.dart'
|
import 'package:front_end/src/fasta/parser/native_support.dart'
|
||||||
show skipNativeClause;
|
show skipNativeClause;
|
||||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
|
||||||
|
|
||||||
/// Cumulative total number of chars scanned.
|
/// Cumulative total number of chars scanned.
|
||||||
int inputSize = 0;
|
int inputSize = 0;
|
||||||
|
@ -80,8 +79,11 @@ UriTranslator uriResolver;
|
||||||
/// Preliminary set up to be able to correctly resolve URIs on the given
|
/// Preliminary set up to be able to correctly resolve URIs on the given
|
||||||
/// program.
|
/// program.
|
||||||
Future setup(Uri entryUri) async {
|
Future setup(Uri entryUri) async {
|
||||||
uriResolver =
|
var options = new CompilerOptions()
|
||||||
await UriTranslatorImpl.parse(PhysicalFileSystem.instance, sdkRoot);
|
..sdkRoot = sdkRoot
|
||||||
|
..compileSdk = true
|
||||||
|
..packagesFileUri = Uri.base.resolve('.packages');
|
||||||
|
uriResolver = await new ProcessedOptions(options).getUriTranslator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan [contents] and return the first token produced by the scanner.
|
/// Scan [contents] and return the first token produced by the scanner.
|
||||||
|
|
|
@ -108,7 +108,7 @@ Future _main(List<String> argv) async {
|
||||||
libContents = _updateLibraryMetadata(sdkOut, libContents);
|
libContents = _updateLibraryMetadata(sdkOut, libContents);
|
||||||
var sdkLibraries = _getSdkLibraries(libContents);
|
var sdkLibraries = _getSdkLibraries(libContents);
|
||||||
|
|
||||||
Map<String, String> locations = <String, String>{};
|
var locations = <String, Map<String, String>>{};
|
||||||
|
|
||||||
// Enumerate core libraries and apply patches
|
// Enumerate core libraries and apply patches
|
||||||
for (SdkLibrary library in sdkLibraries) {
|
for (SdkLibrary library in sdkLibraries) {
|
||||||
|
@ -125,7 +125,10 @@ Future _main(List<String> argv) async {
|
||||||
Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile));
|
Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile));
|
||||||
|
|
||||||
await _writeSync(
|
await _writeSync(
|
||||||
librariesJson.toFilePath(), JSON.encode({"libraries": locations}));
|
librariesJson.toFilePath(),
|
||||||
|
JSON.encode({
|
||||||
|
mode: {"libraries": locations}
|
||||||
|
}));
|
||||||
|
|
||||||
var flags = new TargetFlags();
|
var flags = new TargetFlags();
|
||||||
var target = forVm
|
var target = forVm
|
||||||
|
@ -141,6 +144,22 @@ Future _main(List<String> argv) async {
|
||||||
var base = path.fromUri(Platform.script);
|
var base = path.fromUri(Platform.script);
|
||||||
Uri dartDir =
|
Uri dartDir =
|
||||||
new Uri.directory(path.dirname(path.dirname(path.absolute(base))));
|
new Uri.directory(path.dirname(path.dirname(path.absolute(base))));
|
||||||
|
|
||||||
|
String vmserviceJson = JSON.encode({
|
||||||
|
'vm': {
|
||||||
|
"libraries": {
|
||||||
|
'_vmservice': {
|
||||||
|
'uri': '${dartDir.resolve('sdk/lib/vmservice/vmservice.dart')}'
|
||||||
|
},
|
||||||
|
'vmservice_io': {
|
||||||
|
'uri':
|
||||||
|
'${dartDir.resolve('runtime/bin/vmservice/vmservice_io.dart')}'
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Uri vmserviceJsonUri = outDirUri.resolve("lib/vmservice_libraries.json");
|
||||||
|
await _writeSync(vmserviceJsonUri.toFilePath(), vmserviceJson);
|
||||||
var program = await kernelForProgram(
|
var program = await kernelForProgram(
|
||||||
Uri.parse('dart:$vmserviceName'),
|
Uri.parse('dart:$vmserviceName'),
|
||||||
new CompilerOptions()
|
new CompilerOptions()
|
||||||
|
@ -148,11 +167,7 @@ Future _main(List<String> argv) async {
|
||||||
// TODO(sigmund): investigate. This should be outline, but it breaks
|
// TODO(sigmund): investigate. This should be outline, but it breaks
|
||||||
// vm-debug tests. Issue #30111
|
// vm-debug tests. Issue #30111
|
||||||
..sdkSummary = platform
|
..sdkSummary = platform
|
||||||
..dartLibraries = <String, Uri>{
|
..librariesSpecificationUri = vmserviceJsonUri
|
||||||
'_vmservice': dartDir.resolve('sdk/lib/vmservice/vmservice.dart'),
|
|
||||||
'vmservice_io':
|
|
||||||
dartDir.resolve('runtime/bin/vmservice/vmservice_io.dart'),
|
|
||||||
}
|
|
||||||
..packagesFileUri = packages);
|
..packagesFileUri = packages);
|
||||||
Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill');
|
Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill');
|
||||||
// TODO(sigmund): remove. This is a workaround because in the VM
|
// TODO(sigmund): remove. This is a workaround because in the VM
|
||||||
|
@ -333,7 +348,7 @@ String _updateLibraryMetadata(String sdkOut, String libContents) {
|
||||||
/// Copy internal libraries that are developed outside the sdk folder into the
|
/// Copy internal libraries that are developed outside the sdk folder into the
|
||||||
/// patched_sdk folder. For the VM< this includes files under 'runtime/bin/',
|
/// patched_sdk folder. For the VM< this includes files under 'runtime/bin/',
|
||||||
/// for flutter, this is includes also the ui library.
|
/// for flutter, this is includes also the ui library.
|
||||||
_copyExtraLibraries(String sdkOut, Map<String, String> locations) {
|
_copyExtraLibraries(String sdkOut, Map<String, Map<String, String>> locations) {
|
||||||
if (forDart2js) return;
|
if (forDart2js) return;
|
||||||
var base = path.fromUri(Platform.script);
|
var base = path.fromUri(Platform.script);
|
||||||
var dartDir = path.dirname(path.dirname(path.absolute(base)));
|
var dartDir = path.dirname(path.dirname(path.absolute(base)));
|
||||||
|
@ -341,7 +356,7 @@ _copyExtraLibraries(String sdkOut, Map<String, String> locations) {
|
||||||
var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', 'builtin.dart');
|
var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', 'builtin.dart');
|
||||||
var builtinLibraryOut = path.join(sdkOut, '_builtin', '_builtin.dart');
|
var builtinLibraryOut = path.join(sdkOut, '_builtin', '_builtin.dart');
|
||||||
_writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn));
|
_writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn));
|
||||||
locations['_builtin'] = path.join('_builtin', '_builtin.dart');
|
addLocation(locations, '_builtin', path.join('_builtin', '_builtin.dart'));
|
||||||
|
|
||||||
if (forFlutter) {
|
if (forFlutter) {
|
||||||
// Flutter repo has this layout:
|
// Flutter repo has this layout:
|
||||||
|
@ -356,7 +371,7 @@ _copyExtraLibraries(String sdkOut, Map<String, String> locations) {
|
||||||
var uiLibraryOut = path.join(sdkOut, 'ui', name);
|
var uiLibraryOut = path.join(sdkOut, 'ui', name);
|
||||||
_writeSync(uiLibraryOut, readInputFile(file.path));
|
_writeSync(uiLibraryOut, readInputFile(file.path));
|
||||||
}
|
}
|
||||||
locations['ui'] = 'ui/ui.dart';
|
addLocation(locations, 'ui', path.join('ui', 'ui.dart'));
|
||||||
|
|
||||||
if (!forFlutterRelease) {
|
if (!forFlutterRelease) {
|
||||||
// vmservice should be present unless we build release flavor of Flutter.
|
// vmservice should be present unless we build release flavor of Flutter.
|
||||||
|
@ -368,22 +383,23 @@ _copyExtraLibraries(String sdkOut, Map<String, String> locations) {
|
||||||
var libraryOut = path.join(sdkOut, 'vmservice_io', file);
|
var libraryOut = path.join(sdkOut, 'vmservice_io', file);
|
||||||
_writeSync(libraryOut, readInputFile(libraryIn));
|
_writeSync(libraryOut, readInputFile(libraryIn));
|
||||||
}
|
}
|
||||||
locations['vmservice_sky'] =
|
addLocation(locations, 'vmservice_sky',
|
||||||
path.join('vmservice_io', 'vmservice_io.dart');
|
path.join('vmservice_io', 'vmservice_io.dart'));
|
||||||
locations['_vmservice'] = path.join('vmservice', 'vmservice.dart');
|
addLocation(
|
||||||
|
locations, '_vmservice', path.join('vmservice', 'vmservice.dart'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyPatch(SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut,
|
_applyPatch(SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut,
|
||||||
Map<String, String> locations) {
|
Map<String, Map<String, String>> locations) {
|
||||||
var libraryOut = path.join(sdkLibIn, library.path);
|
var libraryOut = path.join(sdkLibIn, library.path);
|
||||||
var libraryIn = libraryOut;
|
var libraryIn = libraryOut;
|
||||||
|
|
||||||
var libraryFile = getInputFile(libraryIn, canBeMissing: true);
|
var libraryFile = getInputFile(libraryIn, canBeMissing: true);
|
||||||
if (libraryFile != null) {
|
if (libraryFile != null) {
|
||||||
locations[Uri.parse(library.shortName).path] =
|
addLocation(locations, Uri.parse(library.shortName).path,
|
||||||
path.relative(libraryOut, from: sdkLibIn);
|
path.relative(libraryOut, from: sdkLibIn));
|
||||||
var outPaths = <String>[libraryOut];
|
var outPaths = <String>[libraryOut];
|
||||||
var libraryContents = libraryFile.readAsStringSync();
|
var libraryContents = libraryFile.readAsStringSync();
|
||||||
|
|
||||||
|
@ -806,3 +822,9 @@ List<SdkLibrary> _getSdkLibraries(String contents) {
|
||||||
parseCompilationUnit(contents).accept(libraryBuilder);
|
parseCompilationUnit(contents).accept(libraryBuilder);
|
||||||
return libraryBuilder.librariesMap.sdkLibraries;
|
return libraryBuilder.librariesMap.sdkLibraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addLocation(Map<String, Map<String, String>> locations, String libraryName,
|
||||||
|
String libraryPath) {
|
||||||
|
assert(locations[libraryName] == null);
|
||||||
|
locations[libraryName] = {'uri': '${path.toUri(libraryPath)}'};
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue