mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:40:07 +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/utilities_dart.dart';
|
||||
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/testing/validating_instrumentation.dart'
|
||||
as fasta;
|
||||
|
@ -135,7 +134,7 @@ class _ElementNamer {
|
|||
|
||||
class _FrontEndInferenceTest extends BaseAnalysisDriverTest {
|
||||
Future<String> runTest(String path, String code) {
|
||||
return fasta.CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
||||
return fasta.CompilerContext.runWithDefaultOptions((_) async {
|
||||
Uri uri = provider.pathContext.toUri(path);
|
||||
|
||||
List<int> lineStarts = new LineInfo.fromContent(code).lineStarts;
|
||||
|
|
|
@ -23,8 +23,8 @@ main(List<String> args) async {
|
|||
..target = new Dart2jsTarget(new TargetFlags())
|
||||
..packagesFileUri = Uri.base.resolve('.packages')
|
||||
..compileSdk = true
|
||||
..linkedDependencies = [Uri.base.resolve(flags['platform'])]
|
||||
..onError = errorHandler;
|
||||
..setExitCodeOnProblem = true
|
||||
..linkedDependencies = [Uri.base.resolve(flags['platform'])];
|
||||
|
||||
if (flags.rest.isEmpty) {
|
||||
var script = relativizeUri(Platform.script);
|
||||
|
@ -39,11 +39,6 @@ main(List<String> args) async {
|
|||
await writeProgramToBinary(program, flags['out']);
|
||||
}
|
||||
|
||||
void errorHandler(CompilationError e) {
|
||||
exitCode = 1;
|
||||
print(e.message);
|
||||
}
|
||||
|
||||
ArgParser _argParser = new ArgParser()
|
||||
..addOption('platform',
|
||||
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:kernel/target/targets.dart' show Target;
|
||||
|
||||
import 'compilation_error.dart';
|
||||
import 'compilation_message.dart';
|
||||
import '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.
|
||||
typedef void ErrorHandler(CompilationError error);
|
||||
typedef void ErrorHandler(CompilationMessage error);
|
||||
|
||||
/// Front-end options relevant to compiler back ends.
|
||||
///
|
||||
|
@ -43,9 +40,21 @@ class CompilerOptions {
|
|||
|
||||
/// Callback to which compilation errors should be delivered.
|
||||
///
|
||||
/// By default, the first error will be reported by throwing an exception of
|
||||
/// type [CompilationError].
|
||||
ErrorHandler onError = defaultErrorHandler;
|
||||
/// By default, when no callback is provided, the compiler will report
|
||||
/// messages on the console and will throw when fatal errors are discovered.
|
||||
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).
|
||||
///
|
||||
|
@ -197,4 +206,30 @@ class CompilerOptions {
|
|||
/// Whether to set the exit code to non-zero if any problem (including
|
||||
/// warning, etc.) is encountered during compilation.
|
||||
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;
|
||||
|
||||
export 'compiler_options.dart';
|
||||
export 'compilation_error.dart';
|
||||
export 'compilation_message.dart';
|
||||
export 'kernel_generator.dart';
|
||||
export 'summary_generator.dart';
|
||||
export 'file_system.dart';
|
||||
|
|
|
@ -13,6 +13,8 @@ import 'package:kernel/kernel.dart' show Program;
|
|||
import 'compiler_options.dart';
|
||||
import 'src/base/processed_options.dart';
|
||||
import 'src/fasta/fasta_codes.dart';
|
||||
import 'src/fasta/compiler_context.dart';
|
||||
import 'src/fasta/severity.dart';
|
||||
import 'src/kernel_generator_impl.dart';
|
||||
|
||||
/// 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?
|
||||
Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
|
||||
var pOptions = new ProcessedOptions(options, false, [source]);
|
||||
var program = (await generateKernel(pOptions))?.program;
|
||||
if (program == null) return null;
|
||||
return await CompilerContext.runWithOptions(pOptions, (context) async {
|
||||
var program = (await generateKernelInternal())?.program;
|
||||
if (program == null) return null;
|
||||
|
||||
if (program.mainMethod == null) {
|
||||
pOptions.reportMessage(messageMissingMain.withLocation(source, -1));
|
||||
return null;
|
||||
}
|
||||
|
||||
return program;
|
||||
if (program.mainMethod == null) {
|
||||
context.options
|
||||
.report(messageMissingMain.withLocation(source, -1), Severity.error);
|
||||
return null;
|
||||
}
|
||||
return program;
|
||||
});
|
||||
}
|
||||
|
||||
/// Generates a kernel representation for a build unit containing [sources].
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
|
||||
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/file_system.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/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/uri_translator.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/multi_root_file_system.dart';
|
||||
import 'package:kernel/kernel.dart'
|
||||
|
@ -24,6 +25,8 @@ import 'package:package_config/src/packages_impl.dart'
|
|||
show NonFilePackagesDirectoryPackages, MapPackages;
|
||||
import 'package:package_config/packages_file.dart' as package_config;
|
||||
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.
|
||||
///
|
||||
|
@ -88,6 +91,14 @@ class ProcessedOptions {
|
|||
|
||||
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
|
||||
/// value filled in.
|
||||
bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi;
|
||||
|
@ -100,10 +111,15 @@ class ProcessedOptions {
|
|||
/// The entry-points provided to the compiler.
|
||||
final List<Uri> inputs;
|
||||
|
||||
/// The Uri where output is generated, may be null.
|
||||
final Uri output;
|
||||
|
||||
/// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
|
||||
ProcessedOptions(CompilerOptions rawOptions,
|
||||
[this._modularApi = false, this.inputs = const []])
|
||||
[this._modularApi = false, this.inputs = const [], this.output])
|
||||
: 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);
|
||||
|
||||
/// The logger to report compilation progress.
|
||||
|
@ -116,18 +132,34 @@ class ProcessedOptions {
|
|||
return _raw.byteStore;
|
||||
}
|
||||
|
||||
void reportMessage(LocatedMessage message) {
|
||||
_raw.onError(new _CompilationMessage(message));
|
||||
bool get _reportMessages => _raw.reportMessages ?? (_raw.onError == null);
|
||||
|
||||
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) =>
|
||||
reportMessage(message.withLocation(null, -1));
|
||||
void reportWithoutLocation(Message message, Severity severity) {
|
||||
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,
|
||||
/// if an option is a path to a file, it checks that the file exists.
|
||||
Future<bool> validateOptions() async {
|
||||
if (verbose) print(debugString());
|
||||
|
||||
if (inputs.isEmpty) {
|
||||
reportMessageWithoutLocation(messageMissingInput);
|
||||
reportWithoutLocation(messageMissingInput, Severity.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -140,30 +172,31 @@ class ProcessedOptions {
|
|||
if (source.scheme != 'dart' &&
|
||||
source.scheme != 'packages' &&
|
||||
!await fileSystem.entityForUri(source).exists()) {
|
||||
reportMessageWithoutLocation(
|
||||
templateInputFileNotFound.withArguments('$source'));
|
||||
reportWithoutLocation(
|
||||
templateInputFileNotFound.withArguments('$source'), Severity.error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_raw.sdkRoot != null &&
|
||||
!await fileSystem.entityForUri(sdkRoot).exists()) {
|
||||
reportMessageWithoutLocation(
|
||||
templateSdkRootNotFound.withArguments('$sdkRoot'));
|
||||
reportWithoutLocation(
|
||||
templateSdkRootNotFound.withArguments('$sdkRoot'), Severity.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
var summary = sdkSummary;
|
||||
if (summary != null && !await fileSystem.entityForUri(summary).exists()) {
|
||||
reportMessageWithoutLocation(
|
||||
templateSdkSummaryNotFound.withArguments('$summary'));
|
||||
reportWithoutLocation(
|
||||
templateSdkSummaryNotFound.withArguments('$summary'), Severity.error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (compileSdk && summary != null) {
|
||||
reportMessageWithoutLocation(
|
||||
reportWithoutLocation(
|
||||
templateInternalProblemUnsupported.withArguments(
|
||||
"The compileSdk and sdkSummary options are mutually exclusive"));
|
||||
"The compileSdk and sdkSummary options are mutually exclusive"),
|
||||
Severity.internalProblem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -263,21 +296,31 @@ class ProcessedOptions {
|
|||
/// This is an asynchronous getter since file system operations may be
|
||||
/// required to locate/read the packages file.
|
||||
Future<Packages> _getPackages() async {
|
||||
if (_packages == null) {
|
||||
if (_raw.packagesFileUri == null) {
|
||||
if (inputs.length > 1) {
|
||||
// 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);
|
||||
}
|
||||
if (_packages != null) return _packages;
|
||||
if (_raw.packagesFileUri != null) {
|
||||
return _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.
|
||||
|
@ -287,9 +330,11 @@ class ProcessedOptions {
|
|||
Map<String, Uri> map = package_config.parse(contents, file);
|
||||
return new MapPackages(map);
|
||||
} catch (e) {
|
||||
reportMessage(templateCannotReadPackagesFile
|
||||
.withArguments("$e")
|
||||
.withLocation(file, -1));
|
||||
report(
|
||||
templateCannotReadPackagesFile
|
||||
.withArguments("$e")
|
||||
.withLocation(file, -1),
|
||||
Severity.error);
|
||||
return Packages.noPackages;
|
||||
}
|
||||
}
|
||||
|
@ -318,8 +363,10 @@ class ProcessedOptions {
|
|||
Future<Packages> _findPackages(Uri scriptUri) async {
|
||||
var dir = scriptUri.resolve('.');
|
||||
if (!dir.isAbsolute) {
|
||||
reportMessageWithoutLocation(templateInternalProblemUnsupported
|
||||
.withArguments("Expected input Uri to be absolute: $scriptUri."));
|
||||
reportWithoutLocation(
|
||||
templateInternalProblemUnsupported
|
||||
.withArguments("Expected input Uri to be absolute: $scriptUri."),
|
||||
Severity.internalProblem);
|
||||
return Packages.noPackages;
|
||||
}
|
||||
|
||||
|
@ -413,6 +460,56 @@ class ProcessedOptions {
|
|||
}
|
||||
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
|
||||
|
@ -441,19 +538,24 @@ class HermeticAccessException extends FileSystemException {
|
|||
String toString() => message;
|
||||
}
|
||||
|
||||
/// Wraps a [LocatedMessage] to implement the public [CompilationError] API.
|
||||
class _CompilationMessage implements CompilationError {
|
||||
final LocatedMessage original;
|
||||
/// Wraps a [LocatedMessage] to implement the public [CompilationMessage] API.
|
||||
class _CompilationMessage implements CompilationMessage {
|
||||
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 =>
|
||||
new SourceLocation(original.charOffset, sourceUrl: original.uri)
|
||||
new SourceLocation(_original.charOffset, sourceUrl: _original.uri)
|
||||
.pointSpan();
|
||||
|
||||
_CompilationMessage(this.original);
|
||||
_CompilationMessage(this._original, this.severity);
|
||||
|
||||
String toString() => message;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class ParsedArguments {
|
|||
toString() => "ParsedArguments($options, $arguments)";
|
||||
}
|
||||
|
||||
/// Abstract parser for command-line options.
|
||||
class CommandLine {
|
||||
final Map<String, dynamic> options;
|
||||
|
||||
|
|
|
@ -34,16 +34,9 @@ const bool hideWarnings = false;
|
|||
/// command-line tool. This includes source snippets and different colors based
|
||||
/// 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
|
||||
/// be called directly.
|
||||
String formatInternal(Message message, Severity severity, Uri uri, int offset) {
|
||||
if (CompilerContext.current.options.setExitCodeOnProblem) {
|
||||
exitCode = 1;
|
||||
}
|
||||
String text =
|
||||
"${severityName(severity, capitalized: true)}: ${message.message}";
|
||||
if (message.tip != null) {
|
||||
|
@ -107,16 +100,16 @@ bool isHidden(Severity severity) {
|
|||
bool isFatal(Severity severity) {
|
||||
switch (severity) {
|
||||
case Severity.error:
|
||||
return CompilerContext.current.options.errorsAreFatal;
|
||||
return CompilerContext.current.options.throwOnErrors;
|
||||
|
||||
case Severity.internalProblem:
|
||||
return true;
|
||||
|
||||
case Severity.nit:
|
||||
return CompilerContext.current.options.nitsAreFatal;
|
||||
return CompilerContext.current.options.throwOnNits;
|
||||
|
||||
case Severity.warning:
|
||||
return CompilerContext.current.options.warningsAreFatal;
|
||||
return CompilerContext.current.options.throwOnWarnings;
|
||||
}
|
||||
return unhandled("$severity", "isFatal", -1, null);
|
||||
}
|
||||
|
@ -139,11 +132,25 @@ String severityName(Severity severity, {bool capitalized: false}) {
|
|||
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(
|
||||
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);
|
||||
if (isFatal(severity)) {
|
||||
if (isVerbose) print(StackTrace.current);
|
||||
// TODO(sigmund,ahe): ensure there is no circularity when InputError is
|
||||
// handled.
|
||||
throw new deprecated_InputError(uri, charOffset,
|
||||
"Compilation aborted due to fatal ${severityName(severity)}.");
|
||||
}
|
||||
|
|
|
@ -8,11 +8,7 @@ import 'dart:async' show Future;
|
|||
|
||||
import 'dart:io' show exitCode, File;
|
||||
|
||||
import '../../compiler_options.dart' show CompilerOptions;
|
||||
|
||||
import '../base/processed_options.dart' show ProcessedOptions;
|
||||
|
||||
import '../kernel_generator_impl.dart' show generateKernel;
|
||||
import '../kernel_generator_impl.dart' show generateKernelInternal;
|
||||
|
||||
import 'compiler_command_line.dart' show CompilerCommandLine;
|
||||
|
||||
|
@ -24,8 +20,6 @@ import 'kernel/utils.dart' show writeProgramToFile;
|
|||
|
||||
import 'severity.dart' show Severity;
|
||||
|
||||
import 'ticker.dart' show Ticker;
|
||||
|
||||
const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
|
||||
|
||||
Future mainEntryPoint(List<String> arguments) async {
|
||||
|
@ -37,54 +31,44 @@ Future mainEntryPoint(List<String> arguments) async {
|
|||
await compilePlatform(arguments);
|
||||
} on deprecated_InputError catch (e) {
|
||||
exitCode = 1;
|
||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
||||
.current
|
||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
CompilerContext.runWithDefaultOptions(
|
||||
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future compilePlatform(List<String> arguments) async {
|
||||
Ticker ticker = new Ticker();
|
||||
await CompilerCommandLine.withGlobalOptions("compile_platform", arguments,
|
||||
(CompilerContext c) {
|
||||
Uri patchedSdk = Uri.base.resolveUri(new Uri.file(c.options.arguments[0]));
|
||||
Uri fullOutput = Uri.base.resolveUri(new Uri.file(c.options.arguments[1]));
|
||||
Uri outlineOutput =
|
||||
Uri.base.resolveUri(new Uri.file(c.options.arguments[2]));
|
||||
return compilePlatformInternal(
|
||||
c, ticker, patchedSdk, fullOutput, outlineOutput);
|
||||
await CompilerCommandLine
|
||||
.withGlobalOptions("compile_platform", arguments, false,
|
||||
(CompilerContext c, List<String> restArguments) {
|
||||
c.options.inputs.add(Uri.parse('dart:core'));
|
||||
// Note: the patchedSdk argument is already stored in c.options.sdkRoot.
|
||||
Uri fullOutput = Uri.base.resolveUri(new Uri.file(restArguments[1]));
|
||||
Uri outlineOutput = Uri.base.resolveUri(new Uri.file(restArguments[2]));
|
||||
return compilePlatformInternal(c, fullOutput, outlineOutput);
|
||||
});
|
||||
}
|
||||
|
||||
Future compilePlatformInternal(CompilerContext c, Ticker ticker, Uri patchedSdk,
|
||||
Uri fullOutput, Uri outlineOutput) async {
|
||||
var options = new CompilerOptions()
|
||||
..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) {
|
||||
Future compilePlatformInternal(
|
||||
CompilerContext c, Uri fullOutput, Uri outlineOutput) async {
|
||||
if (c.options.strongMode) {
|
||||
print("Note: strong mode support is preliminary and may not work.");
|
||||
}
|
||||
if (options.verbose) {
|
||||
print("Generating outline of $patchedSdk into $outlineOutput");
|
||||
print("Compiling $patchedSdk to $fullOutput");
|
||||
if (c.options.verbose) {
|
||||
print("Generating outline of ${c.options.sdkRoot} into $outlineOutput");
|
||||
print("Compiling ${c.options.sdkRoot} to $fullOutput");
|
||||
}
|
||||
|
||||
var result = await generateKernel(
|
||||
new ProcessedOptions(options, false, [Uri.parse('dart:core')]),
|
||||
buildSummary: true,
|
||||
buildProgram: true);
|
||||
var result =
|
||||
await generateKernelInternal(buildSummary: true, buildProgram: true);
|
||||
if (result == null) {
|
||||
// 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);
|
||||
ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
|
||||
c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
|
||||
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:async' show runZoned;
|
||||
|
||||
import 'package:kernel/target/targets.dart'
|
||||
show Target, getTarget, TargetFlags, targets;
|
||||
|
||||
import '../../compiler_options.dart';
|
||||
import '../base/processed_options.dart';
|
||||
import 'command_line.dart' show CommandLine, deprecated_argumentError;
|
||||
|
||||
import 'compiler_context.dart' show CompilerContext, compilerContextKey;
|
||||
|
||||
import 'command_line_reporting.dart' as command_line_reporting;
|
||||
import 'compiler_context.dart' show CompilerContext;
|
||||
|
||||
import 'fasta_codes.dart'
|
||||
show
|
||||
LocatedMessage,
|
||||
Message,
|
||||
messageFastaUsageLong,
|
||||
messageFastaUsageShort,
|
||||
templateUnspecified;
|
||||
|
||||
import 'severity.dart' show Severity;
|
||||
|
||||
const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
||||
"--compile-sdk": Uri,
|
||||
"--fatal": ",",
|
||||
|
@ -39,6 +34,8 @@ const Map<String, dynamic> optionSpecification = const <String, dynamic>{
|
|||
"-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 {
|
||||
final String programName;
|
||||
|
||||
|
@ -61,13 +58,9 @@ class CompilerCommandLine extends CommandLine {
|
|||
options.containsKey("/?");
|
||||
}
|
||||
|
||||
bool get setExitCodeOnProblem {
|
||||
return options.containsKey("--set-exit-code-on-problem");
|
||||
}
|
||||
|
||||
void validate() {
|
||||
if (help) {
|
||||
print(computeUsage(programName, verbose));
|
||||
print(computeUsage(programName, verbose).message);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -84,8 +77,16 @@ class CompilerCommandLine extends CommandLine {
|
|||
return deprecated_argumentError(
|
||||
usage, "Can't specify both '--compile-sdk' and '--platform'.");
|
||||
}
|
||||
if (programName == "compile_platform" && arguments.length != 3) {
|
||||
return deprecated_argumentError(usage, "Expected three arguments.");
|
||||
if (programName == "compile_platform") {
|
||||
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) {
|
||||
return deprecated_argumentError(usage, "No Dart file specified.");
|
||||
}
|
||||
|
@ -113,7 +114,7 @@ class CompilerCommandLine extends CommandLine {
|
|||
: 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"];
|
||||
|
||||
|
@ -135,43 +136,41 @@ class CompilerCommandLine extends CommandLine {
|
|||
|
||||
Target get target => options["target"];
|
||||
|
||||
void Function(LocatedMessage, Severity) get report {
|
||||
return options["report"] ?? command_line_reporting.report;
|
||||
}
|
||||
static dynamic withGlobalOptions(
|
||||
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 {
|
||||
return options["reportWithoutLocation"] ??
|
||||
command_line_reporting.reportWithoutLocation;
|
||||
}
|
||||
|
||||
String Function(LocatedMessage, Severity) get format {
|
||||
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});
|
||||
var inputs = <Uri>[];
|
||||
if (areRestArgumentsInputs) {
|
||||
inputs = cl.arguments.map(Uri.base.resolve).toList();
|
||||
}
|
||||
var pOptions = new ProcessedOptions(options, false, inputs, cl.output);
|
||||
return CompilerContext.runWithOptions(pOptions, (c) => f(c, cl.arguments));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ library fasta.compiler_context;
|
|||
|
||||
import 'dart:async' show Zone, runZoned;
|
||||
|
||||
import 'package:front_end/compiler_options.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:kernel/ast.dart' show Source;
|
||||
|
||||
import 'compiler_command_line.dart' show CompilerCommandLine;
|
||||
import 'command_line_reporting.dart' as command_line_reporting;
|
||||
|
||||
import 'colors.dart' show computeEnableColors;
|
||||
|
||||
|
@ -21,13 +21,28 @@ import 'severity.dart' show Severity;
|
|||
|
||||
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 {
|
||||
final FileSystem fileSystem = PhysicalFileSystem.instance;
|
||||
|
||||
final CompilerCommandLine options;
|
||||
// TODO(sigmund): Move here any method in ProcessedOptions that doesn't seem
|
||||
// appropriate as an "option", or consider merging ProcessedOptions entirely
|
||||
// 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>{};
|
||||
|
||||
FileSystem get fileSystem => options.fileSystem;
|
||||
|
||||
bool enableColorsCached = null;
|
||||
|
||||
CompilerContext(this.options);
|
||||
|
@ -48,12 +63,12 @@ class CompilerContext {
|
|||
|
||||
/// Format [message] as a text string that can be included in generated code.
|
||||
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.
|
||||
String formatWithoutLocation(Message message, Severity severity) {
|
||||
return options.formatWithoutLocation(message, severity);
|
||||
return command_line_reporting.formatWithoutLocation(message, severity);
|
||||
}
|
||||
|
||||
static CompilerContext get current {
|
||||
|
@ -68,12 +83,22 @@ class CompilerContext {
|
|||
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`.
|
||||
static dynamic withGlobalOptions(
|
||||
CompilerCommandLine cl, dynamic action(CompilerContext c)) {
|
||||
CompilerContext c = new CompilerContext(cl);
|
||||
return runZoned(() => action(c), zoneValues: {compilerContextKey: c});
|
||||
T runInContext<T>(T action(CompilerContext c)) {
|
||||
return runZoned(() => action(this), zoneValues: {compilerContextKey: this});
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
|
|
@ -10,9 +10,10 @@ import 'dart:convert' show JSON;
|
|||
|
||||
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/src/fasta/kernel/utils.dart';
|
||||
import 'package:front_end/src/fasta/uri_translator_impl.dart';
|
||||
|
||||
import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
|
||||
|
||||
|
@ -25,9 +26,9 @@ import 'deprecated_problems.dart'
|
|||
|
||||
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;
|
||||
|
||||
|
@ -70,8 +71,8 @@ outlineEntryPoint(List<String> arguments) async {
|
|||
|
||||
Future<KernelTarget> outline(List<String> arguments) async {
|
||||
try {
|
||||
return await CompilerCommandLine.withGlobalOptions("outline", arguments,
|
||||
(CompilerContext c) async {
|
||||
return await CompilerCommandLine.withGlobalOptions(
|
||||
"outline", arguments, true, (CompilerContext c, _) async {
|
||||
if (c.options.verbose) {
|
||||
print("Building outlines for ${arguments.join(' ')}");
|
||||
}
|
||||
|
@ -81,17 +82,16 @@ Future<KernelTarget> outline(List<String> arguments) async {
|
|||
});
|
||||
} on deprecated_InputError catch (e) {
|
||||
exitCode = 1;
|
||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
||||
.current
|
||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
CompilerContext.runWithDefaultOptions(
|
||||
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uri> compile(List<String> arguments) async {
|
||||
try {
|
||||
return await CompilerCommandLine.withGlobalOptions("compile", arguments,
|
||||
(CompilerContext c) async {
|
||||
return await CompilerCommandLine.withGlobalOptions(
|
||||
"compile", arguments, true, (CompilerContext c, _) async {
|
||||
if (c.options.verbose) {
|
||||
print("Compiling directly to Kernel: ${arguments.join(' ')}");
|
||||
}
|
||||
|
@ -101,9 +101,8 @@ Future<Uri> compile(List<String> arguments) async {
|
|||
});
|
||||
} on deprecated_InputError catch (e) {
|
||||
exitCode = 1;
|
||||
CompilerCommandLine.deprecated_withDefaultOptions(() => CompilerContext
|
||||
.current
|
||||
.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
CompilerContext.runWithDefaultOptions(
|
||||
(c) => c.report(deprecated_InputError.toMessage(e), Severity.error));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -125,8 +124,7 @@ class CompileTask {
|
|||
}
|
||||
|
||||
Future<KernelTarget> buildOutline([Uri output]) async {
|
||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
||||
.parse(c.fileSystem, c.options.sdk, packages: c.options.packages);
|
||||
UriTranslator uriTranslator = await c.options.getUriTranslator();
|
||||
ticker.logMs("Read packages file");
|
||||
DillTarget dillTarget = createDillTarget(uriTranslator);
|
||||
KernelTarget kernelTarget =
|
||||
|
@ -134,13 +132,12 @@ class CompileTask {
|
|||
if (c.options.strongMode) {
|
||||
print("Note: strong mode support is preliminary and may not work.");
|
||||
}
|
||||
Uri platform = c.options.platform;
|
||||
Uri platform = c.options.sdkSummary;
|
||||
if (platform != null) {
|
||||
_appendDillForUri(dillTarget, platform);
|
||||
}
|
||||
String argument = c.options.arguments.first;
|
||||
Uri uri = Uri.base.resolve(argument);
|
||||
String path = uriTranslator.translate(uri)?.path ?? argument;
|
||||
Uri uri = c.options.inputs.first;
|
||||
String path = uriTranslator.translate(uri)?.path ?? uri.path;
|
||||
if (path.endsWith(".dart")) {
|
||||
kernelTarget.read(uri);
|
||||
} else {
|
||||
|
@ -148,7 +145,7 @@ class CompileTask {
|
|||
}
|
||||
await dillTarget.buildOutlines();
|
||||
var outline = await kernelTarget.buildOutlines();
|
||||
if (c.options.dumpIr && output != null) {
|
||||
if (c.options.debugDump && output != null) {
|
||||
printProgramText(outline, libraryFilter: kernelTarget.isSourceLibrary);
|
||||
}
|
||||
if (output != null) {
|
||||
|
@ -163,7 +160,7 @@ class CompileTask {
|
|||
if (exitCode != 0) return null;
|
||||
Uri uri = c.options.output;
|
||||
var program = await kernelTarget.buildProgram(verify: c.options.verify);
|
||||
if (c.options.dumpIr) {
|
||||
if (c.options.debugDump) {
|
||||
printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
|
||||
}
|
||||
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.
|
||||
Future<List<Uri>> getDependencies(Uri script,
|
||||
{Uri sdk,
|
||||
Uri packages,
|
||||
Uri platform,
|
||||
bool verbose: false,
|
||||
String backendTarget}) async {
|
||||
backendTarget ??= "vm_fasta";
|
||||
Ticker ticker = new Ticker(isVerbose: verbose);
|
||||
return await CompilerCommandLine.withGlobalOptions("", [""],
|
||||
Target target}) async {
|
||||
var options = new CompilerOptions()
|
||||
..target = target
|
||||
..verbose = verbose
|
||||
..packagesFileUri = packages
|
||||
..sdkSummary = platform
|
||||
..sdkRoot = sdk;
|
||||
var pOptions = new ProcessedOptions(options);
|
||||
return await CompilerContext.runWithOptions(pOptions,
|
||||
(CompilerContext c) async {
|
||||
c.options.options["--target"] = backendTarget;
|
||||
c.options.options["--strong-mode"] = false;
|
||||
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");
|
||||
UriTranslator uriTranslator = await c.options.getUriTranslator();
|
||||
c.options.ticker.logMs("Read packages file");
|
||||
DillTarget dillTarget =
|
||||
new DillTarget(ticker, uriTranslator, c.options.target);
|
||||
new DillTarget(c.options.ticker, uriTranslator, c.options.target);
|
||||
if (platform != null) _appendDillForUri(dillTarget, platform);
|
||||
KernelTarget kernelTarget = new KernelTarget(PhysicalFileSystem.instance,
|
||||
false, dillTarget, uriTranslator, c.uriToSource);
|
||||
|
|
|
@ -209,7 +209,17 @@ const Code<Null> codeCantInferPackagesFromManyInputs =
|
|||
const MessageCode messageCantInferPackagesFromManyInputs = const MessageCode(
|
||||
"CantInferPackagesFromManyInputs",
|
||||
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.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
|
@ -1394,7 +1404,7 @@ const MessageCode messageInternalProblemMissingContext = const MessageCode(
|
|||
"InternalProblemMissingContext",
|
||||
message: r"""Compiler cannot run without a compiler context.""",
|
||||
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.
|
||||
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 {
|
||||
Uri uri;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
await CompilerCommandLine.withGlobalOptions("run", arguments,
|
||||
(CompilerContext c) async {
|
||||
await CompilerCommandLine.withGlobalOptions("run", arguments, false,
|
||||
(CompilerContext c, List<String> restArguments) async {
|
||||
var input = Uri.base.resolve(restArguments[0]);
|
||||
c.options.inputs.add(input);
|
||||
if (i > 0) {
|
||||
print("\n");
|
||||
}
|
||||
|
@ -46,17 +48,17 @@ mainEntryPoint(List<String> arguments) async {
|
|||
}
|
||||
if (exitCode != 0) exit(exitCode);
|
||||
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 dartVm = computeDartVm(sdk);
|
||||
List<String> arguments = <String>["${uri.toFilePath()}"]
|
||||
..addAll(c.options.arguments.skip(1));
|
||||
..addAll(allArguments.skip(1));
|
||||
if (c.options.verbose) {
|
||||
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 bool excludeSource = CompilerContext.current.options.excludeSource;
|
||||
final bool excludeSource = !CompilerContext.current.options.embedSourceText;
|
||||
|
||||
// Used when building directly to kernel.
|
||||
ClassHierarchy hierarchy;
|
||||
|
|
|
@ -25,7 +25,7 @@ import 'package:kernel/ast.dart' show Library, Program;
|
|||
|
||||
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;
|
||||
|
||||
|
@ -38,6 +38,9 @@ import 'package:kernel/ast.dart' show Program;
|
|||
|
||||
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;
|
||||
|
||||
class Print extends Step<Program, Program, ChainContext> {
|
||||
|
@ -67,7 +70,9 @@ class Verify extends Step<Program, Program, ChainContext> {
|
|||
String get name => "verify";
|
||||
|
||||
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);
|
||||
if (errors.isEmpty) {
|
||||
return pass(program);
|
||||
|
@ -191,7 +196,7 @@ class Compile extends Step<TestDescription, Program, CompileContext> {
|
|||
Future<Result<Program>> run(
|
||||
TestDescription description, CompileContext context) async {
|
||||
Result<Program> result;
|
||||
reportError(CompilationError error) {
|
||||
reportError(CompilationMessage error) {
|
||||
result ??= fail(null, error.message);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
import 'dart:async';
|
||||
|
||||
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/processed_options.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/dill/dill_library_builder.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 {
|
||||
return await CompilerCommandLine.withGlobalOptions("", [""],
|
||||
(CompilerContext context) {
|
||||
context.options.options["--target"] = _target;
|
||||
context.options.options["report"] = (message, severity) {};
|
||||
context.options.options["reportWithoutLocation"] = (message, severity) {};
|
||||
return _logger.runAsync(msg, f);
|
||||
});
|
||||
var options = new CompilerOptions()
|
||||
..target = _target
|
||||
// Note: we do not report error on the console because the driver is an
|
||||
// ongoing background service that shouldn't polute stdout.
|
||||
// TODO(scheglov,sigmund): add an error handler to forward errors to
|
||||
// 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
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'dart:async';
|
|||
import 'package:kernel/kernel.dart' show Program, CanonicalName;
|
||||
|
||||
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/deprecated_problems.dart' show deprecated_InputError, reportCrash;
|
||||
import 'fasta/dill/dill_target.dart' show DillTarget;
|
||||
|
@ -27,34 +27,19 @@ Future<CompilerResult> generateKernel(ProcessedOptions options,
|
|||
{bool buildSummary: false,
|
||||
bool buildProgram: true,
|
||||
bool trimDependencies: false}) async {
|
||||
// TODO(sigmund): Replace CompilerCommandLine and instead simply use a
|
||||
// CompilerContext that directly uses the ProcessedOptions through the
|
||||
// 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,
|
||||
return await CompilerContext.runWithOptions(options, (_) async {
|
||||
return await generateKernelInternal(
|
||||
buildSummary: buildSummary,
|
||||
buildProgram: buildProgram,
|
||||
trimDependencies: trimDependencies);
|
||||
});
|
||||
}
|
||||
|
||||
Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
||||
Future<CompilerResult> generateKernelInternal(
|
||||
{bool buildSummary: false,
|
||||
bool buildProgram: true,
|
||||
bool trimDependencies: false}) async {
|
||||
var options = CompilerContext.current.options;
|
||||
var fs = options.fileSystem;
|
||||
if (!await options.validateOptions()) return null;
|
||||
options.ticker.logMs("Validated arguments");
|
||||
|
@ -120,7 +105,9 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
|||
trimProgram(summaryProgram, (uri) => !excluded.contains(uri));
|
||||
}
|
||||
if (options.verify) {
|
||||
verifyProgram(summaryProgram).forEach(options.reportMessage);
|
||||
for (var error in verifyProgram(summaryProgram)) {
|
||||
options.report(error, Severity.error);
|
||||
}
|
||||
}
|
||||
if (options.debugDump) {
|
||||
printProgramText(summaryProgram,
|
||||
|
@ -147,8 +134,8 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
|||
}
|
||||
|
||||
if (kernelTarget.errors.isNotEmpty) {
|
||||
// TODO(ahe): The errors have already been reported via CompilerContext.
|
||||
kernelTarget.errors.forEach(options.reportMessage);
|
||||
// Note: we don't report errors here because they have been already
|
||||
// reported through the compiler context.
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -157,7 +144,8 @@ Future<CompilerResult> generateKernelInternal(ProcessedOptions options,
|
|||
program: program,
|
||||
deps: kernelTarget.loader.getDependencies());
|
||||
} on deprecated_InputError catch (e) {
|
||||
options.reportMessage(deprecated_InputError.toMessage(e));
|
||||
options.report(
|
||||
deprecated_InputError.toMessage(e), Severity.internalProblem);
|
||||
return null;
|
||||
} catch (e, t) {
|
||||
return reportCrash(e, t);
|
||||
|
|
|
@ -628,7 +628,7 @@ InternalProblemBodyOnAbstractMethod:
|
|||
|
||||
InternalProblemMissingContext:
|
||||
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:
|
||||
template: "Verification of the generated program failed: #string."
|
||||
|
@ -881,7 +881,11 @@ CannotReadPackagesFile:
|
|||
template: "Unable to read '.packages' file:\n #string."
|
||||
|
||||
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."
|
||||
|
||||
PackageNotFound:
|
||||
|
|
|
@ -20,8 +20,9 @@ import 'dart:convert' show JSON;
|
|||
import 'dart:io' show File;
|
||||
|
||||
export 'package:testing/testing.dart' show Chain, runMe;
|
||||
import 'package:front_end/physical_file_system.dart';
|
||||
import 'package:front_end/src/fasta/compiler_command_line.dart';
|
||||
import 'package:front_end/compiler_options.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/deprecated_problems.dart'
|
||||
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/testing/kernel_chain.dart' show runDiff;
|
||||
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:kernel/ast.dart' show Program;
|
||||
import 'package:kernel/kernel.dart' show loadProgramFromBytes;
|
||||
|
@ -53,7 +51,7 @@ Future<TreeShakerContext> createContext(
|
|||
|
||||
/// Context used to run the tree-shaking test suite.
|
||||
class TreeShakerContext extends ChainContext {
|
||||
final UriTranslator uriTranslator;
|
||||
final ProcessedOptions options;
|
||||
final Uri outlineUri;
|
||||
final List<Step> steps;
|
||||
final List<int> outlineBytes;
|
||||
|
@ -61,8 +59,8 @@ class TreeShakerContext extends ChainContext {
|
|||
final ExpectationSet expectationSet =
|
||||
new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
|
||||
|
||||
TreeShakerContext(this.outlineUri, this.uriTranslator, this.outlineBytes,
|
||||
bool updateExpectations)
|
||||
TreeShakerContext(
|
||||
this.outlineUri, this.options, this.outlineBytes, bool updateExpectations)
|
||||
: steps = <Step>[
|
||||
const BuildProgram(),
|
||||
new CheckShaker(updateExpectations: updateExpectations),
|
||||
|
@ -81,12 +79,11 @@ class TreeShakerContext extends ChainContext {
|
|||
bool updateExpectations = environment["updateExpectations"] == "true";
|
||||
Uri sdk = await computePatchedSdk();
|
||||
Uri outlineUri = sdk.resolve('outline.dill');
|
||||
Uri packages = Uri.base.resolve(".packages");
|
||||
UriTranslator uriTranslator = await UriTranslatorImpl
|
||||
.parse(PhysicalFileSystem.instance, sdk, packages: packages);
|
||||
var options = new CompilerOptions()
|
||||
..packagesFileUri = Uri.base.resolve(".packages");
|
||||
List<int> outlineBytes = new File.fromUri(outlineUri).readAsBytesSync();
|
||||
return new TreeShakerContext(
|
||||
outlineUri, uriTranslator, outlineBytes, updateExpectations);
|
||||
return new TreeShakerContext(outlineUri, new ProcessedOptions(options),
|
||||
outlineBytes, updateExpectations);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,17 +95,16 @@ class BuildProgram
|
|||
String get name => "build program";
|
||||
Future<Result<_IntermediateData>> run(
|
||||
TestDescription description, TreeShakerContext context) async {
|
||||
return await CompilerCommandLine.withGlobalOptions("", [""], (_) async {
|
||||
return await CompilerContext.runWithOptions(context.options, (_) async {
|
||||
try {
|
||||
var platformOutline = context.loadPlatformOutline();
|
||||
platformOutline.unbindCanonicalNames();
|
||||
var dillTarget = new DillTarget(
|
||||
new Ticker(isVerbose: false),
|
||||
context.uriTranslator,
|
||||
var uriTranslator = await context.options.getUriTranslator();
|
||||
var dillTarget = new DillTarget(context.options.ticker, uriTranslator,
|
||||
new VmFastaTarget(new TargetFlags(strongMode: false)));
|
||||
dillTarget.loader.appendLibraries(platformOutline);
|
||||
var sourceTarget = new KernelTarget(PhysicalFileSystem.instance, false,
|
||||
dillTarget, context.uriTranslator);
|
||||
var sourceTarget = new KernelTarget(
|
||||
context.options.fileSystem, false, dillTarget, uriTranslator);
|
||||
await dillTarget.buildOutlines();
|
||||
|
||||
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/src/fasta/compiler_command_line.dart';
|
||||
|
||||
import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
|
||||
show ValidatingInstrumentation;
|
||||
|
||||
|
@ -33,6 +31,11 @@ import 'package:testing/testing.dart'
|
|||
TestDescription,
|
||||
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/deprecated_problems.dart'
|
||||
|
@ -224,7 +227,9 @@ class Outline extends Step<TestDescription, Program, FastaContext> {
|
|||
|
||||
Future<Result<Program>> run(
|
||||
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
|
||||
// platforms and independent of stdin/stderr.
|
||||
CompilerContext.current.disableColors();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
import 'package:front_end/front_end.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:kernel/ast.dart';
|
||||
|
||||
|
@ -61,13 +63,14 @@ main() {
|
|||
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;
|
||||
try {
|
||||
await compileScript('a() => print("hi");');
|
||||
} on CompilationError catch (e) {
|
||||
await compileScript('a() => print("hi");', options: options);
|
||||
} on deprecated_InputError catch (e) {
|
||||
exceptionThrown = true;
|
||||
expect(e.message, contains("No 'main' method found"));
|
||||
expect('${e.error}', contains("Compilation aborted"));
|
||||
}
|
||||
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/link.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/src/scanner/reader.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;
|
||||
SourceSpan get span => null;
|
||||
String get analyzerCode => null;
|
||||
String get dart2jsCode => null;
|
||||
Severity get severity => Severity.error;
|
||||
final String message;
|
||||
_DartkError(this.message);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ main() {
|
|||
..packagesFileUri = Platform.script.resolve('../../../.packages')
|
||||
..compileSdk = true
|
||||
..linkedDependencies = [platform]
|
||||
..verify = true
|
||||
..onError = errorHandler;
|
||||
..setExitCodeOnProblem = true
|
||||
..verify = true;
|
||||
|
||||
List<int> kernelBinary =
|
||||
serializeProgram(await kernelForProgram(uri, options));
|
||||
|
@ -79,8 +79,3 @@ main() {
|
|||
Expect.isNotNull(member);
|
||||
});
|
||||
}
|
||||
|
||||
void errorHandler(CompilationError e) {
|
||||
exitCode = 1;
|
||||
print(e.message);
|
||||
}
|
||||
|
|
|
@ -78,12 +78,22 @@ Future _processLoadRequest(request) async {
|
|||
..packagesFileUri = packagesUri
|
||||
..sdkSummary = sdkSummary
|
||||
..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;
|
||||
try {
|
||||
Program program = await kernelForProgram(script, options);
|
||||
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);
|
||||
} else {
|
||||
// We serialize the program excluding platform.dill because the VM has
|
||||
|
|
Loading…
Reference in a new issue