blob: aabc1091ba3411b7656c10bfc06454e9b3687d7d [file] [log] [blame]
// Copyright (c) 2022, 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.
import 'dart:async';
import 'dart:convert' show utf8;
import 'dart:isolate' show RawReceivePort, ReceivePort, SendPort;
import "../bin/kernel_service.dart" as kernel_service;
import 'package:front_end/src/api_unstable/vm.dart' show Verbosity;
final bool verbose = new bool.fromEnvironment('TEST_VERBOSE');
Future<void> main() async {
kernel_service.Status result;
// Expect to work with both absolute and relative package specification
// if the file specified exists and is valid.
result = await singleShotCompile(
relativeEntry, fooSourceFiles, absolutePackageConfig);
expect(result, kernel_service.Status.ok);
result = await singleShotCompile(
relativeEntry, fooSourceFiles, relativePackageConfig);
expect(result, kernel_service.Status.ok);
// Expect an error with both absolute and relative package specification
// if the file specified does not exist.
result = await singleShotCompile(
relativeEntry, fooSourceFiles, nonExistentAbsolutePackageConfig);
expect(result, kernel_service.Status.error);
result = await singleShotCompile(
relativeEntry, fooSourceFiles, nonExistentRelativePackageConfig);
expect(result, kernel_service.Status.error);
// Expect an error with both absolute and relative package specification
// if the file specified does exist but is invalid.
result = await singleShotCompile(
relativeEntry, fooSourceFiles, invalidAbsolutePackageConfig);
expect(result, kernel_service.Status.error);
result = await singleShotCompile(
relativeEntry, fooSourceFiles, invalidRelativePackageConfig);
expect(result, kernel_service.Status.error);
}
void expect(kernel_service.Status actual, kernel_service.Status expected) {
if (actual != expected) {
throw "Got $actual but expected $expected";
}
}
String relativeEntry = "entry.dart";
String relativePackageConfig = "packageConfig.json";
String absolutePackageConfig = Uri.base.resolve(relativePackageConfig).path;
String nonExistentRelativePackageConfig = "nonexisting.json";
String nonExistentAbsolutePackageConfig =
Uri.base.resolve(nonExistentRelativePackageConfig).path;
String invalidRelativePackageConfig = "invalidPackageConfig.json";
String invalidAbsolutePackageConfig =
Uri.base.resolve(invalidRelativePackageConfig).path;
List fooSourceFiles = [
Uri.base.resolve(relativeEntry).path,
utf8.encode("""
import "package:foo/bar.dart";
main() {
bar();
}
"""),
Uri.base.resolve("foo/lib/bar.dart").path,
utf8.encode("""
bar() {
print("Hello from bar!");
}
"""),
absolutePackageConfig,
utf8.encode("""
{
"configVersion": 2,
"packages": [
{
"name": "foo",
"rootUri": "foo/",
"packageUri": "lib/"
}
]
}
"""),
invalidAbsolutePackageConfig,
utf8.encode(/* missing comma after rootUri line*/ """
{
"configVersion": 2,
"packages": [
{
"name": "foo",
"rootUri": "foo/"
"packageUri": "lib/"
}
]
}
"""),
];
Future<kernel_service.Status> singleShotCompile(
String entryFile, List sourceFiles, String? packageConfig) async {
final RawReceivePort kernelServicePort = kernel_service.main();
final SendPort sendPort = kernelServicePort.sendPort;
final ReceivePort myReceivePort = new ReceivePort();
sendPort.send([
/* [0] = int = tag = */ kernel_service.kCompileTag,
/* [1] = SendPort = sendport = */ myReceivePort.sendPort,
/* [2] = String? = inputFileUri = */ entryFile,
/* [3] = various = platformKernel = */ null,
/* [4] = bool = incremental = */ false,
/* [5] = bool = snapshot = */ false,
/* [6] = int = nullSafety = */ kernel_service.kNullSafetyOptionStrong,
/* [7] = int = isolateGroupId = */ 42,
/* [8] = List = sourceFiles = */ sourceFiles,
/* [9] = bool = enableAsserts = */ true,
/* [10] = List<String>? = experimentalFlags = */ [],
/* [11] = String? = packageConfig = */ packageConfig,
/* [12] = String? = multirootFilepaths = */ null,
/* [13] = String? = multirootScheme = */ null,
/* [14] = String? = workingDirectory = */ null,
/* [15] = String = verbosityLevel = */ Verbosity.all.name,
/* [16] = bool = enableMirrors = */ false,
]);
// Wait for kernel-service response.
final StreamIterator streamIterator = new StreamIterator(myReceivePort);
await streamIterator.moveNext();
// Close ports so we can return below.
kernelServicePort.close();
myReceivePort.close();
// Examine kernel-service response.
final List m = streamIterator.current as List;
final int status = m.first;
if (status == kernel_service.Status.ok.index) {
expectLength(m, 2);
final List<int> bytes = m[1];
if (verbose) {
print("OK --- ${bytes.length} bytes dill");
}
return kernel_service.Status.ok;
} else if (status == kernel_service.Status.error.index) {
expectLength(m, 3);
final String errors = m[1];
final List<int> bytes = m[2];
if (verbose) {
print("Compiled with errors --- $errors and ${bytes.length} bytes dill");
}
return kernel_service.Status.error;
} else if (status == kernel_service.Status.crash.index) {
expectLength(m, 2);
final String errors = m[1];
if (verbose) {
print("Compiler crashed --- $errors");
}
return kernel_service.Status.crash;
} else {
throw "Unknow status: $m";
}
}
void expectLength(List list, int expectedLength) {
if (list.length != expectedLength) {
throw "Expected $expectedLength entries, got ${list.length}: $list";
}
}