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( ...@@ -342,6 +342,10 @@ Future<String> _buildAotSnapshot(
aot : true, aot : true,
strongMode: strongMode, strongMode: strongMode,
); );
if (mainPath == null) {
printError('Compiler terminated unexpectedly.');
return null;
}
} }
genSnapshotCmd.add(mainPath); genSnapshotCmd.add(mainPath);
......
...@@ -110,8 +110,8 @@ Future<String> compile( ...@@ -110,8 +110,8 @@ Future<String> compile(
.transform(UTF8.decoder) .transform(UTF8.decoder)
.transform(const LineSplitter()) .transform(const LineSplitter())
.listen(stdoutHandler.handler); .listen(stdoutHandler.handler);
await server.exitCode; final int exitCode = await server.exitCode;
return stdoutHandler.outputFilename.future; return exitCode == 0 ? stdoutHandler.outputFilename.future : null;
} }
/// Wrapper around incremental frontend server compiler, that communicates with /// Wrapper around incremental frontend server compiler, that communicates with
...@@ -173,7 +173,16 @@ class ResidentCompiler { ...@@ -173,7 +173,16 @@ class ResidentCompiler {
_server.stdout _server.stdout
.transform(UTF8.decoder) .transform(UTF8.decoder)
.transform(const LineSplitter()) .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 _server.stderr
.transform(UTF8.decoder) .transform(UTF8.decoder)
.transform(const LineSplitter()) .transform(const LineSplitter())
......
...@@ -76,6 +76,9 @@ Future<Null> build({ ...@@ -76,6 +76,9 @@ Future<Null> build({
mainPath: fs.file(mainPath).absolute.path, mainPath: fs.file(mainPath).absolute.path,
strongMode: strongMode strongMode: strongMode
); );
if (kernelBinaryFilename == null) {
throwToolExit('Compiler terminated unexpectedly on $mainPath');
}
kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename)); kernelContent = new DevFSFileContent(fs.file(kernelBinaryFilename));
} }
......
...@@ -74,6 +74,28 @@ void main() { ...@@ -74,6 +74,28 @@ void main() {
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager, 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', () { group('incremental compile', () {
...@@ -101,7 +123,10 @@ void main() { ...@@ -101,7 +123,10 @@ void main() {
when(mockProcessManager.start(any)).thenAnswer( when(mockProcessManager.start(any)).thenAnswer(
(Invocation invocation) => new Future<Process>.value(mockFrontendServer) (Invocation invocation) => new Future<Process>.value(mockFrontendServer)
); );
when(mockFrontendServer.exitCode).thenReturn(0); });
tearDown(() {
verifyNever(mockFrontendServer.exitCode);
}); });
testUsingContext('single dart compile', () async { testUsingContext('single dart compile', () async {
...@@ -125,6 +150,19 @@ void main() { ...@@ -125,6 +150,19 @@ void main() {
ProcessManager: () => mockProcessManager, 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 { testUsingContext('compile and recompile', () async {
final BufferLogger logger = context[Logger]; 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