| Index: pkg/front_end/lib/kernel_generator.dart
|
| diff --git a/pkg/front_end/lib/kernel_generator.dart b/pkg/front_end/lib/kernel_generator.dart
|
| index d6a40a542de351697f51fc9a63b4edce6856b97c..e0ba4c782e326b5dcb2b06f745b1e2e2acdbd823 100644
|
| --- a/pkg/front_end/lib/kernel_generator.dart
|
| +++ b/pkg/front_end/lib/kernel_generator.dart
|
| @@ -5,14 +5,19 @@
|
| /// Defines the front-end API for converting source code to Dart Kernel objects.
|
| library front_end.kernel_generator;
|
|
|
| +import 'compiler_options.dart';
|
| import 'dart:async' show Future;
|
| import 'dart:async';
|
| -
|
| +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;
|
| import 'package:kernel/kernel.dart' show Program;
|
| -
|
| -import 'compiler_options.dart';
|
| -import 'src/base/processed_options.dart';
|
| -import 'src/kernel_generator_impl.dart';
|
| +import 'package:kernel/target/targets.dart' show TargetFlags;
|
| +import 'package:kernel/target/vm_fasta.dart' show VmFastaTarget;
|
| +import 'src/fasta/ticker.dart' show Ticker;
|
| +import 'src/fasta/translate_uri.dart' show TranslateUri;
|
| +import 'src/simple_error.dart';
|
|
|
| /// Generates a kernel representation of the program whose main library is in
|
| /// the given [source].
|
| @@ -26,36 +31,73 @@ import 'src/kernel_generator_impl.dart';
|
| /// If `compileSdk` in [options] is true, the generated program will include
|
| /// code for the SDK.
|
| ///
|
| -/// If summaries are provided in [options], the compiler will use them instead
|
| -/// of compiling the libraries contained in those summaries. This is useful, for
|
| -/// example, when compiling for platforms that already embed those sources (like
|
| -/// the sdk in the standalone VM).
|
| -///
|
| -/// The input [source] is expected to be a script with a main method, otherwise
|
| -/// an error is reported.
|
| -// TODO(sigmund): rename to kernelForScript?
|
| +/// 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 pOptions = new ProcessedOptions(options, false, [source]);
|
| - var program = (await generateKernel(pOptions))?.program;
|
| - if (program == null) return null;
|
| -
|
| - if (program.mainMethod == null) {
|
| - pOptions.reportError("No 'main' method found.");
|
| + var fs = options.fileSystem;
|
| + report(String msg) {
|
| + options.onError(new SimpleError(msg));
|
| return null;
|
| }
|
|
|
| - return program;
|
| + 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,
|
| + new VmFastaTarget(new TargetFlags(strongMode: options.strongMode)));
|
| + var summary = await pOptions.sdkSummaryProgram;
|
| + if (summary != null) {
|
| + dillTarget.loader.appendLibraries(summary);
|
| + }
|
| +
|
| + var kernelTarget =
|
| + new KernelTarget(options.fileSystem, dillTarget, uriTranslator);
|
| + kernelTarget.read(source);
|
| +
|
| + await dillTarget.buildOutlines();
|
| + await kernelTarget.buildOutlines();
|
| + Program program = await kernelTarget.buildProgram(trimDependencies: true);
|
| +
|
| + if (kernelTarget.errors.isNotEmpty) {
|
| + kernelTarget.errors.forEach(report);
|
| + return null;
|
| + }
|
| +
|
| + if (program.mainMethod == null) {
|
| + return report("No 'main' method found.");
|
| + }
|
| +
|
| + if (!options.compileSdk) {
|
| + // TODO(sigmund): ensure that the result is not including
|
| + // sources for the sdk, only external references.
|
| + }
|
| + return program;
|
| + } on InputError catch (e) {
|
| + options.onError(new SimpleError(e.format()));
|
| + return null;
|
| + }
|
| }
|
|
|
| -/// Generates a kernel representation for a build unit containing [sources].
|
| +/// Generates a kernel representation for a build unit.
|
| ///
|
| -/// A build unit is a collection of libraries that are compiled together.
|
| -/// Libraries in the build unit may depend on each other and may have
|
| -/// dependencies to libraries in other build units. Unlinke library
|
| -/// dependencies, build unit dependencies must be acyclic.
|
| +/// Intended for modular compilation.
|
| ///
|
| -/// This API is intended for modular compilation. Dependencies to other build
|
| -/// units are specified using [CompilerOptions.inputSummaries].
|
| +/// The build unit by default contains only the source files in [sources]
|
| +/// (including library and part files), but if
|
| +/// [CompilerOptions.chaseDependencies] is true, it may include some additional
|
| +/// source files. All of the library files are transformed into Dart Kernel
|
| +/// Library objects.
|
| ///
|
| /// By default, the compilation process is hermetic, meaning that the only files
|
| /// which will be read are those listed in [sources],
|
| @@ -73,11 +115,72 @@ Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
|
| /// are also listed in the build unit sources, otherwise an error results. (It
|
| /// is not permitted to refer to a part file declared in another build unit).
|
| ///
|
| -/// The return value is a [Program] object with no main method set. The
|
| -/// [Program] includes external libraries for those libraries loaded through
|
| -/// summaries.
|
| +/// The return value is a [Program] object with no main method set.
|
| +/// TODO(paulberry): would it be better to define a data type in kernel to
|
| +/// represent a bundle of all the libraries in a given build unit?
|
| +///
|
| +/// TODO(paulberry): does additional information need to be output to allow the
|
| +/// caller to match up referenced elements to the summary files they were
|
| +/// obtained from?
|
| Future<Program> kernelForBuildUnit(
|
| List<Uri> sources, CompilerOptions options) async {
|
| - return (await generateKernel(new ProcessedOptions(options, true, sources)))
|
| - ?.program;
|
| + 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,
|
| + new VmFastaTarget(new TargetFlags(strongMode: options.strongMode)));
|
| + 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);
|
| + 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;
|
| + }
|
| }
|
|
|