blob: c69b4f8237c095d37990981cdcd270e9ca9dce8d [file] [log] [blame]
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index 12c0770ab..b7945fd64 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -57,12 +57,15 @@ class TargetModel {
}
class CompilerOutput {
- const CompilerOutput(this.outputFilename, this.errorCount);
+ const CompilerOutput(this.outputFilename, this.errorCount, this.sources);
final String outputFilename;
final int errorCount;
+ final List<Uri> sources;
}
+enum StdoutState { CollectDiagnostic, CollectDependencies }
+
/// Handles stdin/stdout communication with the frontend server.
class StdoutHandler {
StdoutHandler({this.consumer = printError}) {
@@ -72,40 +75,71 @@ class StdoutHandler {
bool compilerMessageReceived = false;
final CompilerMessageConsumer consumer;
String boundaryKey;
+ StdoutState state = StdoutState.CollectDiagnostic;
Completer<CompilerOutput> compilerOutput;
+ final List<Uri> sources = <Uri>[];
bool _suppressCompilerMessages;
+ bool _expectSources;
void handler(String message) {
+ printTrace('-> $message');
const String kResultPrefix = 'result ';
if (boundaryKey == null && message.startsWith(kResultPrefix)) {
boundaryKey = message.substring(kResultPrefix.length);
- } else if (message.startsWith(boundaryKey)) {
+ return;
+ }
+ if (message.startsWith(boundaryKey)) {
+ if (_expectSources) {
+ if (state == StdoutState.CollectDiagnostic) {
+ state = StdoutState.CollectDependencies;
+ return;
+ }
+ }
if (message.length <= boundaryKey.length) {
compilerOutput.complete(null);
return;
}
final int spaceDelimiter = message.lastIndexOf(' ');
compilerOutput.complete(
- CompilerOutput(
- message.substring(boundaryKey.length + 1, spaceDelimiter),
- int.parse(message.substring(spaceDelimiter + 1).trim())));
- } else if (!_suppressCompilerMessages) {
- if (compilerMessageReceived == false) {
- consumer('\nCompiler message:');
- compilerMessageReceived = true;
+ CompilerOutput(
+ message.substring(boundaryKey.length + 1, spaceDelimiter),
+ int.parse(message.substring(spaceDelimiter + 1).trim()),
+ sources));
+ return;
+ }
+ if (state == StdoutState.CollectDiagnostic) {
+ if (!_suppressCompilerMessages) {
+ if (compilerMessageReceived == false) {
+ consumer('\nCompiler message:');
+ compilerMessageReceived = true;
+ }
+ consumer(message);
+ }
+ } else {
+ assert(state == StdoutState.CollectDependencies);
+ switch (message[0]) {
+ case '+':
+ sources.add(Uri.parse(message.substring(1)));
+ break;
+ case '-':
+ sources.remove(Uri.parse(message.substring(1)));
+ break;
+ default:
+ printTrace('Unexpected prefix for $message uri - ignoring');
}
- consumer(message);
}
}
// This is needed to get ready to process next compilation result output,
// with its own boundary key and new completer.
- void reset({ bool suppressCompilerMessages = false }) {
+ void reset({ bool suppressCompilerMessages = false, bool expectSources = true }) {
boundaryKey = null;
compilerMessageReceived = false;
compilerOutput = Completer<CompilerOutput>();
_suppressCompilerMessages = suppressCompilerMessages;
+ _expectSources = expectSources;
+ state = StdoutState.CollectDiagnostic;
}
}
@@ -200,7 +234,7 @@ class KernelCompiler {
if (await fingerprinter.doesFingerprintMatch()) {
printTrace('Skipping kernel compilation. Fingerprint match.');
- return CompilerOutput(outputFilePath, 0);
+ return CompilerOutput(outputFilePath, 0, /* sources */ null);
}
}
@@ -453,10 +487,13 @@ class ResidentCompiler {
? _mapFilename(request.mainPath, packageUriMapper) + ' '
: '';
_server.stdin.writeln('recompile $mainUri$inputKey');
+ printTrace('<- recompile $mainUri$inputKey');
for (String fileUri in request.invalidatedFiles) {
_server.stdin.writeln(_mapFileUri(fileUri, packageUriMapper));
+ printTrace('<- ${_mapFileUri(fileUri, packageUriMapper)}');
}
_server.stdin.writeln(inputKey);
+ printTrace('<- $inputKey');
return _stdoutHandler.compilerOutput.future;
}
@@ -545,6 +582,7 @@ class ResidentCompiler {
.listen((String message) { printError(message); });
_server.stdin.writeln('compile $scriptUri');
+ printTrace('<- compile $scriptUri');
return _stdoutHandler.compilerOutput.future;
}
@@ -570,7 +608,7 @@ class ResidentCompiler {
}
Future<CompilerOutput> _compileExpression(_CompileExpressionRequest request) async {
- _stdoutHandler.reset(suppressCompilerMessages: true);
+ _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false);
// 'compile-expression' should be invoked after compiler has been started,
// program was compiled.
@@ -597,6 +635,7 @@ class ResidentCompiler {
void accept() {
if (_compileRequestNeedsConfirmation) {
_server.stdin.writeln('accept');
+ printTrace('<- accept');
}
_compileRequestNeedsConfirmation = false;
}
@@ -620,6 +659,7 @@ class ResidentCompiler {
}
_stdoutHandler.reset();
_server.stdin.writeln('reject');
+ printTrace('<- reject');
_compileRequestNeedsConfirmation = false;
return _stdoutHandler.compilerOutput.future;
}
@@ -629,6 +669,7 @@ class ResidentCompiler {
/// kernel file.
void reset() {
_server?.stdin?.writeln('reset');
+ printTrace('<- reset');
}
String _mapFilename(String filename, PackageUriMapper packageUriMapper) {
diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart
index 407a51b12..ea63e73c6 100644
--- a/packages/flutter_tools/lib/src/devfs.dart
+++ b/packages/flutter_tools/lib/src/devfs.dart
@@ -484,6 +484,8 @@ class DevFS {
outputPath: dillOutputPath ?? getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation),
packagesFilePath : _packagesFilePath,
);
+ // list of sources that needs to be monitored are in [compilerOutput.sources]
+ //
// Don't send full kernel file that would overwrite what VM already
// started loading from.
if (!bundleFirstUpload) {
diff --git a/packages/flutter_tools/test/compile_test.dart b/packages/flutter_tools/test/compile_test.dart
index b149a2a84..0d920bdbe 100644
--- a/packages/flutter_tools/test/compile_test.dart
+++ b/packages/flutter_tools/test/compile_test.dart
@@ -78,14 +78,17 @@ example:org-dartlang-app:/
});
});
- test(StdoutHandler, () async {
+ testUsingContext('StdOutHandler test', () async {
final StdoutHandler stdoutHandler = StdoutHandler();
stdoutHandler.handler('result 12345');
expect(stdoutHandler.boundaryKey, '12345');
+ stdoutHandler.handler('12345');
stdoutHandler.handler('12345 message 0');
final CompilerOutput output = await stdoutHandler.compilerOutput.future;
expect(output.errorCount, 0);
expect(output.outputFilename, 'message');
+ }, overrides: <Type, Generator>{
+ Logger: () => BufferLogger(),
});
group('batch compile', () {
@@ -115,7 +118,7 @@ example:org-dartlang-app:/
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0'
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
))
));
final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
@@ -138,7 +141,7 @@ example:org-dartlang-app:/
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc'
+ 'result abc\nline1\nline2\nabc\nabc'
))
));
final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
@@ -163,7 +166,7 @@ example:org-dartlang-app:/
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc'
+ 'result abc\nline1\nline2\nabc\nabc'
))
));
final CompilerOutput output = await kernelCompiler.compile(
@@ -220,7 +223,7 @@ example:org-dartlang-app:/
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => Stream<List<int>>.fromFuture(
Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0'
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
))
));
@@ -264,7 +267,7 @@ example:org-dartlang-app:/
final StreamController<List<int>> streamController = 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 0\n'));
+ streamController.add(utf8.encode('result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0\n'));
await generator.recompile(
'/path/to/main.dart',
null, /* invalidatedFiles */
@@ -278,14 +281,14 @@ example:org-dartlang-app:/
await _reject(streamController, generator, mockFrontendServerStdIn, '', '');
await _recompile(streamController, generator, mockFrontendServerStdIn,
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n');
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');
await _accept(streamController, generator, mockFrontendServerStdIn, '^accept\\n\$');
await _recompile(streamController, generator, mockFrontendServerStdIn,
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n');
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');
- await _reject(streamController, generator, mockFrontendServerStdIn, 'result abc\nabc\n',
+ await _reject(streamController, generator, mockFrontendServerStdIn, 'result abc\nabc\nabc\nabc',
'^reject\\n\$');
verifyNoMoreInteractions(mockFrontendServerStdIn);
@@ -309,15 +312,15 @@ example:org-dartlang-app:/
when(mockFrontendServer.stdout)
.thenAnswer((Invocation invocation) => streamController.stream);
streamController.add(utf8.encode(
- 'result abc\nline0\nline1\nabc /path/to/main.dart.dill 0\n'
+ 'result abc\nline0\nline1\nabc\nabc /path/to/main.dart.dill 0\n'
));
await generator.recompile('/path/to/main.dart', null /* invalidatedFiles */, outputPath: '/build/');
expect(mockFrontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n');
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n');
await _recompile(streamController, generator, mockFrontendServerStdIn,
- 'result abc\nline2\nline3\nabc /path/to/main.dart.dill 0\n');
+ 'result abc\nline2\nline3\nabc\nabc /path/to/main.dart.dill 0\n');
verifyNoMoreInteractions(mockFrontendServerStdIn);
expect(mockFrontendServerStdIn.getAndClear(), isEmpty);
@@ -389,7 +392,7 @@ example:org-dartlang-app:/
compileExpressionResponseCompleter.future]));
compileResponseCompleter.complete(Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n'
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n'
)));
await generator.recompile(
@@ -406,7 +409,7 @@ example:org-dartlang-app:/
compileExpressionResponseCompleter.complete(
Future<List<int>>.value(utf8.encode(
- 'result def\nline1\nline2\ndef /path/to/main.dart.dill.incremental 0\n'
+ 'result def\nline1\nline2\ndef\ndef /path/to/main.dart.dill.incremental 0\n'
)));
generator.compileExpression(
'2+2', null, null, null, null, false).then(
@@ -488,7 +491,7 @@ example:org-dartlang-app:/
);
compileResponseCompleter.complete(Future<List<int>>.value(utf8.encode(
- 'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0\n'
+ 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0\n'
)));
expect(await lastExpressionCompleted.future, isTrue);
diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart
index 42c9d8f7f..c47b4ff7c 100644
--- a/packages/flutter_tools/test/src/mocks.dart
+++ b/packages/flutter_tools/test/src/mocks.dart
@@ -490,6 +490,6 @@ class MockResidentCompiler extends BasicMock implements ResidentCompiler {
Future<CompilerOutput> recompile(String mainPath, List<String> invalidatedFiles, { String outputPath, String packagesFilePath }) async {
fs.file(outputPath).createSync(recursive: true);
fs.file(outputPath).writeAsStringSync('compiled_kernel_output');
- return CompilerOutput(outputPath, 0);
+ return CompilerOutput(outputPath, 0, <Uri>[]);
}
}
diff --git a/packages/flutter_tools/test/tester/flutter_tester_test.dart b/packages/flutter_tools/test/tester/flutter_tester_test.dart
index a78f70f4f..b6524bd5d 100644
--- a/packages/flutter_tools/test/tester/flutter_tester_test.dart
+++ b/packages/flutter_tools/test/tester/flutter_tester_test.dart
@@ -177,7 +177,7 @@ Hello!
packagesPath: anyNamed('packagesPath'),
)).thenAnswer((_) async {
fs.file('$mainPath.dill').createSync(recursive: true);
- return CompilerOutput('$mainPath.dill', 0);
+ return CompilerOutput('$mainPath.dill', 0, <Uri>[]);
});
final LaunchResult result = await device.startApp(null,