blob: 7131e00671dfdc0102e744a012baf01900c6318f [file] [log] [blame]
// 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.
// @dart = 2.7
library dart2js.test.memory_compiler;
import 'dart:async';
import 'package:compiler/compiler.dart'
show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/common.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/messages.dart' show Message;
import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
import 'package:compiler/src/options.dart' show CompilerOptions;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
import 'memory_source_file_helper.dart';
export 'output_collector.dart';
export 'package:compiler/compiler.dart' show CompilationResult;
export 'diagnostic_helper.dart';
String sdkPath = 'sdk/lib';
String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';
Uri sdkLibrariesSpecificationUri =
Uri sdkPlatformBinariesUri = computePlatformBinariesLocation()
String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();
class MultiDiagnostics implements CompilerDiagnostics {
final List<CompilerDiagnostics> diagnosticsList;
const MultiDiagnostics([this.diagnosticsList = const []]);
void report(covariant Message message, Uri uri, int begin, int end,
String text, Diagnostic kind) {
for (CompilerDiagnostics diagnostics in diagnosticsList) {, uri, begin, end, text, kind);
CompilerDiagnostics createCompilerDiagnostics(
CompilerDiagnostics diagnostics, SourceFileProvider provider,
{bool showDiagnostics: true, bool verbose: false}) {
CompilerDiagnostics handler = diagnostics;
if (showDiagnostics) {
if (diagnostics == null) {
handler = new FormattingDiagnosticHandler(provider)
..verbose = verbose
..autoReadFileUri = true;
} else {
var formattingHandler = new FormattingDiagnosticHandler(provider)
..verbose = verbose
..autoReadFileUri = true;
handler = new MultiDiagnostics([diagnostics, formattingHandler]);
} else if (diagnostics == null) {
handler = new MultiDiagnostics();
return handler;
// Cached kernel state.
fe.InitializedCompilerState kernelInitializedCompilerState;
/// memorySourceFiles can contain a map of string filename to string file
/// contents or string file name to binary file contents (hence the `dynamic`
/// type for the second parameter).
Future<CompilationResult> runCompiler(
{Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
Uri entryPoint,
CompilerDiagnostics diagnosticHandler,
CompilerOutput outputProvider,
List<String> options: const <String>[],
bool showDiagnostics: true,
Uri librariesSpecificationUri,
Uri packageConfig,
void beforeRun(Compiler compiler),
bool unsafeToTouchSourceFiles: false}) async {
if (entryPoint == null) {
entryPoint = Uri.parse('memory:main.dart');
Compiler compiler = compilerFor(
entryPoint: entryPoint,
memorySourceFiles: memorySourceFiles,
diagnosticHandler: diagnosticHandler,
outputProvider: outputProvider,
options: options,
showDiagnostics: showDiagnostics,
librariesSpecificationUri: librariesSpecificationUri,
packageConfig: packageConfig,
unsafeToTouchSourceFiles: unsafeToTouchSourceFiles);
if (beforeRun != null) {
bool isSuccess = await;
fe.InitializedCompilerState compilerState = kernelInitializedCompilerState =
return new CompilationResult(compiler,
isSuccess: isSuccess, kernelInitializedCompilerState: compilerState);
Compiler compilerFor(
{Uri entryPoint,
Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
CompilerDiagnostics diagnosticHandler,
CompilerOutput outputProvider,
List<String> options: const <String>[],
bool showDiagnostics: true,
Uri librariesSpecificationUri,
Uri packageConfig,
bool unsafeToTouchSourceFiles: false}) {
retainDataForTesting = true;
librariesSpecificationUri ??= sdkLibrariesSpecificationUri;
if (packageConfig == null) {
if (Platform.packageConfig != null) {
packageConfig = Uri.base.resolve(Platform.packageConfig);
} else {
// The tests are run with the base directory as the SDK root
// so just use the .packages file there.
packageConfig = Uri.base.resolve('.packages');
// Create a local in case we end up cloning memorySourceFiles.
Map<String, dynamic> sources = memorySourceFiles;
// If soundNullSafety is not requested, then we prepend the opt out string to
// the memory files.
if (!options.contains(Flags.soundNullSafety) && !unsafeToTouchSourceFiles) {
// Map may be immutable so copy.
sources = {};
memorySourceFiles.forEach((k, v) => sources[k] = v);
RegExp optOutStr = RegExp(r"\/\/\s*@dart\s*=\s*2\.\d+");
for (var key in sources.keys) {
if (sources[key] is String && key.endsWith('.dart')) {
if (!optOutStr.hasMatch(sources[key])) {
sources[key] = '// @dart=2.7\n' + sources[key];
MemorySourceFileProvider provider;
provider = new MemorySourceFileProvider(sources);
diagnosticHandler = createCompilerDiagnostics(diagnosticHandler, provider,
showDiagnostics: showDiagnostics,
verbose: options.contains('-v') || options.contains('--verbose'));
if (outputProvider == null) {
outputProvider = const NullCompilerOutput();
CompilerOptions compilerOptions = CompilerOptions.parse(options,
librariesSpecificationUri: librariesSpecificationUri)
..entryUri = entryPoint
..environment = {}
..packageConfig = packageConfig;
compilerOptions.kernelInitializedCompilerState =
var compiler = new Compiler(
provider, outputProvider, diagnosticHandler, compilerOptions);
return compiler;
main() {
runCompiler(memorySourceFiles: {'main.dart': 'main() {}'});