Skip to content

Commit

Permalink
Reapply CL: first step for modular support in fasta
Browse files Browse the repository at this point in the history
BUG=
R=scheglov@google.com

Review-Url: https://codereview.chromium.org/2894283002 .
  • Loading branch information
sigmundch committed May 20, 2017
1 parent 58851f2 commit 011f8c5
Show file tree
Hide file tree
Showing 48 changed files with 1,258 additions and 148 deletions.
3 changes: 0 additions & 3 deletions pkg/compiler/lib/src/kernel/fasta_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,6 @@ class KernelTargetForDart2js extends KernelTarget {

@override
void runBuildTransformations() {}

@override
void runLinkTransformations(_) {}
}

/// Specializes [DillTarget] to build kernel for dart2js: JS-specific libraries
Expand Down
24 changes: 0 additions & 24 deletions pkg/front_end/lib/compiler_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@

library front_end.compiler_options;

import 'dart:async';

import 'package:front_end/src/base/performace_logger.dart';
import 'package:front_end/src/incremental/byte_store.dart';

import 'compilation_error.dart';
import 'file_system.dart';
import 'physical_file_system.dart';
import 'src/simple_error.dart';

/// Default error handler used by [CompilerOptions.onError].
void defaultErrorHandler(CompilationError error) => throw error;
Expand Down Expand Up @@ -150,24 +147,3 @@ class CompilerOptions {
// SDK itself.
List<Uri> additionalLibraries = [];
}

Future<bool> validateOptions(CompilerOptions options) async {
var fs = options.fileSystem;
var root = options.sdkRoot;

bool _report(String msg) {
options.onError(new SimpleError(msg));
return false;
}

if (root != null && !await fs.entityForUri(root).exists()) {
return _report("SDK root directory not found: ${options.sdkRoot}");
}

var summary = options.sdkSummary;
if (summary != null && !await fs.entityForUri(summary).exists()) {
return _report("SDK summary not found: ${options.sdkSummary}");
}

return true;
}
89 changes: 74 additions & 15 deletions pkg/front_end/lib/kernel_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ library front_end.kernel_generator;
import 'compiler_options.dart';
import 'dart:async' show Future;
import 'dart:async';
import 'package:front_end/physical_file_system.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'src/fasta/dill/dill_target.dart' show DillTarget;
import 'src/fasta/errors.dart' show InputError;
import 'src/fasta/kernel/kernel_target.dart' show KernelTarget;
Expand All @@ -29,15 +29,13 @@ import 'src/simple_error.dart';
/// If `compileSdk` in [options] is true, the generated program will include
/// code for the SDK.
///
/// If summaries are provided in [options], they may be used to speed up
/// analysis. If in addition `compileSdk` is false, this will speed up
/// compilation, as no source of the sdk will be generated. Note however, that
/// summaries for application code can also speed up analysis, but they will not
/// take the place of Dart source code (since the Dart source code is still
/// needed to access the contents of method bodies).
/// If summaries are provided in [options], they will be used to speed up
/// the process. If in addition `compileSdk` is false, then the resulting
/// program will not contain the sdk contents. This is useful when building apps
/// for platforms that already embed the sdk (e.g. the VM), so there is no need
/// to spend time and space rebuilding it.
Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
var fs = options.fileSystem;

report(String msg) {
options.onError(new SimpleError(msg));
return null;
Expand All @@ -47,24 +45,27 @@ Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
return report("Entry-point file not found: $source");
}

if (!await validateOptions(options)) return null;
var pOptions = new ProcessedOptions(options);

if (!await pOptions.validateOptions()) return null;

