blob: 296694afee1a1ca4777b79263bef9eebf46bc24d [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.
library;
import 'dart:async';
import 'package:compiler/compiler_api.dart'
as api
show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart' show Compiler;
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;
// ignore: implementation_imports
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'memory_source_file_helper.dart';
export 'package:compiler/compiler_api.dart' show CompilationResult;
export 'diagnostic_helper.dart';
export 'output_collector.dart';
String sdkPath = 'sdk/lib';
String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';
Uri sdkLibrariesSpecificationUri = Uri.base.resolve(
sdkLibrariesSpecificationPath,
);
Uri sdkPlatformBinariesUri = fe
.computePlatformBinariesLocation()
.resolve("dart2js_platform.dill")
.resolve('.');
String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();
Uri buildPlatformBinariesUri = fe
.computePlatformBinariesLocation(forceBuildDir: true)
.resolve("dart2js_platform.dill")
.resolve('.');
String buildPlatformBinariesPath = buildPlatformBinariesUri.toString();
class MultiDiagnostics implements api.CompilerDiagnostics {
final List<api.CompilerDiagnostics> diagnosticsList;
const MultiDiagnostics([this.diagnosticsList = const []]);
@override
void report(
covariant Message? message,
Uri? uri,
int? begin,
int? end,
String text,
api.Diagnostic kind,
) {
for (api.CompilerDiagnostics diagnostics in diagnosticsList) {
diagnostics.report(message, uri, begin, end, text, kind);
}
}
}
api.CompilerDiagnostics createCompilerDiagnostics(
api.CompilerDiagnostics? diagnostics,
SourceFileProvider provider, {
bool showDiagnostics = true,
bool verbose = false,
}) {
if (showDiagnostics) {
if (diagnostics == null) {
diagnostics = FormattingDiagnosticHandler()
..verbose = verbose
..registerFileProvider(provider);
} else {
var formattingHandler = FormattingDiagnosticHandler()
..verbose = verbose
..registerFileProvider(provider);
diagnostics = MultiDiagnostics([diagnostics, formattingHandler]);
}
} else {
diagnostics ??= MultiDiagnostics();
}
return diagnostics;
}
// 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<api.CompilationResult> runCompiler({
Map<String, dynamic> memorySourceFiles = const <String, dynamic>{},
Uri? entryPoint,
api.CompilerDiagnostics? diagnosticHandler,
api.CompilerOutput? outputProvider,
List<String> options = const <String>[],
Map<String, String>? environment,
bool showDiagnostics = true,
Uri? librariesSpecificationUri,
Uri? platformBinaries,
Uri? packageConfig,
bool skipPackageConfig = false,
void Function(Compiler compiler)? beforeRun,
}) async {
entryPoint ??= Uri.parse('memory:main.dart');
Compiler compiler = compilerFor(
entryPoint: entryPoint,
memorySourceFiles: memorySourceFiles,
diagnosticHandler: diagnosticHandler,
outputProvider: outputProvider,
options: options,
environment: environment,
showDiagnostics: showDiagnostics,
librariesSpecificationUri: librariesSpecificationUri,
platformBinaries: platformBinaries,
packageConfig: packageConfig,
skipPackageConfig: skipPackageConfig,
);
if (beforeRun != null) {
beforeRun(compiler);
}
bool isSuccess = await compiler.run();
fe.InitializedCompilerState? compilerState = kernelInitializedCompilerState =
compiler.initializedCompilerState;
return api.CompilationResult(
compiler,
isSuccess: isSuccess,
kernelInitializedCompilerState: compilerState,
);
}
Compiler compilerFor({
Uri? entryPoint,
Map<String, dynamic> memorySourceFiles = const <String, dynamic>{},
api.CompilerDiagnostics? diagnosticHandler,
api.CompilerOutput? outputProvider,
List<String> options = const <String>[],
Map<String, String>? environment,
bool showDiagnostics = true,
Uri? librariesSpecificationUri,
Uri? platformBinaries,
Uri? packageConfig,
bool skipPackageConfig = false,
}) {
retainDataForTesting = true;
librariesSpecificationUri ??= sdkLibrariesSpecificationUri;
if (packageConfig == null && !skipPackageConfig) {
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 package config there.
packageConfig = Uri.base.resolve('.dart_tool/package_config.json');
}
}
// Create a local in case we end up cloning memorySourceFiles.
Map<String, dynamic> sources = memorySourceFiles;
MemorySourceFileProvider provider;
provider = MemorySourceFileProvider(sources);
diagnosticHandler = createCompilerDiagnostics(
diagnosticHandler,
provider,
showDiagnostics: showDiagnostics,
verbose: options.contains('-v') || options.contains('--verbose'),
);
outputProvider ??= const NullCompilerOutput();
options = [...options, '${Flags.entryUri}=$entryPoint'];
CompilerOptions compilerOptions =
CompilerOptions.parse(
options,
librariesSpecificationUri: librariesSpecificationUri,
platformBinaries: platformBinaries,
)
..environment = environment ?? {}
..packageConfig = packageConfig;
compilerOptions.setDefaultOutputUriForTesting();
compilerOptions.kernelInitializedCompilerState =
kernelInitializedCompilerState;
var compiler = Compiler(
provider,
outputProvider,
diagnosticHandler,
compilerOptions,
);
return compiler;
}
void main() {
runCompiler(memorySourceFiles: {'main.dart': 'main() {}'});
}