[frontend-server] Report error count on compile and recompile.
This allows frontend-server users(flutter) to do quick check whether frontend compilation reported errors as it produced output kernel file.
Change-Id: I6e4da8fac33104968eb7720200a1b7153ec8f3de
Reviewed-on: https://dart-review.googlesource.com/51000
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 33b37b5..fe7e529 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -286,7 +286,8 @@
final BinaryPrinter printer = printerFactory.newBinaryPrinter(sink);
printer.writeComponentFile(component);
await sink.close();
- _outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
+ _outputStream
+ .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
final String depfile = options['depfile'];
if (depfile != null) {
await _writeDepfile(component, _kernelBinaryFilename, depfile);
@@ -348,6 +349,7 @@
if (filename != null) {
setMainSourceFilename(filename);
}
+ errors.clear();
final Component deltaProgram =
await _generator.compile(entryPoint: _mainSource);
@@ -359,7 +361,8 @@
final BinaryPrinter printer = printerFactory.newBinaryPrinter(sink);
printer.writeComponentFile(deltaProgram);
await sink.close();
- _outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
+ _outputStream
+ .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
_kernelBinaryFilename = _kernelBinaryFilenameIncremental;
return null;
}
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 2377066..bac3e69 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -512,11 +512,17 @@
streamController.add('compile ${file.path}\n'.codeUnits);
int count = 0;
Completer<bool> allDone = new Completer<bool>();
- receivedResults.stream.listen((String outputFilename) {
+ receivedResults.stream.listen((String outputFilenameAndErrorCount) {
+ int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
+ expect(delim > 0, equals(true));
+ String outputFilename = outputFilenameAndErrorCount.substring(0, delim);
+ int errorsCount =
+ int.parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
if (count == 0) {
// First request is to 'compile', which results in full kernel file.
expect(dillFile.existsSync(), equals(true));
expect(outputFilename, dillFile.path);
+ expect(errorsCount, 0);
count += 1;
streamController.add('accept\n'.codeUnits);
var file2 = new File('${tempDir.path}/bar.dart')..createSync();
@@ -531,6 +537,7 @@
// kernel file.
var dillIncFile = new File('${dillFile.path}.incremental.dill');
expect(outputFilename, dillIncFile.path);
+ expect(errorsCount, 0);
expect(dillIncFile.existsSync(), equals(true));
allDone.complete(true);
}
@@ -538,6 +545,93 @@
expect(await allDone.future, true);
});
+ test('compile and recompile report non-zero error count', () async {
+ var file = new File('${tempDir.path}/foo.dart')..createSync();
+ file.writeAsStringSync("main() { foo(); bar(); }\n");
+ var dillFile = new File('${tempDir.path}/app.dill');
+ expect(dillFile.existsSync(), equals(false));
+ final List<String> args = <String>[
+ '--sdk-root=${sdkRoot.toFilePath()}',
+ '--strong',
+ '--incremental',
+ '--platform=${platformKernel.path}',
+ '--output-dill=${dillFile.path}'
+ ];
+
+ final StreamController<List<int>> streamController =
+ new StreamController<List<int>>();
+ final StreamController<List<int>> stdoutStreamController =
+ new StreamController<List<int>>();
+ final IOSink ioSink = new IOSink(stdoutStreamController.sink);
+ StreamController<String> receivedResults = new StreamController<String>();
+
+ String boundaryKey;
+ stdoutStreamController.stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen((String s) {
+ const String RESULT_OUTPUT_SPACE = 'result ';
+ if (boundaryKey == null) {
+ if (s.startsWith(RESULT_OUTPUT_SPACE)) {
+ boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
+ }
+ } else {
+ if (s.startsWith(boundaryKey)) {
+ receivedResults.add(s.substring(boundaryKey.length + 1));
+ boundaryKey = null;
+ }
+ }
+ });
+ int exitcode =
+ await starter(args, input: streamController.stream, output: ioSink);
+ expect(exitcode, equals(0));
+ streamController.add('compile ${file.path}\n'.codeUnits);
+ int count = 0;
+ Completer<bool> allDone = new Completer<bool>();
+ receivedResults.stream.listen((String outputFilenameAndErrorCount) {
+ int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
+ expect(delim > 0, equals(true));
+ String outputFilename = outputFilenameAndErrorCount.substring(0, delim);
+ int errorsCount =
+ int.parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
+ switch (count) {
+ case 0:
+ expect(dillFile.existsSync(), equals(true));
+ expect(outputFilename, dillFile.path);
+ expect(errorsCount, 2);
+ count += 1;
+ streamController.add('accept\n'.codeUnits);
+ var file2 = new File('${tempDir.path}/bar.dart')..createSync();
+ file2.writeAsStringSync("main() { baz(); }\n");
+ streamController.add('recompile ${file2.path} abc\n'
+ '${file2.path}\n'
+ 'abc\n'
+ .codeUnits);
+ break;
+ case 1:
+ var dillIncFile = new File('${dillFile.path}.incremental.dill');
+ expect(outputFilename, dillIncFile.path);
+ expect(errorsCount, 1);
+ count += 1;
+ streamController.add('accept\n'.codeUnits);
+ var file2 = new File('${tempDir.path}/bar.dart')..createSync();
+ file2.writeAsStringSync("main() { }\n");
+ streamController.add('recompile ${file2.path} abc\n'
+ '${file2.path}\n'
+ 'abc\n'
+ .codeUnits);
+ break;
+ case 2:
+ var dillIncFile = new File('${dillFile.path}.incremental.dill');
+ expect(outputFilename, dillIncFile.path);
+ expect(errorsCount, 0);
+ expect(dillIncFile.existsSync(), equals(true));
+ allDone.complete(true);
+ }
+ });
+ expect(await allDone.future, true);
+ });
+
test('compile and recompile with MultiRootFileSystem', () async {
var file = new File('${tempDir.path}/foo.dart')..createSync();
file.writeAsStringSync("main() {}\n");