try {
TranslateUri uriTranslator = await TranslateUri.parse(
PhysicalFileSystem.instance, null, options.packagesFileUri);
TranslateUri uriTranslator = await pOptions.getUriTranslator();

var dillTarget =
new DillTarget(new Ticker(isVerbose: false), uriTranslator);
var summary = options.sdkSummary;
if (summary != null) dillTarget.read(summary);
var summary = await pOptions.sdkSummaryProgram;
if (summary != null) {
dillTarget.loader.appendLibraries(summary);
}

var kernelTarget = new KernelTarget(
options.fileSystem, dillTarget, uriTranslator, options.strongMode);
kernelTarget.read(source);

await dillTarget.buildOutlines();
await kernelTarget.buildOutlines();
Program program = await kernelTarget.buildProgram();
Program program = await kernelTarget.buildProgram(trimDependencies: true);

if (kernelTarget.errors.isNotEmpty) {
kernelTarget.errors.forEach(report);
Expand Down Expand Up @@ -121,5 +122,63 @@ Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
/// obtained from?
Future<Program> kernelForBuildUnit(
List<Uri> sources, CompilerOptions options) async {
throw new UnimplementedError("kernel for build-unit is not implemented");
var fs = options.fileSystem;
report(String msg) {
options.onError(new SimpleError(msg));
return null;
}

if (!options.chaseDependencies) {
// TODO(sigmund): add support, most likely we can do so by adding a wrapper
// on top of filesystem that restricts reads to a set of known files.
report("hermetic mode (chaseDependencies = false) is not implemented");
return null;
}

for (var source in sources) {
if (!await fs.entityForUri(source).exists()) {
return report("Entry-point file not found: $source");
}
}

var pOptions = new ProcessedOptions(options);

if (!await pOptions.validateOptions()) return null;

try {
TranslateUri uriTranslator = await pOptions.getUriTranslator();

var dillTarget =
new DillTarget(new Ticker(isVerbose: false), uriTranslator);
var summary = await pOptions.sdkSummaryProgram;
if (summary != null) {
dillTarget.loader.appendLibraries(summary);
}

// TODO(sigmund): this is likely not going to work if done naively: if
// summaries contain external references we need to ensure they are loaded
// in a specific order.
for (var inputSummary in await pOptions.inputSummariesPrograms) {
dillTarget.loader.appendLibraries(inputSummary);
}

await dillTarget.buildOutlines();

var kernelTarget = new KernelTarget(
options.fileSystem, dillTarget, uriTranslator, options.strongMode);
sources.forEach(kernelTarget.read);
await kernelTarget.buildOutlines();

Program program = await kernelTarget.buildProgram(trimDependencies: true);

if (kernelTarget.errors.isNotEmpty) {
kernelTarget.errors.forEach(report);
return null;
}

return program;
} on InputError catch (e) {
options.onError(new SimpleError(e.format()));
return null;
}
}
108 changes: 69 additions & 39 deletions pkg/front_end/lib/src/base/processed_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

import 'dart:async';

import 'package:analyzer/src/summary/idl.dart';
import 'package:front_end/compiler_options.dart';
import 'package:front_end/file_system.dart';
import 'package:front_end/src/fasta/translate_uri.dart';
import 'package:front_end/src/base/performace_logger.dart';
import 'package:front_end/src/incremental/byte_store.dart';
import 'package:front_end/src/simple_error.dart';
import 'package:package_config/packages_file.dart' as package_config;
import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;

/// Wrapper around [CompilerOptions] which exposes the options in a form useful
/// to the front end implementation.
Expand All @@ -32,13 +33,18 @@ class ProcessedOptions {
/// or `null` if it has not been computed yet.
TranslateUri _uriTranslator;

/// The summary bundle for the SDK, or `null` if it has not been read yet.
PackageBundle _sdkSummary;
/// The SDK summary, or `null` if it has not been read yet.
Program _sdkSummaryProgram;

/// The summary for each uri in `options.inputSummaries`.
List<Program> _inputSummariesPrograms;

/// The location of the SDK, or `null` if the location hasn't been determined
/// yet.
Uri _sdkRoot;

Uri get sdkRoot => _sdkRoot ??= _normalizeSdkRoot();

/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
ProcessedOptions(CompilerOptions rawOptions) : this._raw = rawOptions;

Expand All @@ -52,6 +58,31 @@ class ProcessedOptions {
return _raw.byteStore;
}

/// Runs various validations checks on the input options. For instance,
/// if an option is a path to a file, it checks that the file exists.
Future<bool> validateOptions() async {
var fs = _raw.fileSystem;
var root = _raw.sdkRoot;

bool _report(String msg) {
_raw.onError(new SimpleError(msg));
return false;
}

if (root != null && !await fs.entityForUri(root).exists()) {
return _report("SDK root directory not found: ${_raw.sdkRoot}");
}

var summary = _raw.sdkSummary;
if (summary != null && !await fs.entityForUri(summary).exists()) {
return _report("SDK summary not found: ${_raw.sdkSummary}");
}

// TODO(sigmund): add checks for options that are meant to be disjoint (like
// sdkRoot and sdkSummary).
return true;
}

/// Determine whether to generate code for the SDK when compiling a
/// whole-program.
bool get compileSdk => _raw.compileSdk;
Expand All @@ -70,28 +101,29 @@ class ProcessedOptions {
/// Whether to interpret Dart sources in strong-mode.
bool get strongMode => _raw.strongMode;

/// Get the summary bundle for the SDK.
///
/// This is an asynchronous getter since file system operations are required.
Future<PackageBundle> getSdkSummary() async {
if (_sdkSummary == null) {
Uri summaryLocation;
if (_raw.sdkSummary != null) {
// Options sdkSummary and sdkRoot are mutually exclusive.
assert(_raw.sdkRoot == null);
// No need to look for the SDK; we were told where the SDK summary is.
summaryLocation = _raw.sdkSummary;
} else {
// Need to look for the SDK summary inside the SDK.
var sdkRoot = await _getSdkRoot();
summaryLocation = sdkRoot.resolve(
'lib/_internal/' + (_raw.strongMode ? 'strong.sum' : 'spec.sum'));
}
var summaryBytes =
await fileSystem.entityForUri(summaryLocation).readAsBytes();
_sdkSummary = new PackageBundle.fromBuffer(summaryBytes);
/// Get an outline program that summarizes the SDK.
Future<Program> get sdkSummaryProgram async {
if (_sdkSummaryProgram == null) {
if (_raw.sdkSummary == null) return null;
_sdkSummaryProgram = await _loadProgram(_raw.sdkSummary);
}
return _sdkSummaryProgram;
}

/// Get the summary programs for each of the underlying `inputSummaries`
/// provided via [CompilerOptions].
Future<List<Program>> get inputSummariesPrograms async {
if (_inputSummariesPrograms == null) {
var uris = _raw.inputSummaries;
if (uris == null || uris.isEmpty) return const <Program>[];
_inputSummariesPrograms = await Future.wait(uris.map(_loadProgram));
}
return _sdkSummary;
return _inputSummariesPrograms;
}

Future<Program> _loadProgram(Uri uri) async {
var bytes = await fileSystem.entityForUri(uri).readAsBytes();
return loadProgramFromBytes(bytes)..unbindCanonicalNames();
}

/// Get the [TranslateUri] which resolves "package:" and "dart:" URIs.
Expand Down Expand Up @@ -132,21 +164,19 @@ class ProcessedOptions {
///
/// This is an asynchronous getter since file system operations may be
/// required to locate the SDK.
Future<Uri> _getSdkRoot() async {
if (_sdkRoot == null) {
// If an SDK summary location was provided, the SDK itself should not be
// needed.
assert(_raw.sdkSummary == null);
if (_raw.sdkRoot == null) {
// TODO(paulberry): implement the algorithm for finding the SDK
// automagically.
throw new UnimplementedError();
}
_sdkRoot = _raw.sdkRoot;
if (!_sdkRoot.path.endsWith('/')) {
_sdkRoot = _sdkRoot.replace(path: _sdkRoot.path + '/');
}
Uri _normalizeSdkRoot() {
// If an SDK summary location was provided, the SDK itself should not be
// needed.
assert(_raw.sdkSummary == null);
if (_raw.sdkRoot == null) {
// TODO(paulberry): implement the algorithm for finding the SDK
// automagically.
throw new UnimplementedError();
}
var root = _raw.sdkRoot;
if (!root.path.endsWith('/')) {
root = root.replace(path: _sdkRoot.path + '/');
}
return _sdkRoot;
return root;
}
}
Loading

0 comments on commit 011f8c5

Please sign in to comment.