Skip to content

Commit

Permalink
Add option for recompile request to switch to new main file(entrypoin…
Browse files Browse the repository at this point in the history
…t). (flutter#4703)

* Add option for recompile request to switch to new main file(entrypoint).

This is needed to reuse incremental compiler to compile unrelated programs. First use case is reuse single
incremental compiler for all tests run by 'flutter test'

* Remove left over print
  • Loading branch information
aam authored Feb 23, 2018
1 parent 44dbdbe commit 3697845
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 20 deletions.
51 changes: 35 additions & 16 deletions frontend_server/lib/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ instructions from stdin.
Instructions:
- compile <input.dart>
- recompile <boundary-key>
- recompile [<input.dart>] <boundary-key>
<path/to/updated/file1.dart>
<path/to/updated/file2.dart>
...
Expand Down Expand Up @@ -107,7 +107,7 @@ abstract class CompilerInterface {

/// Assuming some Dart program was previously compiled, recompile it again
/// taking into account some changed(invalidated) sources.
Future<Null> recompileDelta();
Future<Null> recompileDelta({String filename});

/// Accept results of previous compilation so that next recompilation cycle
/// won't recompile sources that were previously reported as changed.
Expand Down Expand Up @@ -144,6 +144,7 @@ class _FrontendCompiler implements CompilerInterface {

CompilerOptions _compilerOptions;
Uri _entryPoint;
ArgResults _options;

IncrementalCompiler _generator;
String _kernelBinaryFilename;
Expand All @@ -152,20 +153,26 @@ class _FrontendCompiler implements CompilerInterface {
final bool trackWidgetCreation;
WidgetCreatorTracker widgetCreatorTracker;

void setEntrypointFilename(String filename) {
final Uri filenameUri = Uri.base.resolveUri(new Uri.file(filename));
_kernelBinaryFilenameFull = _options['output-dill'] ?? '$filename.dill';
_kernelBinaryFilenameIncremental =
_options['output-incremental-dill'] ??
_options['output-dill'] != null
? '${_options["output-dill"]}.incremental.dill'
: '$filename.incremental.dill';
_kernelBinaryFilename = _kernelBinaryFilenameFull;
_entryPoint = filenameUri;
}

@override
Future<Null> compile(
String filename,
ArgResults options, {
IncrementalCompiler generator,
}) async {
final Uri filenameUri = Uri.base.resolveUri(new Uri.file(filename));
_kernelBinaryFilenameFull = options['output-dill'] ?? '$filename.dill';
_kernelBinaryFilenameIncremental =
options['output-incremental-dill'] ??
options['output-dill'] != null
? '${options["output-dill"]}.incremental.dill'
: '$filename.incremental.dill';
_kernelBinaryFilename = _kernelBinaryFilenameFull;
_options = options;
setEntrypointFilename(filename);
final String boundaryKey = new Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
Expand All @@ -178,7 +185,6 @@ class _FrontendCompiler implements CompilerInterface {

Program program;
if (options['incremental']) {
_entryPoint = filenameUri;
_compilerOptions = compilerOptions;
_generator = generator ?? _createGenerator(new Uri.file(_kernelBinaryFilenameFull));
await invalidateIfBootstrapping();
Expand All @@ -194,7 +200,7 @@ class _FrontendCompiler implements CompilerInterface {
];
}
program = await _runWithPrintRedirection(() =>
compileToKernel(filenameUri, compilerOptions, aot: options['aot']));
compileToKernel(_entryPoint, compilerOptions, aot: options['aot']));
}
runFlutterSpecificKernelTransforms(program);
if (program != null) {
Expand Down Expand Up @@ -260,11 +266,14 @@ class _FrontendCompiler implements CompilerInterface {
}

@override
Future<Null> recompileDelta() async {
Future<Null> recompileDelta({String filename}) async {
final String boundaryKey = new Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
await invalidateIfBootstrapping();
final Program deltaProgram = await _generator.compile();
if (filename != null) {
setEntrypointFilename(filename);
}
final Program deltaProgram = await _generator.compile(entryPoint: _entryPoint);
runFlutterSpecificKernelTransforms(deltaProgram);
final IOSink sink = new File(_kernelBinaryFilename).openWrite();
final BinaryPrinter printer = printerFactory.newBinaryPrinter(sink);
Expand Down Expand Up @@ -378,6 +387,7 @@ Future<int> starter(

_State state = _State.READY_FOR_INSTRUCTION;
String boundaryKey;
String recompileFilename;
input
.transform(UTF8.decoder)
.transform(const LineSplitter())
Expand All @@ -391,7 +401,16 @@ Future<int> starter(
string.substring(COMPILE_INSTRUCTION_SPACE.length);
await compiler.compile(filename, options, generator: generator);
} else if (string.startsWith(RECOMPILE_INSTRUCTION_SPACE)) {
boundaryKey = string.substring(RECOMPILE_INSTRUCTION_SPACE.length);
// 'recompile [<filename>] <boundarykey>'
// where <boundarykey> can't have spaces
final String remainder = string.substring(RECOMPILE_INSTRUCTION_SPACE.length);
final int spaceDelim = remainder.lastIndexOf(' ');
if (spaceDelim > -1) {
recompileFilename = remainder.substring(0, spaceDelim);
boundaryKey = remainder.substring(spaceDelim + 1);
} else {
boundaryKey = remainder;
}
state = _State.RECOMPILE_LIST;
} else if (string == 'accept') {
compiler.acceptLastDelta();
Expand All @@ -403,7 +422,7 @@ Future<int> starter(
break;
case _State.RECOMPILE_LIST:
if (string == boundaryKey) {
compiler.recompileDelta();
compiler.recompileDelta(filename: recompileFilename);
state = _State.READY_FOR_INSTRUCTION;
} else
compiler.invalidate(Uri.base.resolve(string));
Expand Down
33 changes: 29 additions & 4 deletions frontend_server/test/server_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ Future<int> main() async {
new StreamController<List<int>>();
final ReceivePort recompileCalled = new ReceivePort();

when(compiler.recompileDelta()).thenAnswer((Invocation invocation) {
when(compiler.recompileDelta(filename: null)).thenAnswer((Invocation invocation) {
recompileCalled.sendPort.send(true);
});
final int exitcode = await starter(args, compiler: compiler,
Expand All @@ -243,12 +243,37 @@ Future<int> main() async {
<void>[
compiler.invalidate(Uri.base.resolve('file1.dart')),
compiler.invalidate(Uri.base.resolve('file2.dart')),
await compiler.recompileDelta(),
await compiler.recompileDelta(filename: null),
]
);
streamController.close();
});

test('recompile few files with new entrypoint', () async {
final StreamController<List<int>> streamController =
new StreamController<List<int>>();
final ReceivePort recompileCalled = new ReceivePort();

when(compiler.recompileDelta(filename: 'file2.dart')).thenAnswer((Invocation invocation) {
recompileCalled.sendPort.send(true);
});
final int exitcode = await starter(args, compiler: compiler,
input: streamController.stream,
);
expect(exitcode, equals(0));
streamController.add('recompile file2.dart abc\nfile1.dart\nfile2.dart\nabc\n'.codeUnits);
await recompileCalled.first;

verifyInOrder(
<void>[
compiler.invalidate(Uri.base.resolve('file1.dart')),
compiler.invalidate(Uri.base.resolve('file2.dart')),
await compiler.recompileDelta(filename: 'file2.dart'),
]
);
streamController.close();
});

test('accept', () async {
final StreamController<List<int>> inputStreamController =
new StreamController<List<int>>();
Expand Down Expand Up @@ -286,7 +311,7 @@ Future<int> main() async {
new StreamController<List<int>>();
final ReceivePort recompileCalled = new ReceivePort();

when(compiler.recompileDelta()).thenAnswer((Invocation invocation) {
when(compiler.recompileDelta(filename: null)).thenAnswer((Invocation invocation) {
recompileCalled.sendPort.send(true);
});
final int exitcode = await starter(args, compiler: compiler,
Expand All @@ -303,7 +328,7 @@ Future<int> main() async {
compiler.acceptLastDelta(),
compiler.invalidate(Uri.base.resolve('file2.dart')),
compiler.invalidate(Uri.base.resolve('file3.dart')),
await compiler.recompileDelta(),
await compiler.recompileDelta(filename: null),
]);
streamController.close();
});
Expand Down

0 comments on commit 3697845

Please sign in to comment.