[frontend_server] Add FrontendServer wrapper in test
This adds a FrontendServer class that wraps steam communication,
reducing the amount of boilerplate code needed to write frontend
server tests.
Change-Id: I9ff0fe6e04a83503e00eea9fc764231e50d6207a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253666
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/frontend_server/test/frontend_server_test.dart b/pkg/frontend_server/test/frontend_server_test.dart
index d4ad295..06e04e1 100644
--- a/pkg/frontend_server/test/frontend_server_test.dart
+++ b/pkg/frontend_server/test/frontend_server_test.dart
@@ -529,23 +529,11 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -553,33 +541,15 @@
expect(result.errorsCount, equals(0));
expect(dillFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
-
- // 'compile-expression <boundarykey>
- // expression
- // definitions (one per line)
- // ...
- // <boundarykey>
- // type-definitions (one per line)
- // ...
- // <boundarykey>
- // <libraryUri: String>
- // <klass: String>
- // <isStatic: true|false>
- outputParser.expectSources = false;
- streamController.add(
- 'compile-expression abc\n2+2\nabc\nabc\n${file.uri}\n\n\n'
- .codeUnits);
+ frontendServer.accept();
+ frontendServer.compileExpression('2+2', file.uri, isStatic: null);
count += 1;
} else if (count == 1) {
expect(result.errorsCount, isNull);
// Previous request should have failed because isStatic was blank
expect(compiledResult.status, isNull);
- outputParser.expectSources = false;
- streamController.add(
- 'compile-expression abc\n2+2\nabc\nabc\n${file.uri}\n\nfalse\n'
- .codeUnits);
+ frontendServer.compileExpression('2+2', file.uri, isStatic: false);
count += 1;
} else if (count == 2) {
expect(result.errorsCount, equals(0));
@@ -589,19 +559,20 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- streamController.add('compile foo.bar\n'.codeUnits);
+ frontendServer.compile('foo.bar');
count += 1;
} else {
expect(count, 3);
// Third request is to 'compile' non-existent file, that should fail.
expect(result.errorsCount, greaterThan(0));
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
expect(count, 3);
+ frontendServer.close();
});
test('mixed compile expression commands with non-web target', () async {
@@ -619,23 +590,11 @@
var library = 'package:hello/foo.dart';
var module = 'packages/hello/foo.dart';
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -643,23 +602,9 @@
expect(result.errorsCount, equals(0));
expect(dillFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
- // 'compile-expression <boundarykey>
- // expression
- // definitions (one per line)
- // ...
- // <boundarykey>
- // type-definitions (one per line)
- // ...
- // <boundarykey>
- // <libraryUri: String>
- // <klass: String>
- // <isStatic: true|false>
- outputParser.expectSources = false;
- streamController.add('compile-expression abc\n'
- '2+2\nabc\nabc\n${file.uri}\n\nfalse\n'
- .codeUnits);
+ frontendServer.compileExpression('2+2', file.uri, isStatic: false);
count += 1;
} else if (count == 1) {
expect(result.errorsCount, equals(0));
@@ -669,22 +614,7 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- // 'compile-expression-to-js <boundarykey>
- // libraryUri
- // line
- // column
- // jsModules (one k-v pair per line)
- // ...
- // <boundarykey>
- // jsFrameValues (one k-v pair per line)
- // ...
- // <boundarykey>
- // moduleName
- // expression
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n1\n1\nabc\nabc\n$module\n\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs('', library, 1, 1, module);
count += 1;
} else if (count == 2) {
// Third request is to 'compile-expression-to-js' that fails
@@ -692,10 +622,7 @@
expect(result.errorsCount, isNull);
expect(compiledResult.status, isNull);
- outputParser.expectSources = false;
- streamController.add('compile-expression abc\n'
- '2+2\nabc\nabc\n${file.uri}\n\nfalse\n'
- .codeUnits);
+ frontendServer.compileExpression('2+2', file.uri, isStatic: false);
count += 1;
} else if (count == 3) {
expect(result.errorsCount, equals(0));
@@ -705,12 +632,13 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
expect(count, 3);
+ frontendServer.close();
});
test('compiler reports correct sources added', () async {
@@ -729,47 +657,31 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- final Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${mainFile.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ final Future<int> result = frontendServer.open(args);
+ frontendServer.compile(mainFile.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
compiledResult.expectNoErrors();
if (count == 0) {
expect(compiledResult.sources.length, equals(1));
expect(compiledResult.sources, contains('+${mainFile.uri}'));
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
mainFile
.writeAsStringSync("import 'lib.dart'; main() => print(foo);\n");
- inputStreamController.add('recompile ${mainFile.path} abc\n'
- '${mainFile.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(mainFile.uri, entryPoint: mainFile.path);
count += 1;
} else if (count == 1) {
expect(compiledResult.sources.length, equals(1));
expect(compiledResult.sources, contains('+${libFile.uri}'));
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
}, timeout: Timeout.factor(100));
test('compiler reports correct sources removed', () async {
@@ -788,47 +700,31 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- final Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${mainFile.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ final Future<int> result = frontendServer.open(args);
+ frontendServer.compile(mainFile.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
compiledResult.expectNoErrors();
if (count == 0) {
expect(compiledResult.sources.length, equals(2));
expect(compiledResult.sources,
allOf(contains('+${mainFile.uri}'), contains('+${libFile.uri}')));
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
mainFile.writeAsStringSync("main() => print('foo');\n");
- inputStreamController.add('recompile ${mainFile.path} abc\n'
- '${mainFile.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(mainFile.uri, entryPoint: mainFile.path);
count += 1;
} else if (count == 1) {
expect(compiledResult.sources.length, equals(1));
expect(compiledResult.sources, contains('-${libFile.uri}'));
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
}, timeout: Timeout.factor(100));
test('compile expression when delta is rejected', () async {
@@ -845,24 +741,11 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- final Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ final Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -870,30 +753,9 @@
expect(result.errorsCount, 0);
expect(dillFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
- // 'compile-expression <boundarykey>
- // expression
- // definitions (one per line)
- // ...
- // <boundarykey>
- // type-definitions (one per line)
- // ...
- // <boundarykey>
- // <libraryUri: String>
- // <klass: String>
- // <isStatic: true|false>
- outputParser.expectSources = false;
- inputStreamController.add('''
-compile-expression abc
-main1
-abc
-abc
-${file.uri}
-
-true
-'''
- .codeUnits);
+ frontendServer.compileExpression('main1', file.uri, isStatic: true);
count += 1;
} else if (count == 1) {
// Second request was to 'compile-expression', which resulted in
@@ -904,36 +766,29 @@
expect(outputFile.lengthSync(), isPositive);
file.writeAsStringSync("import 'lib.dart'; main() => foo();\n");
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file.uri, entryPoint: file.path);
count += 1;
} else if (count == 2) {
// Third request was to recompile the script after renaming a function.
expect(result.errorsCount, 0);
- outputParser.expectSources = false;
- inputStreamController.add('reject\n'.codeUnits);
+ frontendServer.reject();
count += 1;
} else if (count == 3) {
// Fourth request was to reject the compilation results.
- outputParser.expectSources = false;
- inputStreamController.add(
- 'compile-expression abc\nmain1\nabc\nabc\n${file.uri}\n\ntrue\n'
- .codeUnits);
+ frontendServer.compileExpression('main1', file.uri, isStatic: true);
count += 1;
} else {
expect(count, 4);
// Fifth request was to 'compile-expression' that references original
// function, which should still be successful.
expect(result.errorsCount, 0);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
}, timeout: Timeout.factor(100));
test('recompile request keeps incremental output dill filename', () async {
@@ -948,36 +803,20 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
if (count == 0) {
// First request is to 'compile', which results in full kernel file.
expect(dillFile.existsSync(), equals(true));
compiledResult.expectNoErrors(filename: dillFile.path);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
var file2 = File('${tempDir.path}/bar.dart')..createSync();
file2.writeAsStringSync("main() {}\n");
- inputStreamController.add('recompile ${file2.path} abc\n'
- '${file2.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file2.uri, entryPoint: file2.path);
} else {
expect(count, 1);
// Second request is to 'recompile', which results in incremental
@@ -985,11 +824,12 @@
var dillIncFile = File('${dillFile.path}.incremental.dill');
compiledResult.expectNoErrors(filename: dillIncFile.path);
expect(dillIncFile.existsSync(), equals(true));
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test(
@@ -1043,30 +883,17 @@
'--packages=${config.path}',
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
if (count == 0) {
// First request is to 'compile', which results in full kernel file.
expect(dillFile.existsSync(), equals(true));
compiledResult.expectNoErrors(filename: dillFile.path);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";
@@ -1080,10 +907,7 @@
class BarState extends State<FizzWidget> {}
""");
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file.uri, entryPoint: file.path);
} else if (count == 1) {
expect(count, 1);
// Second request is to 'recompile', which results in incremental
@@ -1096,7 +920,7 @@
expect(widgetCacheFile.existsSync(), equals(true));
expect(widgetCacheFile.readAsStringSync(), 'FooWidget');
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";
@@ -1113,10 +937,7 @@
class BarState extends State<FizzWidget> {}
""");
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file.uri, entryPoint: file.path);
} else if (count == 2) {
// Second request is to 'recompile', which results in incremental
// kernel file and invalidation of StatelessWidget.
@@ -1128,7 +949,7 @@
expect(widgetCacheFile.existsSync(), equals(true));
expect(widgetCacheFile.readAsStringSync(), 'FizzWidget');
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";
@@ -1147,10 +968,7 @@
// Added.
}
""");
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file.uri, entryPoint: file.path);
} else if (count == 3) {
// Third request is to 'recompile', which results in incremental
// kernel file and invalidation of State class.
@@ -1162,7 +980,7 @@
expect(widgetCacheFile.existsSync(), equals(true));
expect(widgetCacheFile.readAsStringSync(), 'FizzWidget');
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";
@@ -1183,10 +1001,7 @@
// Added.
}
""");
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file.uri, entryPoint: file.path);
} else if (count == 4) {
// Fourth request is to 'recompile', which results in incremental
// kernel file and no widget cache
@@ -1196,11 +1011,12 @@
compiledResult.expectNoErrors(filename: dillIncFile.path);
expect(dillIncFile.existsSync(), equals(true));
expect(widgetCacheFile.existsSync(), equals(false));
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test('unsafe-package-serialization', () async {
@@ -1262,23 +1078,11 @@
'--no-incremental-serialization',
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
switch (count) {
@@ -1287,18 +1091,16 @@
expect(result.filename, dillFile.path);
expect(result.errorsCount, 0);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('reset\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.reset();
- inputStreamController.add('recompile ${fileB.path} abc\n'
- '${fileB.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(fileB.uri, entryPoint: fileB.path);
break;
case 1:
expect(result.filename, dillFile.path);
expect(result.errorsCount, 0);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
// Loadable.
Component component = loadComponentFromBinary(dillFile.path);
@@ -1319,7 +1121,7 @@
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test('incremental-serialization', () async {
@@ -1396,23 +1198,11 @@
'--incremental-serialization',
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
switch (count) {
@@ -1421,18 +1211,16 @@
expect(result.filename, dillFile.path);
expect(result.errorsCount, 0);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('reset\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.reset();
- inputStreamController.add('recompile ${fileB.path} abc\n'
- '${fileB.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(fileB.uri, entryPoint: fileB.path);
break;
case 1:
expect(result.filename, dillFile.path);
expect(result.errorsCount, 0);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
// Loadable.
Component component = loadComponentFromBinary(dillFile.path);
@@ -1453,7 +1241,7 @@
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test('incremental-serialization with reject', () async {
@@ -1484,23 +1272,11 @@
'--incremental-serialization',
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
switch (count) {
@@ -1523,16 +1299,12 @@
file.writeAsStringSync("pkgA() {} pkgA_2() {}");
count += 1;
- outputParser.expectSources = false;
- inputStreamController.add('reject\n'.codeUnits);
+ frontendServer.reject();
break;
case 1:
count += 1;
- inputStreamController.add('reset\n'.codeUnits);
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.reset();
+ frontendServer.recompile(file.uri, entryPoint: file.path);
break;
case 2:
expect(dillFile.existsSync(), equals(true));
@@ -1553,17 +1325,15 @@
file.writeAsStringSync("pkgA() {} pkgA_2() {} pkgA_3() {}");
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('reset\n'.codeUnits);
- inputStreamController.add('recompile ${file.path} abc\n'
- '${file.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.accept();
+ frontendServer.reset();
+ frontendServer.recompile(file.uri, entryPoint: file.path);
break;
case 3:
expect(result.filename, dillFile.path);
expect(result.errorsCount, 0);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
// Loadable.
Component component = loadComponentFromBinary(dillFile.path);
@@ -1578,7 +1348,7 @@
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test('compile and recompile report non-zero error count', () async {
@@ -1593,24 +1363,11 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${file.uri}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(file.uri.toString());
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
switch (count) {
@@ -1619,37 +1376,33 @@
expect(result.filename, dillFile.path);
expect(result.errorsCount, 2);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
var file2 = File('${tempDir.path}/bar.dart')..createSync();
file2.writeAsStringSync("main() { baz(); }\n");
- inputStreamController.add('recompile ${file2.uri} abc\n'
- '${file2.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file2.uri,
+ entryPoint: file2.uri.toString());
break;
case 1:
var dillIncFile = File('${dillFile.path}.incremental.dill');
expect(result.filename, dillIncFile.path);
expect(result.errorsCount, 1);
count += 1;
- inputStreamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
var file2 = File('${tempDir.path}/bar.dart')..createSync();
file2.writeAsStringSync("main() { }\n");
- inputStreamController.add('recompile ${file2.uri} abc\n'
- '${file2.uri}\n'
- 'abc\n'
- .codeUnits);
+ frontendServer.recompile(file2.uri,
+ entryPoint: file2.uri.toString());
break;
case 2:
var dillIncFile = File('${dillFile.path}.incremental.dill');
expect(result.filename, dillIncFile.path);
expect(result.errorsCount, 0);
expect(dillIncFile.existsSync(), equals(true));
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
test('compile and recompile with MultiRootFileSystem', () async {
@@ -1699,23 +1452,10 @@
'--output-dill=${dillFile.path}'
];
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${src1.uri}\n'.codeUnits);
- receivedResults.stream.listen((Result compiledResult) {
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(src1.uri.toString());
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
expect(dillFile.existsSync(), equals(true));
@@ -1730,10 +1470,10 @@
.where((lib) => srcUris.contains(lib.fileUri))
.length,
srcUris.length);
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
});
group('http uris', () {
@@ -2152,23 +1892,11 @@
'--packages=${packages.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
var count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
count++;
@@ -2176,18 +1904,19 @@
// First request is to 'compile', which results in full JavaScript
expect(result.errorsCount, equals(0));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
- streamController.add('compile foo.bar\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.compile('foo.bar');
} else {
expect(count, 2);
// Second request is to 'compile' non-existent file, that should fail.
expect(result.errorsCount, greaterThan(0));
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
expect(count, 2);
+ frontendServer.close();
}, skip: 'https://github.com/dart-lang/sdk/issues/43959');
test('compile to JavaScript with no metadata', () async {
@@ -2232,23 +1961,11 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
var count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
count++;
@@ -2260,13 +1977,13 @@
expect(sourceMapsFile.existsSync(), equals(true));
expect(metadataFile.existsSync(), equals(false));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
- outputParser.expectSources = false;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
});
expect(await result, 0);
expect(count, 1);
+ frontendServer.close();
});
test('compile to JavaScript with metadata', () async {
@@ -2314,23 +2031,11 @@
'--emit-debug-symbols',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
count++;
@@ -2342,13 +2047,13 @@
expect(metadataFile.existsSync(), equals(true));
expect(symbolsFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
- outputParser.expectSources = false;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
});
expect(await result, 0);
expect(count, 1);
+ frontendServer.close();
});
// This test exercises what happens when a change occurs with a single
@@ -2446,23 +2151,11 @@
'--emit-debug-symbols',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $entryPoint\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(entryPoint);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
switch (count) {
case 0:
CompilationResult result =
@@ -2488,7 +2181,7 @@
expect(jsModules[1], contains('<<d>>'));
expect(jsModules[1], contains('<<e>>'));
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
fileD.writeAsStringSync("""
import 'e.dart';
@@ -2498,12 +2191,9 @@
e();
}
""");
- // Trigger a recompile that invalidates 'd.dart'. The input uri
- // (a.dart) is passed explicitly.
- streamController.add('recompile ${entryPoint} abc\n'
- '${fileD.uri}\n'
- 'abc\n'
- .codeUnits);
+ // Trigger a recompile that invalidates 'd.dart'. The entry point
+ // uri (a.dart) is passed explicitly.
+ frontendServer.recompile(fileD.uri, entryPoint: entryPoint);
break;
case 1:
CompilationResult result =
@@ -2527,7 +2217,7 @@
expect(jsModules[0], contains('<<d2>>'));
expect(jsModules[0], contains('<<e>>'));
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
fileE.writeAsStringSync("""
import 'c.dart';
@@ -2537,13 +2227,9 @@
"<<e2>>";
}
""");
- // Trigger a recompile that invalidates 'd.dart'. The input uri
- // (a.dart) is omitted.
- streamController.add('recompile abc\n'
- '${fileE.uri}\n'
- 'abc\n'
- .codeUnits);
- break;
+ // Trigger a recompile that invalidates 'd.dart'. The entry point
+ // uri (a.dart) is omitted.
+ frontendServer.recompile(fileE.uri);
break;
case 2:
CompilationResult result =
@@ -2569,9 +2255,8 @@
expect(jsModules[0], contains('<<e1>>'));
expect(jsModules[0], contains('<<e2>>'));
- streamController.add('accept\n'.codeUnits);
- outputParser.expectSources = false;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
break;
default:
break;
@@ -2581,6 +2266,7 @@
expect(await result, 0);
expect(count, 3);
+ frontendServer.close();
});
test('compile to JavaScript all modules with unsound null safety',
@@ -2622,24 +2308,12 @@
'--packages=${packageConfig.path}'
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
var count = 0;
var expectationCompleter = Completer<bool>();
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
count++;
@@ -2658,15 +2332,15 @@
jsModules[0], contains('dart._checkModuleNullSafetyMode(false);'));
expect(
jsModules[1], contains('dart._checkModuleNullSafetyMode(false);'));
- streamController.add('accept\n'.codeUnits);
- outputParser.expectSources = false;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
expectationCompleter.complete(true);
});
await expectationCompleter.future;
expect(await result, 0);
expect(count, 1);
+ frontendServer.close();
}, timeout: Timeout.none);
test('compile to JavaScript, all modules with sound null safety', () async {
@@ -2706,24 +2380,12 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
var count = 0;
var expectationCompleter = Completer<bool>();
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
count++;
@@ -2742,15 +2404,15 @@
jsModules[0], contains('dart._checkModuleNullSafetyMode(true);'));
expect(
jsModules[1], contains('dart._checkModuleNullSafetyMode(true);'));
- streamController.add('accept\n'.codeUnits);
- outputParser.expectSources = false;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.accept();
+ frontendServer.quit();
expectationCompleter.complete(true);
});
await expectationCompleter.future;
expect(await result, 0);
expect(count, 1);
+ frontendServer.close();
});
test('compile expression to Javascript', () async {
@@ -2790,23 +2452,11 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -2816,24 +2466,9 @@
expect(manifestFile.existsSync(), equals(true));
expect(sourceMapsFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
- // 'compile-expression-to-js <boundarykey>
- // libraryUri
- // line
- // column
- // jsModules (one k-v pair per line)
- // ...
- // <boundarykey>
- // jsFrameValues (one k-v pair per line)
- // ...
- // <boundarykey>
- // moduleName
- // expression
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n2\n1\nabc\nabc\n$module\n\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs('', library, 2, 1, module);
count += 1;
} else if (count == 1) {
// Second request is to 'compile-expression-to-js' that fails
@@ -2843,10 +2478,7 @@
return status.endsWith(' 1');
});
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n2\n1\nabc\nabc\n$module\n2+2\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs('2+2', library, 2, 1, module);
count += 1;
} else if (count == 2) {
expect(result.errorsCount, equals(0));
@@ -2856,14 +2488,14 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- streamController.add('compile foo.bar\n'.codeUnits);
+ frontendServer.compile('foo.bar');
count += 1;
} else {
expect(count, 3);
// Fourth request is to 'compile' non-existent file, that should fail.
expect(result.errorsCount, greaterThan(0));
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
@@ -2910,23 +2542,11 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -2942,25 +2562,14 @@
// literal.
expect(compiledOutput, contains('print(true);'));
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
- // 'compile-expression-to-js <boundarykey>
- // libraryUri
- // line
- // column
- // jsModules (one k-v pair per line)
- // ...
- // <boundarykey>
- // jsFrameValues (one k-v pair per line)
- // ...
- // <boundarykey>
- // moduleName
- // expression
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n2\n1\nabc\nabc\n$module\n'
- 'const bool.fromEnvironment("dart.library.html")\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs(
+ 'const bool.fromEnvironment("dart.library.html")',
+ library,
+ 2,
+ 1,
+ module);
count += 1;
} else {
expect(count, 1);
@@ -2971,13 +2580,13 @@
// The constant environment variable should be inlined as a boolean
// literal.
expect(resultFile.readAsStringSync(), contains('return true;'));
- outputParser.expectSources = false;
count += 1;
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
expect(count, 2);
+ frontendServer.close();
});
test('mixed compile expression commands with web target', () async {
@@ -3016,23 +2625,11 @@
'--packages=${packageConfig.path}',
];
- final StreamController<List<int>> streamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: streamController.stream, output: ioSink);
- streamController.add('compile $library\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(library);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
if (count == 0) {
@@ -3042,24 +2639,9 @@
expect(manifestFile.existsSync(), equals(true));
expect(sourceMapsFile.existsSync(), equals(true));
expect(result.filename, dillFile.path);
- streamController.add('accept\n'.codeUnits);
+ frontendServer.accept();
- // 'compile-expression-to-js <boundarykey>
- // libraryUri
- // line
- // column
- // jsModules (one k-v pair per line)
- // ...
- // <boundarykey>
- // jsFrameValues (one k-v pair per line)
- // ...
- // <boundarykey>
- // moduleName
- // expression
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n2\n1\nabc\nabc\n$module\n2+2\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs('2+2', library, 2, 1, module);
count += 1;
} else if (count == 1) {
expect(result.errorsCount, equals(0));
@@ -3069,21 +2651,7 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- // 'compile-expression <boundarykey>
- // expression
- // definitions (one per line)
- // ...
- // <boundarykey>
- // type-definitions (one per line)
- // ...
- // <boundarykey>
- // <libraryUri: String>
- // <klass: String>
- // <isStatic: true|false>
- outputParser.expectSources = false;
- streamController.add('compile-expression abc\n'
- '2+2\nabc\nabc\n${file.uri}\n\nfalse\n'
- .codeUnits);
+ frontendServer.compileExpression('2+2', file.uri, isStatic: false);
count += 1;
} else if (count == 2) {
expect(result.errorsCount, equals(0));
@@ -3093,10 +2661,7 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- outputParser.expectSources = false;
- streamController.add('compile-expression-to-js abc\n'
- '$library\n2\n1\nabc\nabc\n$module\n2+2\n'
- .codeUnits);
+ frontendServer.compileExpressionToJs('2+2', library, 2, 1, module);
count += 1;
} else if (count == 3) {
expect(result.errorsCount, equals(0));
@@ -3106,12 +2671,13 @@
expect(outputFile.existsSync(), equals(true));
expect(outputFile.lengthSync(), isPositive);
- streamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
expect(count, 3);
+ frontendServer.close();
});
test('compile "package:"-file', () async {
@@ -3212,24 +2778,11 @@
List<List<int>> compiledKernels = <List<int>>[];
for (int serverCloses = 0; serverCloses < 2; ++serverCloses) {
print("Restart #$serverCloses");
- final StreamController<List<int>> inputStreamController =
- StreamController<List<int>>();
- final StreamController<List<int>> stdoutStreamController =
- StreamController<List<int>>();
- final IOSink ioSink = IOSink(stdoutStreamController.sink);
- StreamController<Result> receivedResults = StreamController<Result>();
-
- final outputParser = OutputParser(receivedResults);
- stdoutStreamController.stream
- .transform(utf8.decoder)
- .transform(const LineSplitter())
- .listen(outputParser.listener);
-
- Future<int> result =
- starter(args, input: inputStreamController.stream, output: ioSink);
- inputStreamController.add('compile ${dart2js.path}\n'.codeUnits);
+ final frontendServer = FrontendServer();
+ Future<int> result = frontendServer.open(args);
+ frontendServer.compile(dart2js.path);
int count = 0;
- receivedResults.stream.listen((Result compiledResult) {
+ frontendServer.listen((Result compiledResult) {
CompilationResult result =
CompilationResult.parse(compiledResult.status);
String outputFilename = result.filename;
@@ -3275,11 +2828,10 @@
count += 1;
// Restart with no changes
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('reset\n'.codeUnits);
- inputStreamController.add('recompile ${dart2js.path} x$count\n'
- 'x$count\n'
- .codeUnits);
+ frontendServer.accept();
+ frontendServer.reset();
+ frontendServer.recompile(null,
+ entryPoint: dart2js.path, boundaryKey: 'x$count');
} else if (count == 1) {
// Restart. Expect full kernel file.
expect(dillFile.existsSync(), equals(true));
@@ -3301,10 +2853,9 @@
count += 1;
// Reload with no changes
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('recompile ${dart2js.path} x$count\n'
- 'x$count\n'
- .codeUnits);
+ frontendServer.accept();
+ frontendServer.recompile(null,
+ entryPoint: dart2js.path, boundaryKey: 'x$count');
} else if (count == 2) {
// Partial file. Expect to be empty.
expect(incrementalDillFile.existsSync(), equals(true));
@@ -3318,11 +2869,9 @@
count += 1;
// Reload with 1 change
- inputStreamController.add('accept\n'.codeUnits);
- inputStreamController.add('recompile ${dart2js.path} x$count\n'
- '${dart2jsOtherFile.uri}\n'
- 'x$count\n'
- .codeUnits);
+ frontendServer.accept();
+ frontendServer.recompile(dart2jsOtherFile.uri,
+ entryPoint: dart2js.path, boundaryKey: 'x$count');
} else if (count == 3) {
// Partial file. Expect to not be empty.
expect(incrementalDillFile.existsSync(), equals(true));
@@ -3338,11 +2887,11 @@
count += 1;
- inputStreamController.add('quit\n'.codeUnits);
+ frontendServer.quit();
}
});
expect(await result, 0);
- inputStreamController.close();
+ frontendServer.close();
}
}, timeout: Timeout.factor(8));
@@ -3525,3 +3074,171 @@
return !matcher.matches(item, matchState);
}
}
+
+/// Wrapper for the frontend server communication.
+class FrontendServer {
+ final StreamController<List<int>> inputStreamController;
+ final StreamController<List<int>> stdoutStreamController;
+ final IOSink ioSink;
+ final StreamController<Result> receivedResults;
+ final OutputParser outputParser;
+
+ factory FrontendServer() {
+ final StreamController<List<int>> inputStreamController =
+ StreamController<List<int>>();
+ final StreamController<List<int>> stdoutStreamController =
+ StreamController<List<int>>();
+ final IOSink ioSink = IOSink(stdoutStreamController.sink);
+ StreamController<Result> receivedResults = StreamController<Result>();
+ final outputParser = OutputParser(receivedResults);
+ stdoutStreamController.stream
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen(outputParser.listener);
+ return new FrontendServer._internal(inputStreamController,
+ stdoutStreamController, ioSink, receivedResults, outputParser);
+ }
+
+ FrontendServer._internal(
+ this.inputStreamController,
+ this.stdoutStreamController,
+ this.ioSink,
+ this.receivedResults,
+ this.outputParser);
+
+ /// Sets up the front end server using the provided commandline arguments
+ /// [args].
+ Future<int> open(List<String> args) =>
+ starter(args, input: inputStreamController.stream, output: ioSink);
+
+ /// Closes the listener stream.
+ void close() => inputStreamController.close();
+
+ /// Sets up [f] to be called for each [Result] received from the frontend
+ /// server.
+ void listen(void Function(Result) f) => receivedResults.stream.listen(f);
+
+ /// Accepts the last compilation delta.
+ void accept() {
+ outputParser.expectSources = false;
+ inputStreamController.add('accept\n'.codeUnits);
+ }
+
+ /// Rejects the last compilation delta.
+ void reject() {
+ outputParser.expectSources = false;
+ inputStreamController.add('reject\n'.codeUnits);
+ }
+
+ /// Resets the incremental compiler.
+ void reset() {
+ outputParser.expectSources = false;
+ inputStreamController.add('reset\n'.codeUnits);
+ }
+
+ /// Terminates the frontend server.
+ void quit() {
+ outputParser.expectSources = false;
+ inputStreamController.add('quit\n'.codeUnits);
+ }
+
+ /// Compiles the program from entry point [path].
+ // TODO(johnniwinther): Use (required) named arguments.
+ void compile(String path) {
+ outputParser.expectSources = true;
+ inputStreamController.add('compile ${path}\n'.codeUnits);
+ }
+
+ /// Recompiles the program.
+ ///
+ /// [invalidatedUri] and [invalidatedUris] define which libraries that
+ /// need recompilation.
+ ///
+ /// [entryPoint] defines the program entry-point. If not provided, the
+ /// original entry point is used.
+ ///
+ /// [boundaryKey] is used as the boundary-key in the communication with the
+ /// frontend server.
+ // TODO(johnniwinther): Use (required) named arguments.
+ void recompile(Uri invalidatedUri,
+ {String boundaryKey: 'abc',
+ List<Uri> invalidatedUris,
+ String entryPoint}) {
+ invalidatedUris ??= [if (invalidatedUri != null) invalidatedUri];
+ outputParser.expectSources = true;
+ inputStreamController.add('recompile '
+ '${entryPoint != null ? '${entryPoint} ' : ''}'
+ '${boundaryKey}\n'
+ '${invalidatedUris.map((uri) => '$uri\n').join()}'
+ '${boundaryKey}\n'
+ .codeUnits);
+ }
+
+ /// Compiles the [expression] as if it occurs in [library].
+ ///
+ /// If [className] is provided, [expression] is compiled as if it occurs in
+ /// the class of that name.
+ ///
+ /// If [isStatic] is `true`, the expression is compiled in the static scope
+ /// of [className]. If [className] is `null`, this must be `false`.
+ ///
+ /// [boundaryKey] is used as the boundary-key in the communication with the
+ /// frontend server.
+ // TODO(johnniwinther): Use (required) named arguments.
+ void compileExpression(String expression, Uri library,
+ {String boundaryKey: 'abc', String className: '', bool isStatic}) {
+ // 'compile-expression <boundarykey>
+ // expression
+ // definitions (one per line)
+ // ...
+ // <boundarykey>
+ // type-definitions (one per line)
+ // ...
+ // <boundarykey>
+ // <libraryUri: String>
+ // <klass: String>
+ // <isStatic: true|false>
+ outputParser.expectSources = false;
+ inputStreamController.add('compile-expression ${boundaryKey}\n'
+ '${expression}\n'
+ '${boundaryKey}\n'
+ '${boundaryKey}\n'
+ '${library}\n'
+ '${className}\n'
+ '${isStatic != null ? '$isStatic' : ''}\n'
+ .codeUnits);
+ }
+
+ /// Compiles the [expression] to JavaScript as if it occurs in [line] and
+ /// [column] of [library].
+ ///
+ /// [boundaryKey] is used as the boundary-key in the communication with the
+ /// frontend server.
+ // TODO(johnniwinther): Use (required) named arguments.
+ void compileExpressionToJs(String expression, String libraryUri, int line,
+ int column, String moduleName,
+ {String boundaryKey: 'abc'}) {
+ // 'compile-expression-to-js <boundarykey>
+ // libraryUri
+ // line
+ // column
+ // jsModules (one k-v pair per line)
+ // ...
+ // <boundarykey>
+ // jsFrameValues (one k-v pair per line)
+ // ...
+ // <boundarykey>
+ // moduleName
+ // expression
+ outputParser.expectSources = false;
+ inputStreamController.add('compile-expression-to-js ${boundaryKey}\n'
+ '${libraryUri}\n'
+ '${line}\n'
+ '${column}\n'
+ '${boundaryKey}\n'
+ '${boundaryKey}\n'
+ '${moduleName}\n'
+ '${expression}\n'
+ .codeUnits);
+ }
+}