Unverified Commit e2e3c5df authored by Alexander Aprelev's avatar Alexander Aprelev Committed by GitHub

Reland 9534082f with fix for incremen… (#14040)

* Reland 9534082f with fix for incremental compilation.

When in incremental mode, awaiting exitCode won't work because compiler is not expected to exit after compilation.
Instead listen for stdout stream closing and report error if outputFilename has not been received.

* Fix lints
parent bedf987f
......@@ -342,6 +342,10 @@ Future<String> _buildAotSnapshot(
aot : true,
strongMode: strongMode,
);
if (mainPath == null) {
printError('Compiler terminated unexpectedly.');
return null;
}
}
genSnapshotCmd.add(mainPath);
......
......@@ -110,8 +110,8 @@ Future<String> compile(
.transform(UTF8.decoder)
.transform(const LineSplitter())
.listen(stdoutHandler.handler);
await server.exitCode;
return stdoutHandler.outputFilename.future;
final int exitCode = await server.exitCode;
return exitCode == 0 ? stdoutHandler.outputFilename.future : null;
}
/// Wrapper around incremental frontend server compiler, that communicates with
......@@ -173,7 +173,16 @@ class ResidentCompiler {
_server.stdout
.transform(UTF8.decoder)
.transform(const LineSplitter())
.listen(stdoutHandler.handler);
.listen(
stdoutHandler.handler,
onDone: () {
// when outputFilename future is not completed, but stdout is closed
// process has died unexpectedly.
if (!stdoutHandler.outputFilename.isCompleted) {
stdoutHandler.outputFilename.complete(null);
}
});
_server.stderr
.transform(UTF8.decoder)
.transform(const LineSplitter())
......
......@@ -76,6 +76,9 @@ Future<Null> build({
mainPath: fs.file(mainPath).absolute.path,
strongMode: strongMode
);
if (kernelBinaryFilename == null) {
throwToolExit('Compiler terminated unexpectedly on $mainPath');
}
kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename));
}
......
......@@ -74,6 +74,28 @@ void main() {
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
testUsingContext('single dart abnormal compiler termination', () async {
when(mockFrontendServer.exitCode).thenReturn(255);
final BufferLogger logger = context[Logger];
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => new Stream<List<int>>.fromFuture(
new Future<List<int>>.value(UTF8.encode(
'result abc\nline1\nline2\nabc'
))
));
final String output = await compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart'
);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
expect(logger.errorText, equals('compiler message: line1\ncompiler message: line2\n'));
expect(output, equals(null));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
});
group('incremental compile', () {
......@@ -101,7 +123,10 @@ void main() {
when(mockProcessManager.start(any)).thenAnswer(
(Invocation invocation) => new Future<Process>.value(mockFrontendServer)
);
when(mockFrontendServer.exitCode).thenReturn(0);
});
tearDown(() {
verifyNever(mockFrontendServer.exitCode);
});
testUsingContext('single dart compile', () async {
......@@ -125,6 +150,19 @@ void main() {
ProcessManager: () => mockProcessManager,
});
testUsingContext('single dart compile abnormally terminates', () async {
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty()
);
final String output = await generator.recompile(
'/path/to/main.dart', null /* invalidatedFiles */
);
expect(output, equals(null));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
testUsingContext('compile and recompile', () async {
final BufferLogger logger = context[Logger];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment