c878108cc8
All non-pubspec changes generated by `dart format pkg/compiler`. Change-Id: Iadaa70974816d96ccb47813fe72d5a2bb83d6bda Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400181 Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
281 lines
8.8 KiB
Dart
281 lines
8.8 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library;
|
|
|
|
import 'dart:async';
|
|
import 'dart:typed_data';
|
|
|
|
// ignore: implementation_imports
|
|
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
|
|
|
|
import 'src/compiler.dart';
|
|
import 'src/diagnostics/messages.dart';
|
|
import 'src/options.dart';
|
|
|
|
/// Kind of diagnostics that the compiler can report.
|
|
enum Diagnostic {
|
|
/// An error as identified by the "Dart Programming Language
|
|
/// Specification" [https://dart.dev/guides/language/spec].
|
|
///
|
|
/// Note: the compiler may still produce an executable result after
|
|
/// reporting a compilation error. The specification says:
|
|
///
|
|
/// "A compile-time error must be reported by a Dart compiler before
|
|
/// the erroneous code is executed." and "If a compile-time error
|
|
/// occurs within the code of a running isolate A, A is immediately
|
|
/// suspended."
|
|
///
|
|
/// This means that the compiler can generate code that when executed
|
|
/// terminates execution.
|
|
error('error'),
|
|
|
|
/// A warning as identified by the "Dart Programming Language
|
|
/// Specification" [https://dart.dev/guides/language/spec].
|
|
warning('warning'),
|
|
|
|
/// Any other warning that is not covered by [warning].
|
|
hint('hint'),
|
|
|
|
/// Informational message about the compiler.
|
|
info('info'),
|
|
|
|
/// Informational messages that shouldn't be printed unless
|
|
/// explicitly requested by the user of a compiler.
|
|
verboseInfo('verbose info'),
|
|
|
|
/// An internal error in the compiler.
|
|
crash('crash'),
|
|
|
|
/// Additional information about the preceding non-info diagnostic from the
|
|
/// compiler.
|
|
///
|
|
/// For example, consider a duplicated definition. The compiler first emits a
|
|
/// message about the duplicated definition, then emits an info message about
|
|
/// the location of the existing definition.
|
|
context('context');
|
|
|
|
/// An [int] representation of this kind. The ordinals are designed
|
|
/// to be used as bitsets.
|
|
int get ordinal => 2 << index;
|
|
|
|
/// The name of this kind.
|
|
final String name;
|
|
|
|
const Diagnostic(this.name);
|
|
|
|
@override
|
|
String toString() => name;
|
|
}
|
|
|
|
// Unless explicitly allowed, passing `null` for any argument to the
|
|
// methods of library will result in an Error being thrown.
|
|
|
|
/// Input kinds used by [CompilerInput.readFromUri].
|
|
enum InputKind {
|
|
/// Data is read as UTF8 either as a [String] or a zero-terminated
|
|
/// `List<int>`.
|
|
utf8,
|
|
|
|
/// Data is read as bytes in a `List<int>`.
|
|
binary,
|
|
}
|
|
|
|
/// Interface for data read through [CompilerInput.readFromUri].
|
|
abstract class Input<T> {
|
|
/// The URI from which data was read.
|
|
Uri get uri;
|
|
|
|
/// The format of the read [data].
|
|
InputKind get inputKind;
|
|
|
|
/// The raw data read from [uri].
|
|
T get data;
|
|
|
|
/// Release any resources held by the input. After releasing, a call to `get
|
|
/// data` will fail, and previously returned data may be invalid.
|
|
void release();
|
|
}
|
|
|
|
/// Interface for providing the compiler with input. That is, Dart source files,
|
|
/// package config files, etc.
|
|
abstract class CompilerInput {
|
|
/// Returns a future that completes to the source corresponding to [uri].
|
|
/// If an exception occurs, the future completes with this exception.
|
|
///
|
|
/// If [inputKind] is `InputKind.UTF8` the source is represented as a
|
|
/// zero-terminated list of encoded bytes. If the input kind is
|
|
/// `InputKind.binary` the resulting list is the raw bytes from the input
|
|
/// source.
|
|
Future<Input<Uint8List>> readFromUri(
|
|
Uri uri, {
|
|
InputKind inputKind = InputKind.utf8,
|
|
});
|
|
|
|
/// Register that [uri] should be an `InputKind.UTF8` input with the
|
|
/// given [source] of contents.
|
|
///
|
|
/// If [uri] was read prior to this call, this registration has no effect,
|
|
/// otherwise it is expected that a future [readFromUri] will return the
|
|
/// contents provided here.
|
|
///
|
|
/// The main purpose of this API is to assist in error reporting when
|
|
/// compiling from kernel binary files. Binary files embed the contents
|
|
/// of source files that may not be available on disk. By using these
|
|
/// registered contents, dart2js will be able to provide accurate line/column
|
|
/// information on an error.
|
|
void registerUtf8ContentsForDiagnostics(Uri uri, Uint8List source);
|
|
}
|
|
|
|
/// Output types used in `CompilerOutput.createOutputSink`.
|
|
enum OutputType {
|
|
/// The main JavaScript output.
|
|
js,
|
|
|
|
/// A deferred JavaScript output part.
|
|
jsPart,
|
|
|
|
/// A source map for a JavaScript output.
|
|
sourceMap,
|
|
|
|
/// Dump info output.
|
|
dumpInfo,
|
|
|
|
/// Deferred map output.
|
|
deferredMap,
|
|
|
|
/// Deferred load ids map output.
|
|
deferredLoadIds,
|
|
|
|
/// Unused libraries output.
|
|
dumpUnusedLibraries,
|
|
|
|
/// Resource identifiers output.
|
|
resourceIdentifiers,
|
|
|
|
/// Implementation specific output used for debugging the compiler.
|
|
debug,
|
|
}
|
|
|
|
/// Sink interface used for generating output from the compiler.
|
|
abstract class OutputSink implements Sink<String> {
|
|
/// Adds [text] to the sink.
|
|
@override
|
|
void add(String text);
|
|
|
|
/// Closes the sink.
|
|
@override
|
|
void close();
|
|
}
|
|
|
|
/// Sink interface used for generating binary data from the compiler.
|
|
abstract class BinaryOutputSink implements Sink<List<int>> {
|
|
/// Writes indices [start] to [end] of [buffer] to the sink.
|
|
@override
|
|
void add(List<int> buffer, [int start = 0, int? end]);
|
|
|
|
/// Closes the sink.
|
|
@override
|
|
void close();
|
|
}
|
|
|
|
/// Interface for producing output from the compiler. That is, JavaScript target
|
|
/// files, source map files, dump info files, etc.
|
|
abstract class CompilerOutput {
|
|
/// Returns an [OutputSink] that will serve as compiler output for the given
|
|
/// component.
|
|
///
|
|
/// Components are identified by [name], [extension], and [type]. By
|
|
/// convention, the empty string `""` will represent the main output of the
|
|
/// provided [type]. [name] and [extension] are otherwise suggestive.
|
|
// TODO(johnniwinther): Replace [name] and [extension] with something like
|
|
// [id] and [uri].
|
|
OutputSink createOutputSink(String name, String extension, OutputType type);
|
|
|
|
/// Returns an [BinaryOutputSink] that will serve as compiler output for the
|
|
/// given URI.
|
|
BinaryOutputSink createBinarySink(Uri uri);
|
|
}
|
|
|
|
/// Interface for receiving diagnostic message from the compiler. That is,
|
|
/// errors, warnings, hints, etc.
|
|
abstract class CompilerDiagnostics {
|
|
/// Invoked by the compiler to report diagnostics. If [uri] is `null`, so are
|
|
/// [begin] and [end]. No other arguments may be `null`. If [uri] is not
|
|
/// `null`, neither are [begin] and [end]. [uri] indicates the compilation
|
|
/// unit from where the diagnostic originates. [begin] and [end] are
|
|
/// zero-based character offsets from the beginning of the compilation unit.
|
|
/// [message] is the diagnostic message, and [kind] indicates what
|
|
/// kind of diagnostic it is.
|
|
///
|
|
/// Experimental: [code] gives access to an id for the messages. Currently it
|
|
/// is the [Message] used to create the diagnostic, if available, from which
|
|
/// the [MessageKind] is accessible.
|
|
void report(
|
|
Message? code,
|
|
Uri? uri,
|
|
int? begin,
|
|
int? end,
|
|
String text,
|
|
Diagnostic kind,
|
|
);
|
|
}
|
|
|
|
/// Information resulting from the compilation.
|
|
class CompilationResult {
|
|
/// `true` if the compilation succeeded, that is, compilation didn't fail due
|
|
/// to compile-time errors and/or internal errors.
|
|
final bool isSuccess;
|
|
|
|
/// The compiler object used for the compilation.
|
|
///
|
|
/// Note: The type of [compiler] is implementation dependent and may vary.
|
|
/// Use only for debugging and testing.
|
|
final Compiler? compiler;
|
|
|
|
/// Shared state between compilations.
|
|
///
|
|
/// This is used to speed up batch mode.
|
|
final fe.InitializedCompilerState? kernelInitializedCompilerState;
|
|
|
|
CompilationResult(
|
|
this.compiler, {
|
|
this.isSuccess = true,
|
|
this.kernelInitializedCompilerState,
|
|
});
|
|
}
|
|
|
|
// Unless explicitly allowed, passing [:null:] for any argument to the
|
|
// methods of library will result in an Error being thrown.
|
|
|
|
/// Returns a future that completes to a [CompilationResult] when the Dart
|
|
/// sources in [options] have been compiled.
|
|
///
|
|
/// The generated compiler output is obtained by providing a [compilerOutput].
|
|
///
|
|
/// If the compilation fails, the future's `CompilationResult.isSuccess` is
|
|
/// `false` and [CompilerDiagnostics.report] on [compilerDiagnostics]
|
|
/// is invoked at least once with `kind == Diagnostic.ERROR` or
|
|
/// `kind == Diagnostic.CRASH`.
|
|
Future<CompilationResult> compile(
|
|
CompilerOptions compilerOptions,
|
|
CompilerInput compilerInput,
|
|
CompilerDiagnostics compilerDiagnostics,
|
|
CompilerOutput compilerOutput,
|
|
) {
|
|
var compiler = Compiler(
|
|
compilerInput,
|
|
compilerOutput,
|
|
compilerDiagnostics,
|
|
compilerOptions,
|
|
);
|
|
return compiler.run().then((bool success) {
|
|
return CompilationResult(
|
|
compiler,
|
|
isSuccess: success,
|
|
kernelInitializedCompilerState: compiler.initializedCompilerState,
|
|
);
|
|
});
|
|
}
|