mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:11:19 +00:00
Unifying compiler context
Changes in this CL: - Updated CompilerContext: - it now contains a ProcessedOptions object - it no longer depends on CompilerCommandLine/CommandLine - it delegates to ProcessedOptions.report so all error reporting goes to one single place. - use "withContext" term instead of "withGlobalOptions" to be more clear about the intent - Changes in public API - added more options that correspond to flags in command-line fasta tools - default onError is different: we now use the command_line_reporting report, which prints and throws on fatal messages, but doesn't throw eagerly on all messages as before. - introduced "printMessages" option: make it easy to have both onError + command_line_reporting (kernel-service.dart is the main use case at this time, other ideas welcome!) - renamed CompilationError to CompilationMessage - Other changes - set exit code is done on report, not on format - fixed corner cases not covered in previous CL - error reporting with missing-main needs to happen with a context - missing error cases when inferring .packages and input URIs are not file:* URIs Ideas for follow up after this CL: - combine ProcessedOptions and CompilerContext into a single class (or extend one from the other) - switch onError to a stream R=ahe@google.com Review-Url: https://codereview.chromium.org/2982093003 .
This commit is contained in:
parent
749b61f8ec
commit
1aa139bc94
|
@ -17,7 +17,6 @@ import 'package:analyzer/src/generated/scanner.dart';
|
||||||
import 'package:analyzer/src/generated/source.dart';
|
import 'package:analyzer/src/generated/source.dart';
|
||||||
import 'package:analyzer/src/generated/utilities_dart.dart';
|
import 'package:analyzer/src/generated/utilities_dart.dart';
|
||||||
import 'package:front_end/src/base/instrumentation.dart' as fasta;
|
import 'package:front_end/src/base/instrumentation.dart' as fasta;
|
||||||
import 'package:front_end/src/fasta/compiler_command_line.dart' as fasta;
|
|
||||||
import 'package:front_end/src/fasta/compiler_context.dart' as fasta;
|
import 'package:front_end/src/fasta/compiler_context.dart' as fasta;
|
||||||
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
||||||
as fasta;
|
as fasta;
|
||||||
|
@ -135,7 +134,7 @@ class _ElementNamer {
|
||||||
|
|
||||||
class _FrontEndInferenceTest extends BaseAnalysisDriverTest {
|
class _FrontEndInferenceTest extends BaseAnalysisDriverTest {
|
||||||
Future<String> runTest(String path, String code) {
|
Future<String> runTest(String path, String code) {
|
||||||
return fasta.CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
return fasta.CompilerContext.runWithDefaultOptions((_) async {
|
||||||
Uri uri = provider.pathContext.toUri(path);
|
Uri uri = provider.pathContext.toUri(path);
|
||||||
|
|
||||||
List<int> lineStarts = new LineInfo.fromContent(code).lineStarts;
|
List<int> lineStarts = new LineInfo.fromContent(code).lineStarts;
|
||||||
|
|
|
@ -23,8 +23,8 @@ main(List<String> args) async {
|
||||||
..target = new Dart2jsTarget(new TargetFlags())
|
..target = new Dart2jsTarget(new TargetFlags())
|
||||||
..packagesFileUri = Uri.base.resolve('.packages')
|
..packagesFileUri = Uri.base.resolve('.packages')
|
||||||
..compileSdk = true
|
..compileSdk = true
|
||||||
..linkedDependencies = [Uri.base.resolve(flags['platform'])]
|
..setExitCodeOnProblem = true
|
||||||
..onError = errorHandler;
|
..linkedDependencies = [Uri.base.resolve(flags['platform'])];
|
||||||
|
|
||||||
if (flags.rest.isEmpty) {
|
if (flags.rest.isEmpty) {
|
||||||
var script = relativizeUri(Platform.script);
|
var script = relativizeUri(Platform.script);
|
||||||
|
@ -39,11 +39,6 @@ main(List<String> args) async {
|
||||||
await writeProgramToBinary(program, flags['out']);
|
await writeProgramToBinary(program, flags['out']);
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorHandler(CompilationError e) {
|
|
||||||
exitCode = 1;
|
|
||||||
print(e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArgParser _argParser = new ArgParser()
|
ArgParser _argParser = new ArgParser()
|
||||||
..addOption('platform',
|
..addOption('platform',
|
||||||
help: 'location of the precompiled dart2js sdk',
|
help: 'location of the precompiled dart2js sdk',
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright (c) 2016, 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.
|
|
||||||
|
|
||||||
/// Defines the API for the front end to communicate information about
|
|
||||||
/// compilation errors to clients.
|
|
||||||
library front_end.compilation_error;
|
|
||||||
|
|
||||||
import 'package:source_span/source_span.dart' show SourceSpan;
|
|
||||||
|
|
||||||
/// A single error that occurred during compilation, and information about where
|
|
||||||
/// it occurred and how to fix it.
|
|
||||||
///
|
|
||||||
/// TODO(paulberry): add a reference to the analyzer error code.
|
|
||||||
///
|
|
||||||
/// Not intended to be implemented or extended by clients.
|
|
||||||
// TODO(sigmund): rename to CompliationMessage
|
|
||||||
abstract class CompilationError {
|
|
||||||
/// A text description of the compile error.
|
|
||||||
String get message;
|
|
||||||
|
|
||||||
/// A suggestion for the user to hint them on how to fix the error. May be
|
|
||||||
/// `null`.
|
|
||||||
String get tip;
|
|
||||||
|
|
||||||
/// The source span where the error occurred.
|
|
||||||
SourceSpan get span;
|
|
||||||
}
|
|
38
pkg/front_end/lib/compilation_message.dart
Normal file
38
pkg/front_end/lib/compilation_message.dart
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright (c) 2016, 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.
|
||||||
|
|
||||||
|
/// Defines the API for the front end to communicate information about
|
||||||
|
/// compilation messages to clients.
|
||||||
|
library front_end.compilation_message;
|
||||||
|
|
||||||
|
import 'package:source_span/source_span.dart' show SourceSpan;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/severity.dart' show Severity;
|
||||||
|
export 'package:front_end/src/fasta/severity.dart' show Severity;
|
||||||
|
|
||||||
|
/// A single message, typically an error, reported during compilation, and
|
||||||
|
/// information about where it occurred and suggestions on how to fix it.
|
||||||
|
///
|
||||||
|
/// Not intended to be implemented or extended by clients.
|
||||||
|
abstract class CompilationMessage {
|
||||||
|
/// A text description of the problem.
|
||||||
|
String get message;
|
||||||
|
|
||||||
|
/// A suggestion for how to fix the problem. May be `null`.
|
||||||
|
String get tip;
|
||||||
|
|
||||||
|
/// The source span where the error occurred.
|
||||||
|
SourceSpan get span;
|
||||||
|
|
||||||
|
/// The severity level of the error.
|
||||||
|
Severity get severity;
|
||||||
|
|
||||||
|
/// The corresponding analyzer error code, or null if there is no
|
||||||
|
/// corresponding message in analyzer.
|
||||||
|
String get analyzerCode;
|
||||||
|
|
||||||
|
/// The corresponding dart2js error code, or null if there is no corresponding
|
||||||
|
/// message in dart2js.
|
||||||
|
String get dart2jsCode;
|
||||||
|
}
|
|
@ -8,15 +8,12 @@ import 'package:front_end/src/base/performace_logger.dart';
|
||||||
import 'package:front_end/src/incremental/byte_store.dart';
|
import 'package:front_end/src/incremental/byte_store.dart';
|
||||||
import 'package:kernel/target/targets.dart' show Target;
|
import 'package:kernel/target/targets.dart' show Target;
|
||||||
|
|
||||||
import 'compilation_error.dart';
|
import 'compilation_message.dart';
|
||||||
import 'file_system.dart';
|
import 'file_system.dart';
|
||||||
import 'physical_file_system.dart';
|
import 'physical_file_system.dart';
|
||||||
|
|
||||||
/// Default error handler used by [CompilerOptions.onError].
|
|
||||||
void defaultErrorHandler(CompilationError error) => throw error;
|
|
||||||
|
|
||||||
/// Callback used to report errors encountered during compilation.
|
/// Callback used to report errors encountered during compilation.
|
||||||
typedef void ErrorHandler(CompilationError error);
|
typedef void ErrorHandler(CompilationMessage error);
|
||||||
|
|
||||||
/// Front-end options relevant to compiler back ends.
|
/// Front-end options relevant to compiler back ends.
|
||||||
///
|
///
|
||||||
|
@ -43,9 +40,21 @@ class CompilerOptions {
|
||||||
|
|
||||||
/// Callback to which compilation errors should be delivered.
|
/// Callback to which compilation errors should be delivered.
|
||||||
///
|
///
|
||||||
/// By default, the first error will be reported by throwing an exception of
|
/// By default, when no callback is provided, the compiler will report
|
||||||
/// type [CompilationError].
|
/// messages on the console and will throw when fatal errors are discovered.
|
||||||
ErrorHandler onError = defaultErrorHandler;
|
ErrorHandler onError;
|
||||||
|
|
||||||
|
/// Whether messages should be reported using the compiler's internal
|
||||||
|
/// reporting mechanism.
|
||||||
|
///
|
||||||
|
/// If no [onError] handler is provided, the default is true. If an [onError]
|
||||||
|
/// handler is provided, the default is false. Setting this to true will
|
||||||
|
/// ensure that error messages are printed in the console and that fatal
|
||||||
|
/// errors cause an exception.
|
||||||
|
// TODO(sigmund): add also an API for formatting errors and provide a default
|
||||||
|
// formatter. This way user can configure error style in the console and in
|
||||||
|
// generated code that contains error messages.
|
||||||
|
bool reportMessages;
|
||||||
|
|
||||||
/// URI of the ".packages" file (typically a "file:" URI).
|
/// URI of the ".packages" file (typically a "file:" URI).
|
||||||
///
|
///
|
||||||
|
@ -197,4 +206,30 @@ class CompilerOptions {
|
||||||
/// Whether to set the exit code to non-zero if any problem (including
|
/// Whether to set the exit code to non-zero if any problem (including
|
||||||
/// warning, etc.) is encountered during compilation.
|
/// warning, etc.) is encountered during compilation.
|
||||||
bool setExitCodeOnProblem = false;
|
bool setExitCodeOnProblem = false;
|
||||||
|
|
||||||
|
/// Whether to embed the input sources in generated kernel programs.
|
||||||
|
///
|
||||||
|
/// The kernel `Program` API includes a `uriToSource` map field that is used
|
||||||
|
/// to embed the entire contents of the source files. This part of the kernel
|
||||||
|
/// API is in flux and it is not necessary for some tools. Today it is used
|
||||||
|
/// for translating error locations and stack traces in the VM.
|
||||||
|
// TODO(sigmund): change the default.
|
||||||
|
bool embedSourceText = true;
|
||||||
|
|
||||||
|
/// Whether the compiler should throw as soon as it encounters a
|
||||||
|
/// compilation error.
|
||||||
|
// TODO(sigmund): change the default (issue #30194).
|
||||||
|
bool throwOnErrors = true;
|
||||||
|
|
||||||
|
/// Whether the compiler should throw as soon as it encounters a
|
||||||
|
/// compilation warning.
|
||||||
|
///
|
||||||
|
/// Typically used by developers to debug internals of the compiler.
|
||||||
|
bool throwOnWarnings = false;
|
||||||
|
|
||||||
|
/// Whether the compiler should throw as soon as it encounters a
|
||||||
|
/// compilation nit.
|
||||||
|
///
|
||||||
|
/// Typically used by developers to debug internals of the compiler.
|
||||||
|
bool throwOnNits = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
library front_end.front_end;
|
library front_end.front_end;
|
||||||
|
|
||||||
export 'compiler_options.dart';
|
export 'compiler_options.dart';
|
||||||
export 'compilation_error.dart';
|
export 'compilation_message.dart';
|
||||||
export 'kernel_generator.dart';
|
export 'kernel_generator.dart';
|
||||||
export 'summary_generator.dart';
|
export 'summary_generator.dart';
|
||||||
export 'file_system.dart';
|
export 'file_system.dart';
|
||||||
|
|
|
@ -13,6 +13,8 @@ import 'package:kernel/kernel.dart' show Program;
|
||||||
import 'compiler_options.dart';
|
import 'compiler_options.dart';
|
||||||
import 'src/base/processed_options.dart';
|
import 'src/base/processed_options.dart';
|
||||||
import 'src/fasta/fasta_codes.dart';
|
import 'src/fasta/fasta_codes.dart';
|
||||||
|
import 'src/fasta/compiler_context.dart';
|
||||||
|
import 'src/fasta/severity.dart';
|
||||||
import 'src/kernel_generator_impl.dart';
|
import 'src/kernel_generator_impl.dart';
|
||||||
|
|
||||||
/// Generates a kernel representation of the program whose main library is in
|
/// Generates a kernel representation of the program whose main library is in
|
||||||
|
@ -37,15 +39,17 @@ import 'src/kernel_generator_impl.dart';
|
||||||
// TODO(sigmund): rename to kernelForScript?
|
// TODO(sigmund): rename to kernelForScript?
|
||||||
Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
|
Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
|
||||||
var pOptions = new ProcessedOptions(options, false, [source]);
|
var pOptions = new ProcessedOptions(options, false, [source]);
|
||||||
var program = (await generateKernel(pOptions))?.program;
|
return await CompilerContext.runWithOptions(pOptions, (context) async {
|
||||||
if (program == null) return null;
|
var program = (await generateKernelInternal())?.program;
|
||||||
|
if (program == null) return null;
|
||||||
|
|
||||||
if (program.mainMethod == null) {
|
if (program.mainMethod == null) {
|
||||||
pOptions.reportMessage(messageMissingMain.withLocation(source, -1));
|
context.options
|
||||||
return null;
|
.report(messageMissingMain.withLocation(source, -1), Severity.error);
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
return program;
|
return program;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a kernel representation for a build unit containing [sources].
|
/// Generates a kernel representation for a build unit containing [sources].
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:front_end/compilation_error.dart';
|
import 'package:front_end/compilation_message.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/fasta/fasta_codes.dart';
|
import 'package:front_end/src/fasta/fasta_codes.dart';
|
||||||
|
import 'package:front_end/src/fasta/problems.dart' show unimplemented;
|
||||||
|
import 'package:front_end/src/fasta/severity.dart';
|
||||||
import 'package:front_end/src/fasta/ticker.dart';
|
import 'package:front_end/src/fasta/ticker.dart';
|
||||||
import 'package:front_end/src/fasta/uri_translator.dart';
|
import 'package:front_end/src/fasta/uri_translator.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/fasta/problems.dart' show unimplemented;
|
|
||||||
import 'package:front_end/src/incremental/byte_store.dart';
|
import 'package:front_end/src/incremental/byte_store.dart';
|
||||||
import 'package:front_end/src/multi_root_file_system.dart';
|
import 'package:front_end/src/multi_root_file_system.dart';
|
||||||
import 'package:kernel/kernel.dart'
|
import 'package:kernel/kernel.dart'
|
||||||
|
@ -24,6 +25,8 @@ import 'package:package_config/src/packages_impl.dart'
|
||||||
show NonFilePackagesDirectoryPackages, MapPackages;
|
show NonFilePackagesDirectoryPackages, MapPackages;
|
||||||
import 'package:package_config/packages_file.dart' as package_config;
|
import 'package:package_config/packages_file.dart' as package_config;
|
||||||
import 'package:source_span/source_span.dart' show SourceSpan, SourceLocation;
|
import 'package:source_span/source_span.dart' show SourceSpan, SourceLocation;
|
||||||
|
import 'package:front_end/src/fasta/command_line_reporting.dart'
|
||||||
|
as command_line_reporting;
|
||||||
|
|
||||||
/// All options needed for the front end implementation.
|
/// All options needed for the front end implementation.
|
||||||
///
|
///
|
||||||
|
@ -88,6 +91,14 @@ class ProcessedOptions {
|
||||||
|
|
||||||
bool get setExitCodeOnProblem => _raw.setExitCodeOnProblem;
|
bool get setExitCodeOnProblem => _raw.setExitCodeOnProblem;
|
||||||
|
|
||||||
|
bool get embedSourceText => _raw.embedSourceText;
|
||||||
|
|
||||||
|
bool get throwOnErrors => _raw.throwOnErrors;
|
||||||
|
|
||||||
|
bool get throwOnWarnings => _raw.throwOnWarnings;
|
||||||
|
|
||||||
|
bool get throwOnNits => _raw.throwOnNits;
|
||||||
|
|
||||||
/// Like [CompilerOptions.chaseDependencies] but with the appropriate default
|
/// Like [CompilerOptions.chaseDependencies] but with the appropriate default
|
||||||
/// value filled in.
|
/// value filled in.
|
||||||
bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi;
|
bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi;
|
||||||
|
@ -100,10 +111,15 @@ class ProcessedOptions {
|
||||||
/// The entry-points provided to the compiler.
|
/// The entry-points provided to the compiler.
|
||||||
final List<Uri> inputs;
|
final List<Uri> inputs;
|
||||||
|
|
||||||
|
/// The Uri where output is generated, may be null.
|
||||||
|
final Uri output;
|
||||||
|
|
||||||
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
|
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
|
||||||
ProcessedOptions(CompilerOptions rawOptions,
|
ProcessedOptions(CompilerOptions rawOptions,
|
||||||
[this._modularApi = false, this.inputs = const []])
|
[this._modularApi = false, this.inputs = const [], this.output])
|
||||||
: this._raw = rawOptions,
|
: this._raw = rawOptions,
|
||||||
|
// TODO(sigmund, ahe): create ticker even earlier or pass in a stopwatch
|
||||||
|
// collecting time since the start of the VM.
|
||||||
ticker = new Ticker(isVerbose: rawOptions.verbose);
|
ticker = new Ticker(isVerbose: rawOptions.verbose);
|
||||||
|
|
||||||
/// The logger to report compilation progress.
|
/// The logger to report compilation progress.
|
||||||
|
@ -116,18 +132,34 @@ class ProcessedOptions {
|
||||||
return _raw.byteStore;
|
return _raw.byteStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportMessage(LocatedMessage message) {
|
bool get _reportMessages => _raw.reportMessages ?? (_raw.onError == null);
|
||||||
_raw.onError(new _CompilationMessage(message));
|
|
||||||
|
void report(LocatedMessage message, Severity severity) {
|
||||||
|
if (_raw.onError != null) {
|
||||||
|
_raw.onError(new _CompilationMessage(message, severity));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_reportMessages) command_line_reporting.report(message, severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reportMessageWithoutLocation(Message message) =>
|
void reportWithoutLocation(Message message, Severity severity) {
|
||||||
reportMessage(message.withLocation(null, -1));
|
if (_raw.onError != null) {
|
||||||
|
_raw.onError(
|
||||||
|
new _CompilationMessage(message.withLocation(null, -1), severity));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_reportMessages) {
|
||||||
|
command_line_reporting.reportWithoutLocation(message, severity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs various validations checks on the input options. For instance,
|
/// 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.
|
/// if an option is a path to a file, it checks that the file exists.
|
||||||
Future<bool> validateOptions() async {
|
Future<bool> validateOptions() async {
|
||||||
|
if (verbose) print(debugString());
|
||||||
|
|
||||||
if (inputs.isEmpty) {
|
if (inputs.isEmpty) {
|
||||||
reportMessageWithoutLocation(messageMissingInput);
|
reportWithoutLocation(messageMissingInput, Severity.error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,30 +172,31 @@ class ProcessedOptions {
|
||||||
if (source.scheme != 'dart' &&
|
if (source.scheme != 'dart' &&
|
||||||
source.scheme != 'packages' &&
|
source.scheme != 'packages' &&
|
||||||
!await fileSystem.entityForUri(source).exists()) {
|
!await fileSystem.entityForUri(source).exists()) {
|
||||||
reportMessageWithoutLocation(
|
reportWithoutLocation(
|
||||||
templateInputFileNotFound.withArguments('$source'));
|
templateInputFileNotFound.withArguments('$source'), Severity.error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_raw.sdkRoot != null &&
|
if (_raw.sdkRoot != null &&
|
||||||
!await fileSystem.entityForUri(sdkRoot).exists()) {
|
!await fileSystem.entityForUri(sdkRoot).exists()) {
|
||||||
reportMessageWithoutLocation(
|
reportWithoutLocation(
|
||||||
templateSdkRootNotFound.withArguments('$sdkRoot'));
|
templateSdkRootNotFound.withArguments('$sdkRoot'), Severity.error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var summary = sdkSummary;
|
var summary = sdkSummary;
|
||||||
if (summary != null && !await fileSystem.entityForUri(summary).exists()) {
|
if (summary != null && !await fileSystem.entityForUri(summary).exists()) {
|
||||||
reportMessageWithoutLocation(
|
reportWithoutLocation(
|
||||||
templateSdkSummaryNotFound.withArguments('$summary'));
|
templateSdkSummaryNotFound.withArguments('$summary'), Severity.error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compileSdk && summary != null) {
|
if (compileSdk && summary != null) {
|
||||||
reportMessageWithoutLocation(
|
reportWithoutLocation(
|
||||||
templateInternalProblemUnsupported.withArguments(
|
templateInternalProblemUnsupported.withArguments(
|
||||||
"The compileSdk and sdkSummary options are mutually exclusive"));
|
"The compileSdk and sdkSummary options are mutually exclusive"),
|
||||||
|
Severity.internalProblem);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -263,21 +296,31 @@ class ProcessedOptions {
|
||||||
/// This is an asynchronous getter since file system operations may be
|
/// This is an asynchronous getter since file system operations may be
|
||||||
/// required to locate/read the packages file.
|
/// required to locate/read the packages file.
|
||||||
Future<Packages> _getPackages() async {
|
Future<Packages> _getPackages() async {
|
||||||
if (_packages == null) {
|
if (_packages != null) return _packages;
|
||||||
if (_raw.packagesFileUri == null) {
|
if (_raw.packagesFileUri != null) {
|
||||||
if (inputs.length > 1) {
|
return _packages = await createPackagesFromFile(_raw.packagesFileUri);
|
||||||
// TODO(sigmund): consider not reporting an error if we would infer
|
|
||||||
// the same .packages file from all of the inputs.
|
|
||||||
reportMessageWithoutLocation(messageCantInferPackagesFromManyInputs);
|
|
||||||
_packages = Packages.noPackages;
|
|
||||||
} else {
|
|
||||||
_packages = await _findPackages(inputs.first);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_packages = await createPackagesFromFile(_raw.packagesFileUri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return _packages;
|
|
||||||
|
if (inputs.length > 1) {
|
||||||
|
// TODO(sigmund): consider not reporting an error if we would infer
|
||||||
|
// the same .packages file from all of the inputs.
|
||||||
|
reportWithoutLocation(
|
||||||
|
messageCantInferPackagesFromManyInputs, Severity.error);
|
||||||
|
return _packages = Packages.noPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
var input = inputs.first;
|
||||||
|
|
||||||
|
// When compiling the SDK the input files are normaly `dart:` URIs.
|
||||||
|
if (input.scheme == 'dart') return _packages = Packages.noPackages;
|
||||||
|
|
||||||
|
if (input.scheme == 'packages') {
|
||||||
|
report(messageCantInferPackagesFromPackageUri.withLocation(input, -1),
|
||||||
|
Severity.error);
|
||||||
|
return _packages = Packages.noPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _packages = await _findPackages(inputs.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [Packages] given the Uri to a `.packages` file.
|
/// Create a [Packages] given the Uri to a `.packages` file.
|
||||||
|
@ -287,9 +330,11 @@ class ProcessedOptions {
|
||||||
Map<String, Uri> map = package_config.parse(contents, file);
|
Map<String, Uri> map = package_config.parse(contents, file);
|
||||||
return new MapPackages(map);
|
return new MapPackages(map);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reportMessage(templateCannotReadPackagesFile
|
report(
|
||||||
.withArguments("$e")
|
templateCannotReadPackagesFile
|
||||||
.withLocation(file, -1));
|
.withArguments("$e")
|
||||||
|
.withLocation(file, -1),
|
||||||
|
Severity.error);
|
||||||
return Packages.noPackages;
|
return Packages.noPackages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,8 +363,10 @@ class ProcessedOptions {
|
||||||
Future<Packages> _findPackages(Uri scriptUri) async {
|
Future<Packages> _findPackages(Uri scriptUri) async {
|
||||||
var dir = scriptUri.resolve('.');
|
var dir = scriptUri.resolve('.');
|
||||||
if (!dir.isAbsolute) {
|
if (!dir.isAbsolute) {
|
||||||
reportMessageWithoutLocation(templateInternalProblemUnsupported
|
reportWithoutLocation(
|
||||||
.withArguments("Expected input Uri to be absolute: $scriptUri."));
|
templateInternalProblemUnsupported
|
||||||
|
.withArguments("Expected input Uri to be absolute: $scriptUri."),
|
||||||
|
Severity.internalProblem);
|
||||||
return Packages.noPackages;
|
return Packages.noPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,6 +460,56 @@ class ProcessedOptions {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String debugString() {
|
||||||
|
var sb = new StringBuffer();
|
||||||
|
writeList(String name, List elements) {
|
||||||
|
if (elements.isEmpty) {
|
||||||
|
sb.writeln('$name: <empty>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sb.writeln('$name:');
|
||||||
|
elements.forEach((s) {
|
||||||
|
sb.writeln(' - $s');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.writeln('Inputs: ${inputs}');
|
||||||
|
sb.writeln('Output: ${output}');
|
||||||
|
|
||||||
|
sb.writeln('Was error handler provided: '
|
||||||
|
'${_raw.onError == null ? "no" : "yes"}');
|
||||||
|
|
||||||
|
sb.writeln('FileSystem: ${_fileSystem.runtimeType} '
|
||||||
|
'(provided: ${_raw.fileSystem.runtimeType})');
|
||||||
|
|
||||||
|
writeList('Input Summaries', _raw.inputSummaries);
|
||||||
|
writeList('Linked Dependencies', _raw.linkedDependencies);
|
||||||
|
writeList('Multiroots', _raw.multiRoots);
|
||||||
|
|
||||||
|
sb.writeln('Modular: ${_modularApi}');
|
||||||
|
sb.writeln('Hermetic: ${!chaseDependencies}'
|
||||||
|
' (provided: ${!_raw.chaseDependencies})');
|
||||||
|
sb.writeln('Packages uri: ${_raw.packagesFileUri}');
|
||||||
|
sb.writeln('Packages: ${_packages}');
|
||||||
|
|
||||||
|
sb.writeln('Compile SDK: ${compileSdk}');
|
||||||
|
sb.writeln('SDK root: ${_sdkRoot} (provided: ${_raw.sdkRoot})');
|
||||||
|
sb.writeln('SDK summary: ${_sdkSummary} (provided: ${_raw.sdkSummary})');
|
||||||
|
|
||||||
|
sb.writeln('Strong: ${strongMode}');
|
||||||
|
sb.writeln('Target: ${_target?.name} (provided: ${_raw.target?.name})');
|
||||||
|
|
||||||
|
sb.writeln('throwOnErrorsAreFatal: ${throwOnErrors}');
|
||||||
|
sb.writeln('throwOnWarningsAreFatal: ${throwOnWarnings}');
|
||||||
|
sb.writeln('throwOnNits: ${throwOnNits}');
|
||||||
|
sb.writeln('exit on problem: ${setExitCodeOnProblem}');
|
||||||
|
sb.writeln('Embed sources: ${embedSourceText}');
|
||||||
|
sb.writeln('debugDump: ${debugDump}');
|
||||||
|
sb.writeln('verbose: ${verbose}');
|
||||||
|
sb.writeln('verify: ${verify}');
|
||||||
|
return '$sb';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [FileSystem] that only allows access to files that have been explicitly
|
/// A [FileSystem] that only allows access to files that have been explicitly
|
||||||
|
@ -441,19 +538,24 @@ class HermeticAccessException extends FileSystemException {
|
||||||
String toString() => message;
|
String toString() => message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps a [LocatedMessage] to implement the public [CompilationError] API.
|
/// Wraps a [LocatedMessage] to implement the public [CompilationMessage] API.
|
||||||
class _CompilationMessage implements CompilationError {
|
class _CompilationMessage implements CompilationMessage {
|
||||||
final LocatedMessage original;
|
final LocatedMessage _original;
|
||||||
|
final Severity severity;
|
||||||
|
|
||||||
String get message => original.message;
|
String get message => _original.message;
|
||||||
|
|
||||||
String get tip => original.tip;
|
String get tip => _original.tip;
|
||||||
|
|
||||||
|
String get analyzerCode => _original.code.analyzerCode;
|
||||||
|
|
||||||
|
String get dart2jsCode => _original.code.dart2jsCode;
|
||||||
|
|
||||||
SourceSpan get span =>
|
SourceSpan get span =>
|
||||||
new SourceLocation(original.charOffset, sourceUrl: original.uri)
|
new SourceLocation(_original.charOffset, sourceUrl: _original.uri)
|
||||||
.pointSpan();
|
.pointSpan();
|
||||||
|
|
||||||
_CompilationMessage(this.original);
|
_CompilationMessage(this._original, this.severity);
|
||||||
|
|
||||||
String toString() => message;
|
String toString() => message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ class ParsedArguments {
|
||||||
toString() => "ParsedArguments($options, $arguments)";
|
toString() => "ParsedArguments($options, $arguments)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Abstract parser for command-line options.
|
||||||
class CommandLine {
|
class CommandLine {
|
||||||
final Map<String, dynamic> options;
|
final Map<String, dynamic> options;
|
||||||
|
|
||||||
|
|
|
@ -34,16 +34,9 @@ const bool hideWarnings = false;
|
||||||
/// command-line tool. This includes source snippets and different colors based
|
/// command-line tool. This includes source snippets and different colors based
|
||||||
/// on [severity].
|
/// on [severity].
|
||||||
///
|
///
|
||||||
/// It is a assumed that a formatted message is reported to a user, so
|
|
||||||
/// [exitCode] is also set depending on the value of
|
|
||||||
/// `CompilerContext.current.options.setExitCodeOnProblem`.
|
|
||||||
///
|
|
||||||
/// This is shared implementation used by methods below, and isn't intended to
|
/// This is shared implementation used by methods below, and isn't intended to
|
||||||
/// be called directly.
|
/// be called directly.
|
||||||
String formatInternal(Message message, Severity severity, Uri uri, int offset) {
|
String formatInternal(Message message, Severity severity, Uri uri, int offset) {
|
||||||
if (CompilerContext.current.options.setExitCodeOnProblem) {
|
|
||||||
exitCode = 1;
|
|
||||||
}
|
|
||||||
String text =
|
String text =
|
||||||
"${severityName(severity, capitalized: true)}: ${message.message}";
|
"${severityName(severity, capitalized: true)}: ${message.message}";
|
||||||
if (message.tip != null) {
|
if (message.tip != null) {
|
||||||
|
@ -107,16 +100,16 @@ bool isHidden(Severity severity) {
|
||||||
bool isFatal(Severity severity) {
|
bool isFatal(Severity severity) {
|
||||||
switch (severity) {
|
switch (severity) {
|
||||||
case Severity.error:
|
case Severity.error:
|
||||||
return CompilerContext.current.options.errorsAreFatal;
|
return CompilerContext.current.options.throwOnErrors;
|
||||||
|
|
||||||
case Severity.internalProblem:
|
case Severity.internalProblem:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Severity.nit:
|
case Severity.nit:
|
||||||
return CompilerContext.current.options.nitsAreFatal;
|
return CompilerContext.current.options.throwOnNits;
|
||||||
|
|
||||||
case Severity.warning:
|
case Severity.warning:
|
||||||
return CompilerContext.current.options.warningsAreFatal;
|
return CompilerContext.current.options.throwOnWarnings;
|
||||||
}
|
}
|
||||||
return unhandled("$severity", "isFatal", -1, null);
|
return unhandled("$severity", "isFatal", -1, null);
|
||||||
}
|
}
|
||||||
|
@ -139,11 +132,25 @@ String severityName(Severity severity, {bool capitalized: false}) {
|
||||||
return unhandled("$severity", "severityName", -1, null);
|
return unhandled("$severity", "severityName", -1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Print a formatted message and throw when errors are treated as fatal.
|
||||||
|
/// Also set [exitCode] depending on the value of
|
||||||
|
/// `CompilerContext.current.options.setExitCodeOnProblem`.
|
||||||
void _printAndThrowIfFatal(
|
void _printAndThrowIfFatal(
|
||||||
String text, Severity severity, Uri uri, int charOffset) {
|
String text, Severity severity, Uri uri, int charOffset) {
|
||||||
|
// I believe we should only set it if we are reporting something, if we are
|
||||||
|
// formatting to embed the error in the program, then we probably don't want
|
||||||
|
// to do it in format.
|
||||||
|
// Note: I also want to limit dependencies to dart:io for when we use the FE
|
||||||
|
// outside of the VM. This default reporting is likely not going to be used in
|
||||||
|
// that context, but the default formatter is.
|
||||||
|
if (CompilerContext.current.options.setExitCodeOnProblem) {
|
||||||
|
exitCode = 1;
|
||||||
|
}
|
||||||
print(text);
|
print(text);
|
||||||
if (isFatal(severity)) {
|
if (isFatal(severity)) {
|
||||||
if (isVerbose) print(StackTrace.current);
|
if (isVerbose) print(StackTrace.current);
|
||||||
|
// TODO(sigmund,ahe): ensure there is no circularity when InputError is
|
||||||
|
// handled.
|
||||||
throw new deprecated_InputError(uri, charOffset,
|
throw new deprecated_InputError(uri, charOffset,
|
||||||
"Compilation aborted due to fatal ${severityName(severity)}.");
|
"Compilation aborted due to fatal ${severityName(severity)}.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,7 @@ import 'dart:async' show Future;
|
||||||
|
|
||||||
import 'dart:io' show exitCode, File;
|
import 'dart:io' show exitCode, File;
|
||||||
|
|
||||||
import '../../compiler_options.dart' show CompilerOptions;
|
import '../kernel_generator_impl.dart' show generateKernelInternal;
|
||||||
|
|
||||||
import '../base/processed_options.dart' show ProcessedOptions;
|
|
||||||
|
|
||||||
import '../kernel_generator_impl.dart' show generateKernel;
|
|
||||||
|
|
||||||
import 'compiler_command_line.dart' show CompilerCommandLine;
|
import 'compiler_command_line.dart' show CompilerCommandLine;
|
||||||
|
|
||||||
|
@ -24,8 +20,6 @@ import 'kernel/utils.dart' show writeProgramToFile;
|
||||||
|
|
||||||
import 'severity.dart' show Severity;
|
import 'severity.dart' show Severity;
|
||||||
|
|
||||||
import 'ticker.dart' show Ticker;
|
|
||||||
|
|
||||||
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
|
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
|
||||||
|
|
||||||
Future mainEntryPoint(List<String> arguments) async {
|
Future mainEntryPoint(List<String> arguments) async {
|
||||||
|
@ -37,54 +31,44 @@ Future mainEntryPoint(List<String> arguments) async {
|
||||||
await compilePlatform(arguments);
|
await compilePlatform(arguments);
|
||||||
} on deprecated_InputError catch (e) {
|
} on deprecated_InputError catch (e) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
CompilerContext.runWithDefaultOptions(
|
||||||
.current
|
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future compilePlatform(List<String> arguments) async {
|
Future compilePlatform(List<String> arguments) async {
|
||||||
Ticker ticker = new Ticker();
|
await CompilerCommandLine
|
||||||
await CompilerCommandLine.withGlobalOptions("compile_platform", arguments,
|
.withGlobalOptions("compile_platform", arguments, false,
|
||||||
(CompilerContext c) {
|
(CompilerContext c, List<String> restArguments) {
|
||||||
Uri patchedSdk = Uri.base.resolveUri(new Uri.file(c.options.arguments[0]));
|
c.options.inputs.add(Uri.parse('dart:core'));
|
||||||
Uri fullOutput = Uri.base.resolveUri(new Uri.file(c.options.arguments[1]));
|
// Note: the patchedSdk argument is already stored in c.options.sdkRoot.
|
||||||
Uri outlineOutput =
|
Uri fullOutput = Uri.base.resolveUri(new Uri.file(restArguments[1]));
|
||||||
Uri.base.resolveUri(new Uri.file(c.options.arguments[2]));
|
Uri outlineOutput = Uri.base.resolveUri(new Uri.file(restArguments[2]));
|
||||||
return compilePlatformInternal(
|
return compilePlatformInternal(c, fullOutput, outlineOutput);
|
||||||
c, ticker, patchedSdk, fullOutput, outlineOutput);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future compilePlatformInternal(CompilerContext c, Ticker ticker, Uri patchedSdk,
|
Future compilePlatformInternal(
|
||||||
Uri fullOutput, Uri outlineOutput) async {
|
CompilerContext c, Uri fullOutput, Uri outlineOutput) async {
|
||||||
var options = new CompilerOptions()
|
if (c.options.strongMode) {
|
||||||
..strongMode = c.options.strongMode
|
|
||||||
..sdkRoot = patchedSdk
|
|
||||||
..packagesFileUri = c.options.packages
|
|
||||||
..compileSdk = true
|
|
||||||
..chaseDependencies = true
|
|
||||||
..target = c.options.target
|
|
||||||
..debugDump = c.options.dumpIr
|
|
||||||
..verify = c.options.verify
|
|
||||||
..verbose = c.options.verbose;
|
|
||||||
|
|
||||||
if (options.strongMode) {
|
|
||||||
print("Note: strong mode support is preliminary and may not work.");
|
print("Note: strong mode support is preliminary and may not work.");
|
||||||
}
|
}
|
||||||
if (options.verbose) {
|
if (c.options.verbose) {
|
||||||
print("Generating outline of $patchedSdk into $outlineOutput");
|
print("Generating outline of ${c.options.sdkRoot} into $outlineOutput");
|
||||||
print("Compiling $patchedSdk to $fullOutput");
|
print("Compiling ${c.options.sdkRoot} to $fullOutput");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await generateKernel(
|
var result =
|
||||||
new ProcessedOptions(options, false, [Uri.parse('dart:core')]),
|
await generateKernelInternal(buildSummary: true, buildProgram: true);
|
||||||
buildSummary: true,
|
if (result == null) {
|
||||||
buildProgram: true);
|
// Note: an error should have been reported by now.
|
||||||
|
print('The platform .dill files were not created.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
new File.fromUri(outlineOutput).writeAsBytesSync(result.summary);
|
new File.fromUri(outlineOutput).writeAsBytesSync(result.summary);
|
||||||
ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
|
c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
|
||||||
await writeProgramToFile(result.program, fullOutput);
|
await writeProgramToFile(result.program, fullOutput);
|
||||||
ticker.logMs("Wrote program to ${fullOutput.toFilePath()}");
|
c.options.ticker.logMs("Wrote program to ${fullOutput.toFilePath()}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,27 +6,22 @@ library fasta.compiler_command_line;
|
||||||
|
|
||||||
import 'dart:io' show exit;
|
import 'dart:io' show exit;
|
||||||
|
|
||||||
import 'dart:async' show runZoned;
|
|
||||||
|
|
||||||
import 'package:kernel/target/targets.dart'
|
import 'package:kernel/target/targets.dart'
|
||||||
show Target, getTarget, TargetFlags, targets;
|
show Target, getTarget, TargetFlags, targets;
|
||||||
|
|
||||||
|
import '../../compiler_options.dart';
|
||||||
|
import '../base/processed_options.dart';
|
||||||
import 'command_line.dart' show CommandLine, deprecated_argumentError;
|
import 'command_line.dart' show CommandLine, deprecated_argumentError;
|
||||||
|
|
||||||
import 'compiler_context.dart' show CompilerContext, compilerContextKey;
|
import 'compiler_context.dart' show CompilerContext;
|
||||||
|
|
||||||
import 'command_line_reporting.dart' as command_line_reporting;
|
|
||||||
|
|
||||||
import 'fasta_codes.dart'
|
import 'fasta_codes.dart'
|
||||||
show
|
show
|
||||||
LocatedMessage,
|
|
||||||
Message,
|
Message,
|
||||||
messageFastaUsageLong,
|
messageFastaUsageLong,
|
||||||
messageFastaUsageShort,
|
messageFastaUsageShort,
|
||||||
templateUnspecified;
|
templateUnspecified;
|
||||||
|
|
||||||
import 'severity.dart' show Severity;
|
|
||||||
|
|
||||||
const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
||||||
"--compile-sdk": Uri,
|
"--compile-sdk": Uri,
|
||||||
"--fatal": ",",
|
"--fatal": ",",
|
||||||
|
@ -39,6 +34,8 @@ const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
||||||
"-t": String,
|
"-t": String,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Parser for options accepted by the `fasta` command-line tools.
|
||||||
|
// TODO(ahe,sigmund): move this and other tools under pkg/front_end/tool/
|
||||||
class CompilerCommandLine extends CommandLine {
|
class CompilerCommandLine extends CommandLine {
|
||||||
final String programName;
|
final String programName;
|
||||||
|
|
||||||
|
@ -61,13 +58,9 @@ class CompilerCommandLine extends CommandLine {
|
||||||
options.containsKey("/?");
|
options.containsKey("/?");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get setExitCodeOnProblem {
|
|
||||||
return options.containsKey("--set-exit-code-on-problem");
|
|
||||||
}
|
|
||||||
|
|
||||||
void validate() {
|
void validate() {
|
||||||
if (help) {
|
if (help) {
|
||||||
print(computeUsage(programName, verbose));
|
print(computeUsage(programName, verbose).message);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +77,16 @@ class CompilerCommandLine extends CommandLine {
|
||||||
return deprecated_argumentError(
|
return deprecated_argumentError(
|
||||||
usage, "Can't specify both '--compile-sdk' and '--platform'.");
|
usage, "Can't specify both '--compile-sdk' and '--platform'.");
|
||||||
}
|
}
|
||||||
if (programName == "compile_platform" && arguments.length != 3) {
|
if (programName == "compile_platform") {
|
||||||
return deprecated_argumentError(usage, "Expected three arguments.");
|
if (arguments.length != 3) {
|
||||||
|
return deprecated_argumentError(usage, "Expected three arguments.");
|
||||||
|
}
|
||||||
|
if (options.containsKey("--compile-sdk")) {
|
||||||
|
return deprecated_argumentError(usage,
|
||||||
|
"Cannot specify '--compile-sdk' option to compile_platform.");
|
||||||
|
}
|
||||||
|
options['--compile-sdk'] =
|
||||||
|
Uri.base.resolveUri(new Uri.file(arguments[0]));
|
||||||
} else if (arguments.isEmpty) {
|
} else if (arguments.isEmpty) {
|
||||||
return deprecated_argumentError(usage, "No Dart file specified.");
|
return deprecated_argumentError(usage, "No Dart file specified.");
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ class CompilerCommandLine extends CommandLine {
|
||||||
: options["--platform"] ?? Uri.base.resolve("platform.dill");
|
: options["--platform"] ?? Uri.base.resolve("platform.dill");
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri get packages => options["--packages"] ?? Uri.base.resolve(".packages");
|
Uri get packages => options["--packages"];
|
||||||
|
|
||||||
Uri get sdk => options["--sdk"] ?? options["--compile-sdk"];
|
Uri get sdk => options["--sdk"] ?? options["--compile-sdk"];
|
||||||
|
|
||||||
|
@ -135,43 +136,41 @@ class CompilerCommandLine extends CommandLine {
|
||||||
|
|
||||||
Target get target => options["target"];
|
Target get target => options["target"];
|
||||||
|
|
||||||
void Function(LocatedMessage, Severity) get report {
|
static dynamic withGlobalOptions(
|
||||||
return options["report"] ?? command_line_reporting.report;
|
String programName,
|
||||||
}
|
List<String> arguments,
|
||||||
|
bool areRestArgumentsInputs,
|
||||||
|
dynamic f(CompilerContext context, List<String> restArguments)) {
|
||||||
|
// TODO(sigmund,ahe): delete this wrapper by moving validation into the
|
||||||
|
// callback. Note that this requires some subtle changes because validate
|
||||||
|
// sets some implicit options (like --compile-sdk in compile_platform).
|
||||||
|
var cl = CompilerContext.runWithDefaultOptions(
|
||||||
|
(_) => new CompilerCommandLine(programName, arguments));
|
||||||
|
var options = new CompilerOptions()
|
||||||
|
..compileSdk = cl.options.containsKey("--compile-sdk")
|
||||||
|
..sdkRoot = cl.sdk
|
||||||
|
..sdkSummary = cl.platform
|
||||||
|
..packagesFileUri = cl.packages
|
||||||
|
..strongMode = cl.strongMode
|
||||||
|
..target = cl.target
|
||||||
|
..throwOnErrors = cl.errorsAreFatal
|
||||||
|
..throwOnWarnings = cl.warningsAreFatal
|
||||||
|
..throwOnNits = cl.nitsAreFatal
|
||||||
|
..embedSourceText = !cl.excludeSource
|
||||||
|
// All command-line tools take only a single entry point and chase
|
||||||
|
// dependencies, and provide a non-zero exit code when errors are found.
|
||||||
|
..chaseDependencies = true
|
||||||
|
..setExitCodeOnProblem = true
|
||||||
|
..debugDump = cl.dumpIr
|
||||||
|
..verbose = cl.verbose
|
||||||
|
..verify = cl.verify;
|
||||||
|
|
||||||
void Function(Message, Severity) get reportWithoutLocation {
|
var inputs = <Uri>[];
|
||||||
return options["reportWithoutLocation"] ??
|
if (areRestArgumentsInputs) {
|
||||||
command_line_reporting.reportWithoutLocation;
|
inputs = cl.arguments.map(Uri.base.resolve).toList();
|
||||||
}
|
}
|
||||||
|
var pOptions = new ProcessedOptions(options, false, inputs, cl.output);
|
||||||
String Function(LocatedMessage, Severity) get format {
|
return CompilerContext.runWithOptions(pOptions, (c) => f(c, cl.arguments));
|
||||||
return options["format"] ?? command_line_reporting.format;
|
|
||||||
}
|
|
||||||
|
|
||||||
String Function(Message, Severity) get formatWithoutLocation {
|
|
||||||
return options["formatWithoutLocation"] ??
|
|
||||||
command_line_reporting.formatWithoutLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
static dynamic withGlobalOptions(String programName, List<String> arguments,
|
|
||||||
dynamic f(CompilerContext context)) {
|
|
||||||
CompilerCommandLine cl = deprecated_withDefaultOptions(
|
|
||||||
() => new CompilerCommandLine(programName, arguments));
|
|
||||||
return CompilerContext.withGlobalOptions(cl, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(sigmund, ahe): delete. We use this to wrap places where we require a
|
|
||||||
// context but we shoudln't. Right now this includes:
|
|
||||||
// - constructor calls to CompilerCommandLine (because it is calling
|
|
||||||
// [validate] which may report errors). This should be fixed by doing
|
|
||||||
// validation after creating these objects.
|
|
||||||
// - top-level try-catch in command-line tools that capture
|
|
||||||
// deprecated_InputError, and then report errors using fasta's error
|
|
||||||
// reporting mechanism. Those should be unnecessary once we get rid of all
|
|
||||||
// deprecated_InputErrors.
|
|
||||||
static dynamic deprecated_withDefaultOptions(dynamic f()) {
|
|
||||||
var defaultContext = new CompilerContext(new CompilerCommandLine("", [""]));
|
|
||||||
return runZoned(f, zoneValues: {compilerContextKey: defaultContext});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ library fasta.compiler_context;
|
||||||
|
|
||||||
import 'dart:async' show Zone, runZoned;
|
import 'dart:async' show Zone, runZoned;
|
||||||
|
|
||||||
|
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/physical_file_system.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/fasta/fasta_codes.dart';
|
import 'package:front_end/src/fasta/fasta_codes.dart';
|
||||||
import 'package:kernel/ast.dart' show Source;
|
import 'package:kernel/ast.dart' show Source;
|
||||||
|
import 'command_line_reporting.dart' as command_line_reporting;
|
||||||
import 'compiler_command_line.dart' show CompilerCommandLine;
|
|
||||||
|
|
||||||
import 'colors.dart' show computeEnableColors;
|
import 'colors.dart' show computeEnableColors;
|
||||||
|
|
||||||
|
@ -21,13 +21,28 @@ import 'severity.dart' show Severity;
|
||||||
|
|
||||||
final Object compilerContextKey = new Object();
|
final Object compilerContextKey = new Object();
|
||||||
|
|
||||||
|
/// Shared context used throughout the compiler.
|
||||||
|
///
|
||||||
|
/// The compiler works with a single instance of this class. To avoid
|
||||||
|
/// passing it around as an argument everywhere, it is stored as a zone-value.
|
||||||
|
///
|
||||||
|
/// For convenience the static getter [CompilerContext.current] retrieves the
|
||||||
|
/// context stored in the current zone.
|
||||||
class CompilerContext {
|
class CompilerContext {
|
||||||
final FileSystem fileSystem = PhysicalFileSystem.instance;
|
// TODO(sigmund): Move here any method in ProcessedOptions that doesn't seem
|
||||||
|
// appropriate as an "option", or consider merging ProcessedOptions entirely
|
||||||
final CompilerCommandLine options;
|
// within this class, and depend only on the raw options here.
|
||||||
|
final ProcessedOptions options;
|
||||||
|
|
||||||
|
/// Sources seen by the compiler.
|
||||||
|
///
|
||||||
|
/// This is populated as the compiler reads files, and it is used for error
|
||||||
|
/// reporting and to generate source location information in the compiled
|
||||||
|
/// programs.
|
||||||
final Map<String, Source> uriToSource = <String, Source>{};
|
final Map<String, Source> uriToSource = <String, Source>{};
|
||||||
|
|
||||||
|
FileSystem get fileSystem => options.fileSystem;
|
||||||
|
|
||||||
bool enableColorsCached = null;
|
bool enableColorsCached = null;
|
||||||
|
|
||||||
CompilerContext(this.options);
|
CompilerContext(this.options);
|
||||||
|
@ -48,12 +63,12 @@ class CompilerContext {
|
||||||
|
|
||||||
/// Format [message] as a text string that can be included in generated code.
|
/// Format [message] as a text string that can be included in generated code.
|
||||||
String format(LocatedMessage message, Severity severity) {
|
String format(LocatedMessage message, Severity severity) {
|
||||||
return options.format(message, severity);
|
return command_line_reporting.format(message, severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format [message] as a text string that can be included in generated code.
|
/// Format [message] as a text string that can be included in generated code.
|
||||||
String formatWithoutLocation(Message message, Severity severity) {
|
String formatWithoutLocation(Message message, Severity severity) {
|
||||||
return options.formatWithoutLocation(message, severity);
|
return command_line_reporting.formatWithoutLocation(message, severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CompilerContext get current {
|
static CompilerContext get current {
|
||||||
|
@ -68,12 +83,22 @@ class CompilerContext {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform [action] in a [Zone] where [cl] will be available as
|
/// Perform [action] in a [Zone] where [this] will be available as
|
||||||
/// `CompilerContext.current.options`.
|
/// `CompilerContext.current.options`.
|
||||||
static dynamic withGlobalOptions(
|
T runInContext<T>(T action(CompilerContext c)) {
|
||||||
CompilerCommandLine cl, dynamic action(CompilerContext c)) {
|
return runZoned(() => action(this), zoneValues: {compilerContextKey: this});
|
||||||
CompilerContext c = new CompilerContext(cl);
|
}
|
||||||
return runZoned(() => action(c), zoneValues: {compilerContextKey: c});
|
|
||||||
|
/// Perform [action] in a [Zone] where [options] will be available as
|
||||||
|
/// `CompilerContext.current.options`.
|
||||||
|
static T runWithOptions<T>(
|
||||||
|
ProcessedOptions options, T action(CompilerContext c)) {
|
||||||
|
return new CompilerContext(options).runInContext(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static T runWithDefaultOptions<T>(T action(CompilerContext c)) {
|
||||||
|
var options = new ProcessedOptions(new CompilerOptions());
|
||||||
|
return new CompilerContext(options).runInContext(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool get enableColors {
|
static bool get enableColors {
|
||||||
|
|
|
@ -10,9 +10,10 @@ import 'dart:convert' show JSON;
|
||||||
|
|
||||||
import 'dart:io' show BytesBuilder, File, exitCode;
|
import 'dart:io' show BytesBuilder, File, exitCode;
|
||||||
|
|
||||||
|
import 'package:front_end/compiler_options.dart';
|
||||||
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/physical_file_system.dart';
|
import 'package:front_end/physical_file_system.dart';
|
||||||
import 'package:front_end/src/fasta/kernel/utils.dart';
|
import 'package:front_end/src/fasta/kernel/utils.dart';
|
||||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
|
||||||
|
|
||||||
import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
|
import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
|
||||||
|
|
||||||
|
@ -25,9 +26,9 @@ import 'deprecated_problems.dart'
|
||||||
|
|
||||||
import 'kernel/kernel_target.dart' show KernelTarget;
|
import 'kernel/kernel_target.dart' show KernelTarget;
|
||||||
|
|
||||||
import 'dill/dill_target.dart' show DillTarget;
|
import 'package:kernel/target/targets.dart' show Target;
|
||||||
|
|
||||||
import 'compile_platform.dart' show compilePlatformInternal;
|
import 'dill/dill_target.dart' show DillTarget;
|
||||||
|
|
||||||
import 'severity.dart' show Severity;
|
import 'severity.dart' show Severity;
|
||||||
|
|
||||||
|
@ -70,8 +71,8 @@ outlineEntryPoint(List<String> arguments) async {
|
||||||
|
|
||||||
Future<KernelTarget> outline(List<String> arguments) async {
|
Future<KernelTarget> outline(List<String> arguments) async {
|
||||||
try {
|
try {
|
||||||
return await CompilerCommandLine.withGlobalOptions("outline", arguments,
|
return await CompilerCommandLine.withGlobalOptions(
|
||||||
(CompilerContext c) async {
|
"outline", arguments, true, (CompilerContext c, _) async {
|
||||||
if (c.options.verbose) {
|
if (c.options.verbose) {
|
||||||
print("Building outlines for ${arguments.join(' ')}");
|
print("Building outlines for ${arguments.join(' ')}");
|
||||||
}
|
}
|
||||||
|
@ -81,17 +82,16 @@ Future<KernelTarget> outline(List<String> arguments) async {
|
||||||
});
|
});
|
||||||
} on deprecated_InputError catch (e) {
|
} on deprecated_InputError catch (e) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
CompilerContext.runWithDefaultOptions(
|
||||||
.current
|
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uri> compile(List<String> arguments) async {
|
Future<Uri> compile(List<String> arguments) async {
|
||||||
try {
|
try {
|
||||||
return await CompilerCommandLine.withGlobalOptions("compile", arguments,
|
return await CompilerCommandLine.withGlobalOptions(
|
||||||
(CompilerContext c) async {
|
"compile", arguments, true, (CompilerContext c, _) async {
|
||||||
if (c.options.verbose) {
|
if (c.options.verbose) {
|
||||||
print("Compiling directly to Kernel: ${arguments.join(' ')}");
|
print("Compiling directly to Kernel: ${arguments.join(' ')}");
|
||||||
}
|
}
|
||||||
|
@ -101,9 +101,8 @@ Future<Uri> compile(List<String> arguments) async {
|
||||||
});
|
});
|
||||||
} on deprecated_InputError catch (e) {
|
} on deprecated_InputError catch (e) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
CompilerContext.runWithDefaultOptions(
|
||||||
.current
|
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,8 +124,7 @@ class CompileTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<KernelTarget> buildOutline([Uri output]) async {
|
Future<KernelTarget> buildOutline([Uri output]) async {
|
||||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
UriTranslator uriTranslator = await c.options.getUriTranslator();
|
||||||
.parse(c.fileSystem, c.options.sdk, packages: c.options.packages);
|
|
||||||
ticker.logMs("Read packages file");
|
ticker.logMs("Read packages file");
|
||||||
DillTarget dillTarget = createDillTarget(uriTranslator);
|
DillTarget dillTarget = createDillTarget(uriTranslator);
|
||||||
KernelTarget kernelTarget =
|
KernelTarget kernelTarget =
|
||||||
|
@ -134,13 +132,12 @@ class CompileTask {
|
||||||
if (c.options.strongMode) {
|
if (c.options.strongMode) {
|
||||||
print("Note: strong mode support is preliminary and may not work.");
|
print("Note: strong mode support is preliminary and may not work.");
|
||||||
}
|
}
|
||||||
Uri platform = c.options.platform;
|
Uri platform = c.options.sdkSummary;
|
||||||
if (platform != null) {
|
if (platform != null) {
|
||||||
_appendDillForUri(dillTarget, platform);
|
_appendDillForUri(dillTarget, platform);
|
||||||
}
|
}
|
||||||
String argument = c.options.arguments.first;
|
Uri uri = c.options.inputs.first;
|
||||||
Uri uri = Uri.base.resolve(argument);
|
String path = uriTranslator.translate(uri)?.path ?? uri.path;
|
||||||
String path = uriTranslator.translate(uri)?.path ?? argument;
|
|
||||||
if (path.endsWith(".dart")) {
|
if (path.endsWith(".dart")) {
|
||||||
kernelTarget.read(uri);
|
kernelTarget.read(uri);
|
||||||
} else {
|
} else {
|
||||||
|
@ -148,7 +145,7 @@ class CompileTask {
|
||||||
}
|
}
|
||||||
await dillTarget.buildOutlines();
|
await dillTarget.buildOutlines();
|
||||||
var outline = await kernelTarget.buildOutlines();
|
var outline = await kernelTarget.buildOutlines();
|
||||||
if (c.options.dumpIr && output != null) {
|
if (c.options.debugDump && output != null) {
|
||||||
printProgramText(outline, libraryFilter: kernelTarget.isSourceLibrary);
|
printProgramText(outline, libraryFilter: kernelTarget.isSourceLibrary);
|
||||||
}
|
}
|
||||||
if (output != null) {
|
if (output != null) {
|
||||||
|
@ -163,7 +160,7 @@ class CompileTask {
|
||||||
if (exitCode != 0) return null;
|
if (exitCode != 0) return null;
|
||||||
Uri uri = c.options.output;
|
Uri uri = c.options.output;
|
||||||
var program = await kernelTarget.buildProgram(verify: c.options.verify);
|
var program = await kernelTarget.buildProgram(verify: c.options.verify);
|
||||||
if (c.options.dumpIr) {
|
if (c.options.debugDump) {
|
||||||
printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
|
printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
|
||||||
}
|
}
|
||||||
await writeProgramToFile(program, uri);
|
await writeProgramToFile(program, uri);
|
||||||
|
@ -172,50 +169,26 @@ class CompileTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future compilePlatform(Uri patchedSdk, Uri fullOutput,
|
|
||||||
{Uri outlineOutput,
|
|
||||||
Uri packages,
|
|
||||||
bool verbose: false,
|
|
||||||
String backendTarget}) async {
|
|
||||||
backendTarget ??= "vm_fasta";
|
|
||||||
Ticker ticker = new Ticker(isVerbose: verbose);
|
|
||||||
await CompilerCommandLine.withGlobalOptions("", [""], (CompilerContext c) {
|
|
||||||
c.options.options["--target"] = backendTarget;
|
|
||||||
c.options.options["--packages"] = packages;
|
|
||||||
if (verbose) {
|
|
||||||
c.options.options["--verbose"] = true;
|
|
||||||
}
|
|
||||||
c.options.validate();
|
|
||||||
return compilePlatformInternal(
|
|
||||||
c, ticker, patchedSdk, fullOutput, outlineOutput);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(sigmund): reimplement this API using the directive listener intead.
|
// TODO(sigmund): reimplement this API using the directive listener intead.
|
||||||
Future<List<Uri>> getDependencies(Uri script,
|
Future<List<Uri>> getDependencies(Uri script,
|
||||||
{Uri sdk,
|
{Uri sdk,
|
||||||
Uri packages,
|
Uri packages,
|
||||||
Uri platform,
|
Uri platform,
|
||||||
bool verbose: false,
|
bool verbose: false,
|
||||||
String backendTarget}) async {
|
Target target}) async {
|
||||||
backendTarget ??= "vm_fasta";
|
var options = new CompilerOptions()
|
||||||
Ticker ticker = new Ticker(isVerbose: verbose);
|
..target = target
|
||||||
return await CompilerCommandLine.withGlobalOptions("", [""],
|
..verbose = verbose
|
||||||
|
..packagesFileUri = packages
|
||||||
|
..sdkSummary = platform
|
||||||
|
..sdkRoot = sdk;
|
||||||
|
var pOptions = new ProcessedOptions(options);
|
||||||
|
return await CompilerContext.runWithOptions(pOptions,
|
||||||
(CompilerContext c) async {
|
(CompilerContext c) async {
|
||||||
c.options.options["--target"] = backendTarget;
|
UriTranslator uriTranslator = await c.options.getUriTranslator();
|
||||||
c.options.options["--strong-mode"] = false;
|
c.options.ticker.logMs("Read packages file");
|
||||||
c.options.options["--packages"] = packages;
|
|
||||||
if (verbose) {
|
|
||||||
c.options.options["--verbose"] = true;
|
|
||||||
}
|
|
||||||
c.options.validate();
|
|
||||||
sdk ??= c.options.sdk;
|
|
||||||
|
|
||||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
|
||||||
.parse(c.fileSystem, sdk, packages: c.options.packages);
|
|
||||||
ticker.logMs("Read packages file");
|
|
||||||
DillTarget dillTarget =
|
DillTarget dillTarget =
|
||||||
new DillTarget(ticker, uriTranslator, c.options.target);
|
new DillTarget(c.options.ticker, uriTranslator, c.options.target);
|
||||||
if (platform != null) _appendDillForUri(dillTarget, platform);
|
if (platform != null) _appendDillForUri(dillTarget, platform);
|
||||||
KernelTarget kernelTarget = new KernelTarget(PhysicalFileSystem.instance,
|
KernelTarget kernelTarget = new KernelTarget(PhysicalFileSystem.instance,
|
||||||
false, dillTarget, uriTranslator, c.uriToSource);
|
false, dillTarget, uriTranslator, c.uriToSource);
|
||||||
|
|
|
@ -209,7 +209,17 @@ const Code<Null> codeCantInferPackagesFromManyInputs =
|
||||||
const MessageCode messageCantInferPackagesFromManyInputs = const MessageCode(
|
const MessageCode messageCantInferPackagesFromManyInputs = const MessageCode(
|
||||||
"CantInferPackagesFromManyInputs",
|
"CantInferPackagesFromManyInputs",
|
||||||
message:
|
message:
|
||||||
r"""Cannot infer a .packages file when compiling multiple inputs.""",
|
r"""Can't infer a .packages file when compiling multiple inputs.""",
|
||||||
|
tip: r"""Try specifying the file explicitly with the --packages option.""");
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const Code<Null> codeCantInferPackagesFromPackageUri =
|
||||||
|
messageCantInferPackagesFromPackageUri;
|
||||||
|
|
||||||
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
const MessageCode messageCantInferPackagesFromPackageUri = const MessageCode(
|
||||||
|
"CantInferPackagesFromPackageUri",
|
||||||
|
message: r"""Can't infer a .packages file from an input 'package:*' URI.""",
|
||||||
tip: r"""Try specifying the file explicitly with the --packages option.""");
|
tip: r"""Try specifying the file explicitly with the --packages option.""");
|
||||||
|
|
||||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||||
|
@ -1394,7 +1404,7 @@ const MessageCode messageInternalProblemMissingContext = const MessageCode(
|
||||||
"InternalProblemMissingContext",
|
"InternalProblemMissingContext",
|
||||||
message: r"""Compiler cannot run without a compiler context.""",
|
message: r"""Compiler cannot run without a compiler context.""",
|
||||||
tip:
|
tip:
|
||||||
r"""Are calls to the compiler wrapped in CompilerContext.withGlobalOptions?""");
|
r"""Are calls to the compiler wrapped in CompilerContext.runInContext?""");
|
||||||
|
|
||||||
// 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(String name)> templateInternalProblemNotFound =
|
const Template<Message Function(String name)> templateInternalProblemNotFound =
|
||||||
|
|
|
@ -30,8 +30,10 @@ const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
|
||||||
mainEntryPoint(List<String> arguments) async {
|
mainEntryPoint(List<String> arguments) async {
|
||||||
Uri uri;
|
Uri uri;
|
||||||
for (int i = 0; i < iterations; i++) {
|
for (int i = 0; i < iterations; i++) {
|
||||||
await CompilerCommandLine.withGlobalOptions("run", arguments,
|
await CompilerCommandLine.withGlobalOptions("run", arguments, false,
|
||||||
(CompilerContext c) async {
|
(CompilerContext c, List<String> restArguments) async {
|
||||||
|
var input = Uri.base.resolve(restArguments[0]);
|
||||||
|
c.options.inputs.add(input);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
@ -46,17 +48,17 @@ mainEntryPoint(List<String> arguments) async {
|
||||||
}
|
}
|
||||||
if (exitCode != 0) exit(exitCode);
|
if (exitCode != 0) exit(exitCode);
|
||||||
if (i + 1 == iterations) {
|
if (i + 1 == iterations) {
|
||||||
exit(await run(uri, c));
|
exit(await run(uri, c, restArguments));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<int> run(Uri uri, CompilerContext c) async {
|
Future<int> run(Uri uri, CompilerContext c, List<String> allArguments) async {
|
||||||
Uri sdk = await computePatchedSdk();
|
Uri sdk = await computePatchedSdk();
|
||||||
Uri dartVm = computeDartVm(sdk);
|
Uri dartVm = computeDartVm(sdk);
|
||||||
List<String> arguments = <String>["${uri.toFilePath()}"]
|
List<String> arguments = <String>["${uri.toFilePath()}"]
|
||||||
..addAll(c.options.arguments.skip(1));
|
..addAll(allArguments.skip(1));
|
||||||
if (c.options.verbose) {
|
if (c.options.verbose) {
|
||||||
print("Running ${dartVm.toFilePath()} ${arguments.join(' ')}");
|
print("Running ${dartVm.toFilePath()} ${arguments.join(' ')}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ class SourceLoader<L> extends Loader<L> {
|
||||||
|
|
||||||
final Map<Uri, List<int>> sourceBytes = <Uri, List<int>>{};
|
final Map<Uri, List<int>> sourceBytes = <Uri, List<int>>{};
|
||||||
|
|
||||||
final bool excludeSource = CompilerContext.current.options.excludeSource;
|
final bool excludeSource = !CompilerContext.current.options.embedSourceText;
|
||||||
|
|
||||||
// Used when building directly to kernel.
|
// Used when building directly to kernel.
|
||||||
ClassHierarchy hierarchy;
|
ClassHierarchy hierarchy;
|
||||||
|
|
|
@ -25,7 +25,7 @@ import 'package:kernel/ast.dart' show Library, Program;
|
||||||
|
|
||||||
import '../kernel/verifier.dart' show verifyProgram;
|
import '../kernel/verifier.dart' show verifyProgram;
|
||||||
|
|
||||||
import '../compiler_command_line.dart';
|
import '../compiler_context.dart';
|
||||||
|
|
||||||
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
|
import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ import 'package:kernel/ast.dart' show Program;
|
||||||
|
|
||||||
import 'package:front_end/front_end.dart';
|
import 'package:front_end/front_end.dart';
|
||||||
|
|
||||||
|
import 'package:front_end/src/base/processed_options.dart'
|
||||||
|
show ProcessedOptions;
|
||||||
|
|
||||||
import 'patched_sdk_location.dart' show computePatchedSdk;
|
import 'patched_sdk_location.dart' show computePatchedSdk;
|
||||||
|
|
||||||
class Print extends Step<Program, Program, ChainContext> {
|
class Print extends Step<Program, Program, ChainContext> {
|
||||||
|
@ -67,7 +70,9 @@ class Verify extends Step<Program, Program, ChainContext> {
|
||||||
String get name => "verify";
|
String get name => "verify";
|
||||||
|
|
||||||
Future<Result<Program>> run(Program program, ChainContext context) async {
|
Future<Result<Program>> run(Program program, ChainContext context) async {
|
||||||
return await CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
var options =
|
||||||
|
new ProcessedOptions(new CompilerOptions()..throwOnErrors = false);
|
||||||
|
return await CompilerContext.runWithOptions(options, (_) async {
|
||||||
var errors = verifyProgram(program, isOutline: !fullCompile);
|
var errors = verifyProgram(program, isOutline: !fullCompile);
|
||||||
if (errors.isEmpty) {
|
if (errors.isEmpty) {
|
||||||
return pass(program);
|
return pass(program);
|
||||||
|
@ -191,7 +196,7 @@ class Compile extends Step<TestDescription, Program, CompileContext> {
|
||||||
Future<Result<Program>> run(
|
Future<Result<Program>> run(
|
||||||
TestDescription description, CompileContext context) async {
|
TestDescription description, CompileContext context) async {
|
||||||
Result<Program> result;
|
Result<Program> result;
|
||||||
reportError(CompilationError error) {
|
reportError(CompilationMessage error) {
|
||||||
result ??= fail(null, error.message);
|
result ??= fail(null, error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:front_end/file_system.dart';
|
import 'package:front_end/file_system.dart';
|
||||||
|
import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/src/base/api_signature.dart';
|
import 'package:front_end/src/base/api_signature.dart';
|
||||||
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
import 'package:front_end/src/base/performace_logger.dart';
|
import 'package:front_end/src/base/performace_logger.dart';
|
||||||
import 'package:front_end/src/fasta/compiler_command_line.dart';
|
|
||||||
import 'package:front_end/src/fasta/compiler_context.dart';
|
import 'package:front_end/src/fasta/compiler_context.dart';
|
||||||
import 'package:front_end/src/fasta/dill/dill_library_builder.dart';
|
import 'package:front_end/src/fasta/dill/dill_library_builder.dart';
|
||||||
import 'package:front_end/src/fasta/dill/dill_target.dart';
|
import 'package:front_end/src/fasta/dill/dill_target.dart';
|
||||||
|
@ -149,13 +150,15 @@ class KernelDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<T> runWithFrontEndContext<T>(String msg, Future<T> f()) async {
|
Future<T> runWithFrontEndContext<T>(String msg, Future<T> f()) async {
|
||||||
return await CompilerCommandLine.withGlobalOptions("", [""],
|
var options = new CompilerOptions()
|
||||||
(CompilerContext context) {
|
..target = _target
|
||||||
context.options.options["--target"] = _target;
|
// Note: we do not report error on the console because the driver is an
|
||||||
context.options.options["report"] = (message, severity) {};
|
// ongoing background service that shouldn't polute stdout.
|
||||||
context.options.options["reportWithoutLocation"] = (message, severity) {};
|
// TODO(scheglov,sigmund): add an error handler to forward errors to
|
||||||
return _logger.runAsync(msg, f);
|
// analyzer driver and incremental kernel generator.
|
||||||
});
|
..reportMessages = false;
|
||||||
|
return await CompilerContext.runWithOptions(
|
||||||
|
new ProcessedOptions(options), (_) => _logger.runAsync(msg, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The file with the given [uri] might have changed - updated, added, or
|
/// The file with the given [uri] might have changed - updated, added, or
|
||||||
|
|
|
@ -11,7 +11,7 @@ import 'dart:async';
|
||||||
import 'package:kernel/kernel.dart' show Program, CanonicalName;
|
import 'package:kernel/kernel.dart' show Program, CanonicalName;
|
||||||
|
|
||||||
import 'base/processed_options.dart';
|
import 'base/processed_options.dart';
|
||||||
import 'fasta/compiler_command_line.dart' show CompilerCommandLine;
|
import 'fasta/severity.dart' show Severity;
|
||||||
import 'fasta/compiler_context.dart' show CompilerContext;
|
import 'fasta/compiler_context.dart' show CompilerContext;
|
||||||
import 'fasta/deprecated_problems.dart' show deprecated_InputError, reportCrash;
|
import 'fasta/deprecated_problems.dart' show deprecated_InputError, reportCrash;
|
||||||
import 'fasta/dill/dill_target.dart' show DillTarget;
|
import 'fasta/dill/dill_target.dart' show DillTarget;
|
||||||
|
@ -27,34 +27,19 @@ Future<CompilerResult> generateKernel(ProcessedOptions options,
|
||||||
{bool buildSummary: false,
|
{bool buildSummary: false,
|
||||||
bool buildProgram: true,
|
bool buildProgram: true,
|
||||||
bool trimDependencies: false}) async {
|
bool trimDependencies: false}) async {
|
||||||
// TODO(sigmund): Replace CompilerCommandLine and instead simply use a
|
return await CompilerContext.runWithOptions(options, (_) async {
|
||||||
// CompilerContext that directly uses the ProcessedOptions through the
|
return await generateKernelInternal(
|
||||||
// system.
|
|
||||||
String programName = "";
|
|
||||||
List<String> arguments = <String>[programName, "--target=none"];
|
|
||||||
if (options.strongMode) {
|
|
||||||
arguments.add("--strong-mode");
|
|
||||||
}
|
|
||||||
if (options.verbose) {
|
|
||||||
arguments.add("--verbose");
|
|
||||||
}
|
|
||||||
if (options.setExitCodeOnProblem) {
|
|
||||||
arguments.add("--set-exit-code-on-problem");
|
|
||||||
}
|
|
||||||
return await CompilerCommandLine.withGlobalOptions(programName, arguments,
|
|
||||||
(CompilerContext context) async {
|
|
||||||
context.options.options["--target"] = options.target;
|
|
||||||
return await generateKernelInternal(options,
|
|
||||||
buildSummary: buildSummary,
|
buildSummary: buildSummary,
|
||||||
buildProgram: buildProgram,
|
buildProgram: buildProgram,
|
||||||
trimDependencies: trimDependencies);
|
trimDependencies: trimDependencies);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
Future<CompilerResult> generateKernelInternal(
|
||||||
{bool buildSummary: false,
|
{bool buildSummary: false,
|
||||||
bool buildProgram: true,
|
bool buildProgram: true,
|
||||||
bool trimDependencies: false}) async {
|
bool trimDependencies: false}) async {
|
||||||
|
var options = CompilerContext.current.options;
|
||||||
var fs = options.fileSystem;
|
var fs = options.fileSystem;
|
||||||
if (!await options.validateOptions()) return null;
|
if (!await options.validateOptions()) return null;
|
||||||
options.ticker.logMs("Validated arguments");
|
options.ticker.logMs("Validated arguments");
|
||||||
|
@ -120,7 +105,9 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
||||||
trimProgram(summaryProgram, (uri) => !excluded.contains(uri));
|
trimProgram(summaryProgram, (uri) => !excluded.contains(uri));
|
||||||
}
|
}
|
||||||
if (options.verify) {
|
if (options.verify) {
|
||||||
verifyProgram(summaryProgram).forEach(options.reportMessage);
|
for (var error in verifyProgram(summaryProgram)) {
|
||||||
|
options.report(error, Severity.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (options.debugDump) {
|
if (options.debugDump) {
|
||||||
printProgramText(summaryProgram,
|
printProgramText(summaryProgram,
|
||||||
|
@ -147,8 +134,8 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kernelTarget.errors.isNotEmpty) {
|
if (kernelTarget.errors.isNotEmpty) {
|
||||||
// TODO(ahe): The errors have already been reported via CompilerContext.
|
// Note: we don't report errors here because they have been already
|
||||||
kernelTarget.errors.forEach(options.reportMessage);
|
// reported through the compiler context.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +144,8 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
||||||
program: program,
|
program: program,
|
||||||
deps: kernelTarget.loader.getDependencies());
|
deps: kernelTarget.loader.getDependencies());
|
||||||
} on deprecated_InputError catch (e) {
|
} on deprecated_InputError catch (e) {
|
||||||
options.reportMessage(deprecated_InputError.toMessage(e));
|
options.report(
|
||||||
|
deprecated_InputError.toMessage(e), Severity.internalProblem);
|
||||||
return null;
|
return null;
|
||||||
} catch (e, t) {
|
} catch (e, t) {
|
||||||
return reportCrash(e, t);
|
return reportCrash(e, t);
|
||||||
|
|
|
@ -628,7 +628,7 @@ InternalProblemBodyOnAbstractMethod:
|
||||||
|
|
||||||
InternalProblemMissingContext:
|
InternalProblemMissingContext:
|
||||||
template: "Compiler cannot run without a compiler context."
|
template: "Compiler cannot run without a compiler context."
|
||||||
tip: "Are calls to the compiler wrapped in CompilerContext.withGlobalOptions?"
|
tip: "Are calls to the compiler wrapped in CompilerContext.runInContext?"
|
||||||
|
|
||||||
InternalVerificationError:
|
InternalVerificationError:
|
||||||
template: "Verification of the generated program failed: #string."
|
template: "Verification of the generated program failed: #string."
|
||||||
|
@ -881,7 +881,11 @@ CannotReadPackagesFile:
|
||||||
template: "Unable to read '.packages' file:\n #string."
|
template: "Unable to read '.packages' file:\n #string."
|
||||||
|
|
||||||
CantInferPackagesFromManyInputs:
|
CantInferPackagesFromManyInputs:
|
||||||
template: "Cannot 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."
|
||||||
|
|
||||||
|
CantInferPackagesFromPackageUri:
|
||||||
|
template: "Can't infer a .packages file from an input 'package:*' URI."
|
||||||
tip: "Try specifying the file explicitly with the --packages option."
|
tip: "Try specifying the file explicitly with the --packages option."
|
||||||
|
|
||||||
PackageNotFound:
|
PackageNotFound:
|
||||||
|
|
|
@ -20,8 +20,9 @@ import 'dart:convert' show JSON;
|
||||||
import 'dart:io' show File;
|
import 'dart:io' show File;
|
||||||
|
|
||||||
export 'package:testing/testing.dart' show Chain, runMe;
|
export 'package:testing/testing.dart' show Chain, runMe;
|
||||||
import 'package:front_end/physical_file_system.dart';
|
import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/src/fasta/compiler_command_line.dart';
|
import 'package:front_end/src/base/processed_options.dart';
|
||||||
|
import 'package:front_end/src/fasta/compiler_context.dart';
|
||||||
import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
|
import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
|
||||||
import 'package:front_end/src/fasta/deprecated_problems.dart'
|
import 'package:front_end/src/fasta/deprecated_problems.dart'
|
||||||
show deprecated_InputError;
|
show deprecated_InputError;
|
||||||
|
@ -31,9 +32,6 @@ import 'package:front_end/src/fasta/kernel/kernel_target.dart'
|
||||||
import 'package:front_end/src/fasta/kernel/verifier.dart' show verifyProgram;
|
import 'package:front_end/src/fasta/kernel/verifier.dart' show verifyProgram;
|
||||||
import 'package:front_end/src/fasta/testing/kernel_chain.dart' show runDiff;
|
import 'package:front_end/src/fasta/testing/kernel_chain.dart' show runDiff;
|
||||||
import 'package:front_end/src/fasta/testing/patched_sdk_location.dart';
|
import 'package:front_end/src/fasta/testing/patched_sdk_location.dart';
|
||||||
import 'package:front_end/src/fasta/ticker.dart' show Ticker;
|
|
||||||
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
|
|
||||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
|
||||||
import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
|
import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
|
||||||
import 'package:kernel/ast.dart' show Program;
|
import 'package:kernel/ast.dart' show Program;
|
||||||
import 'package:kernel/kernel.dart' show loadProgramFromBytes;
|
import 'package:kernel/kernel.dart' show loadProgramFromBytes;
|
||||||
|
@ -53,7 +51,7 @@ Future<TreeShakerContext> createContext(
|
||||||
|
|
||||||
/// Context used to run the tree-shaking test suite.
|
/// Context used to run the tree-shaking test suite.
|
||||||
class TreeShakerContext extends ChainContext {
|
class TreeShakerContext extends ChainContext {
|
||||||
final UriTranslator uriTranslator;
|
final ProcessedOptions options;
|
||||||
final Uri outlineUri;
|
final Uri outlineUri;
|
||||||
final List<Step> steps;
|
final List<Step> steps;
|
||||||
final List<int> outlineBytes;
|
final List<int> outlineBytes;
|
||||||
|
@ -61,8 +59,8 @@ class TreeShakerContext extends ChainContext {
|
||||||
final ExpectationSet expectationSet =
|
final ExpectationSet expectationSet =
|
||||||
new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
|
new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
|
||||||
|
|
||||||
TreeShakerContext(this.outlineUri, this.uriTranslator, this.outlineBytes,
|
TreeShakerContext(
|
||||||
bool updateExpectations)
|
this.outlineUri, this.options, this.outlineBytes, bool updateExpectations)
|
||||||
: steps = <Step>[
|
: steps = <Step>[
|
||||||
const BuildProgram(),
|
const BuildProgram(),
|
||||||
new CheckShaker(updateExpectations: updateExpectations),
|
new CheckShaker(updateExpectations: updateExpectations),
|
||||||
|
@ -81,12 +79,11 @@ class TreeShakerContext extends ChainContext {
|
||||||
bool updateExpectations = environment["updateExpectations"] == "true";
|
bool updateExpectations = environment["updateExpectations"] == "true";
|
||||||
Uri sdk = await computePatchedSdk();
|
Uri sdk = await computePatchedSdk();
|
||||||
Uri outlineUri = sdk.resolve('outline.dill');
|
Uri outlineUri = sdk.resolve('outline.dill');
|
||||||
Uri packages = Uri.base.resolve(".packages");
|
var options = new CompilerOptions()
|
||||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
..packagesFileUri = Uri.base.resolve(".packages");
|
||||||
.parse(PhysicalFileSystem.instance, sdk, packages: packages);
|
|
||||||
List<int> outlineBytes = new File.fromUri(outlineUri).readAsBytesSync();
|
List<int> outlineBytes = new File.fromUri(outlineUri).readAsBytesSync();
|
||||||
return new TreeShakerContext(
|
return new TreeShakerContext(outlineUri, new ProcessedOptions(options),
|
||||||
outlineUri, uriTranslator, outlineBytes, updateExpectations);
|
outlineBytes, updateExpectations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,17 +95,16 @@ class BuildProgram
|
||||||
String get name => "build program";
|
String get name => "build program";
|
||||||
Future<Result<_IntermediateData>> run(
|
Future<Result<_IntermediateData>> run(
|
||||||
TestDescription description, TreeShakerContext context) async {
|
TestDescription description, TreeShakerContext context) async {
|
||||||
return await CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
return await CompilerContext.runWithOptions(context.options, (_) async {
|
||||||
try {
|
try {
|
||||||
var platformOutline = context.loadPlatformOutline();
|
var platformOutline = context.loadPlatformOutline();
|
||||||
platformOutline.unbindCanonicalNames();
|
platformOutline.unbindCanonicalNames();
|
||||||
var dillTarget = new DillTarget(
|
var uriTranslator = await context.options.getUriTranslator();
|
||||||
new Ticker(isVerbose: false),
|
var dillTarget = new DillTarget(context.options.ticker, uriTranslator,
|
||||||
context.uriTranslator,
|
|
||||||
new VmFastaTarget(new TargetFlags(strongMode: false)));
|
new VmFastaTarget(new TargetFlags(strongMode: false)));
|
||||||
dillTarget.loader.appendLibraries(platformOutline);
|
dillTarget.loader.appendLibraries(platformOutline);
|
||||||
var sourceTarget = new KernelTarget(PhysicalFileSystem.instance, false,
|
var sourceTarget = new KernelTarget(
|
||||||
dillTarget, context.uriTranslator);
|
context.options.fileSystem, false, dillTarget, uriTranslator);
|
||||||
await dillTarget.buildOutlines();
|
await dillTarget.buildOutlines();
|
||||||
|
|
||||||
var inputUri = description.uri;
|
var inputUri = description.uri;
|
||||||
|
|
|
@ -12,8 +12,6 @@ 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/fasta/compiler_command_line.dart';
|
|
||||||
|
|
||||||
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
||||||
show ValidatingInstrumentation;
|
show ValidatingInstrumentation;
|
||||||
|
|
||||||
|
@ -33,6 +31,11 @@ import 'package:testing/testing.dart'
|
||||||
TestDescription,
|
TestDescription,
|
||||||
StdioProcess;
|
StdioProcess;
|
||||||
|
|
||||||
|
import 'package:front_end/compiler_options.dart' show CompilerOptions;
|
||||||
|
|
||||||
|
import 'package:front_end/src/base/processed_options.dart'
|
||||||
|
show ProcessedOptions;
|
||||||
|
|
||||||
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/deprecated_problems.dart'
|
import 'package:front_end/src/fasta/deprecated_problems.dart'
|
||||||
|
@ -224,7 +227,9 @@ class Outline extends Step<TestDescription, Program, FastaContext> {
|
||||||
|
|
||||||
Future<Result<Program>> run(
|
Future<Result<Program>> run(
|
||||||
TestDescription description, FastaContext context) async {
|
TestDescription description, FastaContext context) async {
|
||||||
return await CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
var options =
|
||||||
|
new ProcessedOptions(new CompilerOptions()..throwOnErrors = false);
|
||||||
|
return await CompilerContext.runWithOptions(options, (_) async {
|
||||||
// Disable colors to ensure that expectation files are the same across
|
// Disable colors to ensure that expectation files are the same across
|
||||||
// platforms and independent of stdin/stderr.
|
// platforms and independent of stdin/stderr.
|
||||||
CompilerContext.current.disableColors();
|
CompilerContext.current.disableColors();
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
import 'package:front_end/front_end.dart';
|
import 'package:front_end/front_end.dart';
|
||||||
import 'package:front_end/src/fasta/kernel/utils.dart';
|
import 'package:front_end/src/fasta/kernel/utils.dart';
|
||||||
|
import 'package:front_end/src/fasta/deprecated_problems.dart'
|
||||||
|
show deprecated_InputError;
|
||||||
import 'package:front_end/src/testing/compiler_common.dart';
|
import 'package:front_end/src/testing/compiler_common.dart';
|
||||||
import 'package:kernel/ast.dart';
|
import 'package:kernel/ast.dart';
|
||||||
|
|
||||||
|
@ -61,13 +63,14 @@ main() {
|
||||||
expect(errors.first.message, contains("No 'main' method found"));
|
expect(errors.first.message, contains("No 'main' method found"));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('default error handler throws', () async {
|
test('default error handler throws on errors', () async {
|
||||||
|
var options = new CompilerOptions();
|
||||||
var exceptionThrown = false;
|
var exceptionThrown = false;
|
||||||
try {
|
try {
|
||||||
await compileScript('a() => print("hi");');
|
await compileScript('a() => print("hi");', options: options);
|
||||||
} on CompilationError catch (e) {
|
} on deprecated_InputError catch (e) {
|
||||||
exceptionThrown = true;
|
exceptionThrown = true;
|
||||||
expect(e.message, contains("No 'main' method found"));
|
expect('${e.error}', contains("Compilation aborted"));
|
||||||
}
|
}
|
||||||
expect(exceptionThrown, isTrue);
|
expect(exceptionThrown, isTrue);
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,7 +25,7 @@ import 'package:analyzer/src/summary/format.dart';
|
||||||
import 'package:analyzer/src/summary/idl.dart';
|
import 'package:analyzer/src/summary/idl.dart';
|
||||||
import 'package:analyzer/src/summary/link.dart';
|
import 'package:analyzer/src/summary/link.dart';
|
||||||
import 'package:analyzer/src/summary/summarize_ast.dart';
|
import 'package:analyzer/src/summary/summarize_ast.dart';
|
||||||
import 'package:front_end/compilation_error.dart';
|
import 'package:front_end/compilation_message.dart';
|
||||||
import 'package:front_end/compiler_options.dart';
|
import 'package:front_end/compiler_options.dart';
|
||||||
import 'package:front_end/src/scanner/reader.dart';
|
import 'package:front_end/src/scanner/reader.dart';
|
||||||
import 'package:front_end/src/scanner/scanner.dart';
|
import 'package:front_end/src/scanner/scanner.dart';
|
||||||
|
@ -201,9 +201,12 @@ void _reportErrors(List errors, ErrorHandler onError) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DartkError implements CompilationError {
|
class _DartkError implements CompilationMessage {
|
||||||
String get tip => null;
|
String get tip => null;
|
||||||
SourceSpan get span => null;
|
SourceSpan get span => null;
|
||||||
|
String get analyzerCode => null;
|
||||||
|
String get dart2jsCode => null;
|
||||||
|
Severity get severity => Severity.error;
|
||||||
final String message;
|
final String message;
|
||||||
_DartkError(this.message);
|
_DartkError(this.message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ main() {
|
||||||
..packagesFileUri = Platform.script.resolve('../../../.packages')
|
..packagesFileUri = Platform.script.resolve('../../../.packages')
|
||||||
..compileSdk = true
|
..compileSdk = true
|
||||||
..linkedDependencies = [platform]
|
..linkedDependencies = [platform]
|
||||||
..verify = true
|
..setExitCodeOnProblem = true
|
||||||
..onError = errorHandler;
|
..verify = true;
|
||||||
|
|
||||||
List<int> kernelBinary =
|
List<int> kernelBinary =
|
||||||
serializeProgram(await kernelForProgram(uri, options));
|
serializeProgram(await kernelForProgram(uri, options));
|
||||||
|
@ -79,8 +79,3 @@ main() {
|
||||||
Expect.isNotNull(member);
|
Expect.isNotNull(member);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorHandler(CompilationError e) {
|
|
||||||
exitCode = 1;
|
|
||||||
print(e.message);
|
|
||||||
}
|
|
||||||
|
|
|
@ -78,12 +78,22 @@ Future _processLoadRequest(request) async {
|
||||||
..packagesFileUri = packagesUri
|
..packagesFileUri = packagesUri
|
||||||
..sdkSummary = sdkSummary
|
..sdkSummary = sdkSummary
|
||||||
..verbose = verbose
|
..verbose = verbose
|
||||||
..onError = (CompilationError e) => errors.add(e.message);
|
..throwOnErrors = false
|
||||||
|
..reportMessages = true
|
||||||
|
..onError = (CompilationMessage e) {
|
||||||
|
if (e.severity == Severity.error) {
|
||||||
|
// TODO(sigmund): support emitting code with errors as long as they are
|
||||||
|
// handled in the generated code (issue #30194).
|
||||||
|
errors.add(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
CompilationResult result;
|
CompilationResult result;
|
||||||
try {
|
try {
|
||||||
Program program = await kernelForProgram(script, options);
|
Program program = await kernelForProgram(script, options);
|
||||||
if (errors.isNotEmpty) {
|
if (errors.isNotEmpty) {
|
||||||
|
// TODO(sigmund): the compiler prints errors to the console, so we
|
||||||
|
// shouldn't print those messages again here.
|
||||||
result = new CompilationResult.errors(errors);
|
result = new CompilationResult.errors(errors);
|
||||||
} else {
|
} else {
|
||||||
// We serialize the program excluding platform.dill because the VM has
|
// We serialize the program excluding platform.dill because the VM has
|
||||||
|
|
Loading…
Reference in a new issue