Commit e0cd42e4 authored by Alexander Aprelev's avatar Alexander Aprelev Committed by Siva

Roll engine to 76cb311d9c33720dcd19274228b39ecdbad8d9af (with rolled dart) (#16518)

* Handle error count reported by frontend.

Extend compilation result from single string to a structure(string filename and integer error count).

* Use ?.

* Include engine roll with dart sdk roll.

* parse(onError) -> tryParse

* Make '?? throw' more readable and avoid issue with analyzer

* Fix test so it mocks compiler output including errors count
parent c73b8a7c
8a6e64a8ef09f1f1af207725b40022d8d7a9dcd7
76cb311d9c33720dcd19274228b39ecdbad8d9af
......@@ -238,8 +238,14 @@ dependencies:
throw 'failed to parse error message: $error';
}
final String column = error.substring(colon2 + kColon.length, bullet2);
final int lineNumber = int.parse(line, radix: 10, onError: (String source) => throw 'failed to parse error message: $error');
final int columnNumber = int.parse(column, radix: 10, onError: (String source) => throw 'failed to parse error message: $error');
final int lineNumber = int.tryParse(line, radix: 10);
if (lineNumber == null) {
throw 'failed to parse error message: $error';
}
final int columnNumber = int.tryParse(column, radix: 10);
if (columnNumber == null) {
throw 'failed to parse error message: $error';
}
if (lineNumber < 1 || lineNumber > lines.length) {
keepMain = true;
throw 'failed to parse error message (read line number as $lineNumber; total number of lines is ${lines.length}): $error';
......
......@@ -210,7 +210,7 @@ class AndroidDevice extends Device {
// Sample output: '22'
final String sdkVersion = await _getProperty('ro.build.version.sdk');
final int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null);
final int sdkVersionParsed = int.tryParse(sdkVersion);
if (sdkVersionParsed == null) {
printError('Unexpected response from getprop: "$sdkVersion"');
return false;
......@@ -817,7 +817,7 @@ class _AndroidDevicePortForwarder extends DevicePortForwarder {
final AndroidDevice device;
static int _extractPort(String portString) {
return int.parse(portString.trim(), onError: (_) => null);
return int.tryParse(portString.trim());
}
@override
......
......@@ -105,7 +105,7 @@ Future<void> build({
String kernelBinaryFilename;
if (needBuild) {
ensureDirectoryExists(applicationKernelFilePath);
kernelBinaryFilename = await compile(
final CompilerOutput compilerOutput = await compile(
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
incrementalCompilerByteStorePath: fs.path.absolute(getIncrementalCompilerByteStoreDirectory()),
mainPath: fs.file(mainPath).absolute.path,
......@@ -116,6 +116,7 @@ Future<void> build({
fileSystemScheme: fileSystemScheme,
packagesPath: packagesPath,
);
kernelBinaryFilename = compilerOutput?.outputFilename;
if (kernelBinaryFilename == null) {
throwToolExit('Compiler failed on $mainPath');
}
......
......@@ -387,7 +387,7 @@ Future<String> _buildAotSnapshot(
}
if (previewDart2) {
mainPath = await compile(
final CompilerOutput compilerOutput = await compile(
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
mainPath: mainPath,
outputFilePath: kApplicationKernelPath,
......@@ -398,6 +398,7 @@ Future<String> _buildAotSnapshot(
entryPointsJsonFiles: entryPointsJsonFiles,
trackWidgetCreation: false,
);
mainPath = compilerOutput?.outputFilename;
if (mainPath == null) {
printError('Compiler terminated unexpectedly.');
return null;
......
......@@ -384,7 +384,7 @@ class FuchsiaReloadCommand extends FlutterCommand {
final int lastSpace = trimmed.lastIndexOf(' ');
final String lastWord = trimmed.substring(lastSpace + 1);
if ((lastWord != '.') && (lastWord != '..')) {
final int value = int.parse(lastWord, onError: (_) => null);
final int value = int.tryParse(lastWord);
if (value != null)
ports.add(value);
}
......
......@@ -784,7 +784,7 @@ class PubspecChecksum extends PubspecLine {
if (twoLines.length != 2) {
return new PubspecChecksum(-1, line);
}
final int value = int.parse(twoLines.last.trim(), radix: 16, onError: (String _) => -1);
final int value = int.tryParse(twoLines.last.trim(), radix: 16) ?? -1;
return new PubspecChecksum(value, line);
}
}
......
......@@ -15,6 +15,13 @@ import 'globals.dart';
typedef void CompilerMessageConsumer(String message);
class CompilerOutput {
String outputFilename;
int errorCount;
CompilerOutput(this.outputFilename, this.errorCount);
}
class _StdoutHandler {
_StdoutHandler({this.consumer: printError}) {
reset();
......@@ -22,17 +29,24 @@ class _StdoutHandler {
final CompilerMessageConsumer consumer;
String boundaryKey;
Completer<String> outputFilename;
Completer<CompilerOutput> compilerOutput;
void handler(String string) {
const String kResultPrefix = 'result ';
if (boundaryKey == null) {
if (string.startsWith(kResultPrefix))
boundaryKey = string.substring(kResultPrefix.length);
} else if (string.startsWith(boundaryKey))
outputFilename.complete(string.length > boundaryKey.length
? string.substring(boundaryKey.length + 1)
: null);
} else if (string.startsWith(boundaryKey)) {
if (string.length <= boundaryKey.length) {
compilerOutput.complete(null);
return;
}
final int spaceDelimiter = string.lastIndexOf(' ');
compilerOutput.complete(
new CompilerOutput(
string.substring(boundaryKey.length + 1, spaceDelimiter),
int.parse(string.substring(spaceDelimiter + 1).trim())));
}
else
consumer('compiler message: $string');
}
......@@ -41,11 +55,11 @@ class _StdoutHandler {
// with its own boundary key and new completer.
void reset() {
boundaryKey = null;
outputFilename = new Completer<String>();
compilerOutput = new Completer<CompilerOutput>();
}
}
Future<String> compile(
Future<CompilerOutput> compile(
{String sdkRoot,
String mainPath,
String outputFilePath,
......@@ -132,7 +146,7 @@ Future<String> compile(
.transform(const LineSplitter())
.listen(stdoutHandler.handler);
final int exitCode = await server.exitCode;
return exitCode == 0 ? stdoutHandler.outputFilename.future : null;
return exitCode == 0 ? stdoutHandler.compilerOutput.future : null;
}
/// Wrapper around incremental frontend server compiler, that communicates with
......@@ -170,7 +184,7 @@ class ResidentCompiler {
/// point that is used for recompilation.
/// Binary file name is returned if compilation was successful, otherwise
/// null is returned.
Future<String> recompile(String mainPath, List<String> invalidatedFiles,
Future<CompilerOutput> recompile(String mainPath, List<String> invalidatedFiles,
{String outputPath, String packagesFilePath}) async {
stdoutHandler.reset();
......@@ -186,10 +200,11 @@ class ResidentCompiler {
}
_server.stdin.writeln(inputKey);
return stdoutHandler.outputFilename.future;
return stdoutHandler.compilerOutput.future;
}
Future<String> _compile(String scriptFilename, String outputPath, String packagesFilePath) async {
Future<CompilerOutput> _compile(String scriptFilename, String outputPath,
String packagesFilePath) async {
final String frontendServer = artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
);
......@@ -231,8 +246,8 @@ class ResidentCompiler {
onDone: () {
// when outputFilename future is not completed, but stdout is closed
// process has died unexpectedly.
if (!stdoutHandler.outputFilename.isCompleted) {
stdoutHandler.outputFilename.complete(null);
if (!stdoutHandler.compilerOutput.isCompleted) {
stdoutHandler.compilerOutput.complete(null);
}
});
......@@ -243,7 +258,7 @@ class ResidentCompiler {
_server.stdin.writeln('compile $scriptFilename');
return stdoutHandler.outputFilename.future;
return stdoutHandler.compilerOutput.future;
}
......
......@@ -501,10 +501,11 @@ class DevFS {
if (fullRestart) {
generator.reset();
}
final String compiledBinary =
final CompilerOutput compilerOutput =
await generator.recompile(mainPath, invalidatedFiles,
outputPath: dillOutputPath ?? fs.path.join(getBuildDirectory(), 'app.dill'),
packagesFilePath : _packagesFilePath);
final String compiledBinary = compilerOutput?.outputFilename;
if (compiledBinary != null && compiledBinary.isNotEmpty) {
final String entryUri = projectRootPath != null ?
fs.path.relative(mainPath, from: projectRootPath):
......
......@@ -143,10 +143,13 @@ class _Compiler {
printTrace('Compiling ${request.path}');
compiler ??= createCompiler();
suppressOutput = false;
final String outputPath = await handleTimeout(compiler.recompile(request.path,
<String>[request.path],
outputPath: outputDill.path,
), request.path);
final CompilerOutput compilerOutput = await handleTimeout<CompilerOutput>(
compiler.recompile(
request.path,
<String>[request.path],
outputPath: outputDill.path),
request.path);
final String outputPath = compilerOutput?.outputFilename;
// Check if the compiler produced the output. If it failed then
// outputPath would be null. In this case pass null upwards to the
......@@ -179,7 +182,7 @@ class _Compiler {
Future<String> compile(String mainDart) {
final Completer<String> completer = new Completer<String>();
compilerController.add(new _CompilationRequest(mainDart, completer));
return handleTimeout(completer.future, mainDart);
return handleTimeout<String>(completer.future, mainDart);
}
Future<dynamic> shutdown() async {
......@@ -187,7 +190,7 @@ class _Compiler {
compiler = null;
}
static Future<String> handleTimeout(Future<String> value, String path) {
static Future<T> handleTimeout<T>(Future<T> value, String path) {
return value.timeout(const Duration(minutes: 5), onTimeout: () {
printError('Compilation of $path timed out after 5 minutes.');
return null;
......
......@@ -499,7 +499,7 @@ class GitTagVersion {
return const GitTagVersion.unknown();
}
final List<int> parsedParts = parts.take(4).map<int>(
(String value) => int.parse(value, onError: (String value) => null),
(String value) => int.tryParse(value),
).toList();
return new GitTagVersion(parsedParts[0], parsedParts[1], parsedParts[2], parsedParts[3], parts[4]);
}
......
......@@ -43,15 +43,15 @@ void main() {
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => new Stream<List<int>>.fromFuture(
new Future<List<int>>.value(utf8.encode(
'result abc\nline1\nline2\nabc /path/to/main.dart.dill'
'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0'
))
));
final String output = await compile(sdkRoot: '/path/to/sdkroot',
final CompilerOutput 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('/path/to/main.dart.dill'));
expect(output.outputFilename, equals('/path/to/main.dart.dill'));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
......@@ -66,7 +66,7 @@ void main() {
))
));
final String output = await compile(sdkRoot: '/path/to/sdkroot',
final CompilerOutput output = await compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart'
);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
......@@ -88,7 +88,7 @@ void main() {
))
));
final String output = await compile(sdkRoot: '/path/to/sdkroot',
final CompilerOutput output = await compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart'
);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
......@@ -137,17 +137,17 @@ void main() {
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => new Stream<List<int>>.fromFuture(
new Future<List<int>>.value(utf8.encode(
'result abc\nline1\nline2\nabc /path/to/main.dart.dill'
'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0'
))
));
final String output = await generator.recompile(
final CompilerOutput output = await generator.recompile(
'/path/to/main.dart', null /* invalidatedFiles */
);
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(logger.errorText, equals('compiler message: line1\ncompiler message: line2\n'));
expect(output, equals('/path/to/main.dart.dill'));
expect(output.outputFilename, equals('/path/to/main.dart.dill'));
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
});
......@@ -157,7 +157,7 @@ void main() {
.thenAnswer((Invocation invocation) => const Stream<List<int>>.empty()
);
final String output = await generator.recompile(
final CompilerOutput output = await generator.recompile(
'/path/to/main.dart', null /* invalidatedFiles */
);
expect(output, equals(null));
......@@ -171,12 +171,12 @@ void main() {
final StreamController<List<int>> streamController = new StreamController<List<int>>();
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => streamController.stream);
streamController.add(utf8.encode('result abc\nline0\nline1\nabc /path/to/main.dart.dill\n'));
streamController.add(utf8.encode('result abc\nline0\nline1\nabc /path/to/main.dart.dill 0\n'));
await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
'result abc\nline1\nline2\nabc /path/to/main.dart.dill\n');
'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
......@@ -195,15 +195,15 @@ void main() {
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => streamController.stream);
streamController.add(utf8.encode(
'result abc\nline0\nline1\nabc /path/to/main.dart.dill\n'
'result abc\nline0\nline1\nabc /path/to/main.dart.dill 0\n'
));
await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */);
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
'result abc\nline1\nline2\nabc /path/to/main.dart.dill\n');
'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
'result abc\nline2\nline3\nabc /path/to/main.dart.dill\n');
'result abc\nline2\nline3\nabc /path/to/main.dart.dill 0\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
......@@ -226,8 +226,8 @@ Future<Null> _recompile(StreamController<List<int>> streamController,
new Future<List<int>>(() {
streamController.add(utf8.encode(mockCompilerOutput));
});
final String output = await generator.recompile(null /* mainPath */, <String>['/path/to/main.dart']);
expect(output, equals('/path/to/main.dart.dill'));
final CompilerOutput output = await generator.recompile(null /* mainPath */, <String>['/path/to/main.dart']);
expect(output.outputFilename, equals('/path/to/main.dart.dill'));
final String commands = mockFrontendServerStdIn.getAndClear();
final RegExp re = new RegExp('^recompile (.*)\\n/path/to/main.dart\\n(.*)\\n\$');
expect(commands, matches(re));
......
......@@ -197,7 +197,7 @@ class FuchsiaRemoteConnection {
final int lastSpace = trimmed.lastIndexOf(' ');
final String lastWord = trimmed.substring(lastSpace + 1);
if ((lastWord != '.') && (lastWord != '..')) {
final int value = int.parse(lastWord, onError: (_) => null);
final int value = int.tryParse(lastWord);
if (value != null) {
ports.add(value);
}
......
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