blob: 77e7cabe8df13fc27b5d4e214c5333b09c3216bb [file] [log] [blame]
// Copyright (c) 2017, 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' show Future;
import 'dart:io' show Directory, File, Platform;
import 'package:async_helper/async_helper.dart' show asyncEnd, asyncStart;
import 'package:testing/testing.dart' show StdioProcess;
import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
import 'package:kernel/ast.dart' show Component;
import 'package:kernel/text/ast_to_text.dart' show componentToString;
Future main() async {
asyncStart();
Uri sourceCompiler =
Uri.base.resolve("pkg/front_end/tool/_fasta/compile.dart");
Uri outline = Uri.base.resolve("pkg/front_end/tool/_fasta/outline.dart");
Directory tmp = await Directory.systemTemp.createTemp("fasta_bootstrap");
Uri compiledOnceOutput = tmp.uri.resolve("fasta1.dill");
Uri compiledTwiceOutput = tmp.uri.resolve("fasta2.dill");
Uri outlineOutput = tmp.uri.resolve("outline.dill");
try {
await runCompiler(sourceCompiler, sourceCompiler, compiledOnceOutput);
await runCompiler(compiledOnceOutput, sourceCompiler, compiledTwiceOutput);
await compare(compiledOnceOutput, compiledTwiceOutput);
await runCompiler(compiledTwiceOutput, outline, outlineOutput);
try {
// Test that compare actually works by comparing the compiled component
// to the outline component (which are different, but similar).
await compare(compiledOnceOutput, outlineOutput, silent: true);
throw "Expected an error.";
} on ComparisonFailed {
// Expected.
}
} finally {
await tmp.delete(recursive: true);
}
asyncEnd();
}
Future runCompiler(Uri compiler, Uri input, Uri output) async {
Uri dartVm = Uri.base.resolveUri(new Uri.file(Platform.resolvedExecutable));
StdioProcess result = await StdioProcess.run(dartVm.toFilePath(), <String>[
"-c",
compiler.toFilePath(),
"--compile-sdk=sdk/",
"--output=${output.toFilePath()}",
"--verify",
input.toFilePath(),
]);
if (result.output.isNotEmpty) {
print(result.output);
}
if (result.exitCode != 0) {
throw "Compilation failed.";
}
}
Future compare(Uri a, Uri b, {bool silent: false}) async {
List<int> bytesA = await new File.fromUri(a).readAsBytes();
List<int> bytesB = await new File.fromUri(b).readAsBytes();
if (bytesA.length == bytesB.length) {
bool same = true;
for (int i = 0; i < bytesA.length; i++) {
if (bytesA[i] != bytesB[i]) {
same = false;
break;
}
}
if (same) return;
}
if (!silent) {
print("$a is different from $b");
}
Component programA = new Component();
Component programB = new Component();
new BinaryBuilder(bytesA, filename: a.toFilePath()).readComponent(programA);
new BinaryBuilder(bytesB, filename: b.toFilePath()).readComponent(programB);
RegExp splitLines = new RegExp('^', multiLine: true);
List<String> linesA = componentToString(programA).split(splitLines);
List<String> linesB = componentToString(programB).split(splitLines);
for (int i = 0; i < linesA.length && i < linesB.length; i++) {
String lineA = linesA[i].trimRight();
String lineB = linesB[i].trimRight();
if (lineA != lineB) {
String diffHunk = "${i}c$i\n>$lineA\n---\n<$lineB";
if (!silent) {
print(diffHunk);
}
}
}
throw new ComparisonFailed(a, b);
}
class ComparisonFailed {
final Uri a;
final Uri b;
ComparisonFailed(this.a, this.b);
toString() => "Error: $a is different from $b";
}