mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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
This commit is contained in:
parent
c73b8a7cf6
commit
e0cd42e4ad
@ -1 +1 @@
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user