// @dart = 2.9
// ignore_for_file: empty_catches

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/macros/compiler/request_channel.dart';
import 'package:front_end/src/api_unstable/vm.dart';
import 'package:frontend_server/frontend_server.dart';
import 'package:kernel/ast.dart' show Component;
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/kernel.dart' show loadComponentFromBinary;
import 'package:kernel/verifier.dart' show verifyComponent;
import 'package:mockito/mockito.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:vm/incremental_compiler.dart';

void main() async {
  group('basic', () {
    final CompilerInterface compiler = _MockedCompiler();

    test('train with mocked compiler completes', () async {
      await starter(<String>['--train', 'foo.dart'], compiler: compiler);
    });
  });

  group('batch compile with mocked compiler', () {
    final CompilerInterface compiler = _MockedCompiler();
    when(compiler.compile(any, any, generator: anyNamed('generator')))
        .thenAnswer((_) => Future.value(true));

    test('compile from command line', () async {
      final List<String> args = <String>[
        'server.dart',
        '--sdk-root',
        'sdkroot',
      ];
      await starter(args, compiler: compiler);
      final List<dynamic> capturedArgs = verify(compiler.compile(
        argThat(equals('server.dart')),
        captureAny,
        generator: anyNamed('generator'),
      )).captured;
      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
    });

    test('compile from command line with link platform', () async {
      final List<String> args = <String>[
        'server.dart',
        '--sdk-root',
        'sdkroot',
        '--link-platform',
      ];
      await starter(args, compiler: compiler);
      final List<dynamic> capturedArgs = verify(compiler.compile(
        argThat(equals('server.dart')),
        captureAny,
        generator: anyNamed('generator'),
      )).captured;
      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
      expect(capturedArgs.single['link-platform'], equals(true));
    });

    test('compile from command line with widget cache', () async {
      final List<String> args = <String>[
        'server.dart',
        '--sdk-root',
        'sdkroot',
        '--flutter-widget-cache',
      ];
      await starter(args, compiler: compiler);
      final List<dynamic> capturedArgs = verify(compiler.compile(
        argThat(equals('server.dart')),
        captureAny,
        generator: anyNamed('generator'),
      )).captured;
      expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
      expect(capturedArgs.single['link-platform'], equals(true));
      expect(capturedArgs.single['flutter-widget-cache'], equals(true));
    });
  });

  group('interactive compile with mocked compiler', () {
    final CompilerInterface compiler = _MockedCompiler();

    final List<String> args = <String>[
      '--sdk-root',
      'sdkroot',
    ];

    test('compile one file', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort compileCalled = ReceivePort();
      when(compiler.compile(any, any, generator: anyNamed('generator')))
          .thenAnswer((Invocation invocation) async {
        expect(invocation.positionalArguments[0], equals('server.dart'));
        expect(
            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
        compileCalled.sendPort.send(true);
        return true;
      });

      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('compile server.dart\n'.codeUnits);
      await compileCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('compile one file to JavaScript', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort compileCalled = ReceivePort();
      when(compiler.compile(any, any, generator: anyNamed('generator')))
          .thenAnswer((Invocation invocation) async {
        expect(invocation.positionalArguments[0], equals('server.dart'));
        expect(
            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
        compileCalled.sendPort.send(true);
        return true;
      });

      Future<int> result = starter(
        ['--target=dartdevc', ...args],
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('compile server.dart\n'.codeUnits);
      await compileCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });
  });

  group('interactive compile with mocked compiler', () {
    final CompilerInterface compiler = _MockedCompiler();

    final List<String> args = <String>[
      '--sdk-root',
      'sdkroot',
    ];

    test('compile one file', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort compileCalled = ReceivePort();
      when(compiler.compile(any, any, generator: anyNamed('generator')))
          .thenAnswer((Invocation invocation) async {
        expect(invocation.positionalArguments[0], equals('server.dart'));
        expect(
            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
        compileCalled.sendPort.send(true);
        return true;
      });

      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('compile server.dart\n'.codeUnits);
      await compileCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('compile few files', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort compileCalled = ReceivePort();
      int counter = 1;
      when(compiler.compile(any, any, generator: anyNamed('generator')))
          .thenAnswer((Invocation invocation) async {
        expect(invocation.positionalArguments[0],
            equals('server${counter++}.dart'));
        expect(
            invocation.positionalArguments[1]['sdk-root'], equals('sdkroot'));
        compileCalled.sendPort.send(true);
        return true;
      });

      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('compile server1.dart\n'.codeUnits);
      inputStreamController.add('compile server2.dart\n'.codeUnits);
      await compileCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });
  });

  group('interactive incremental compile with mocked compiler', () {
    final CompilerInterface compiler = _MockedCompiler();
    when(compiler.compile(any, any, generator: anyNamed('generator')))
        .thenAnswer((_) => Future.value(true));

    final List<String> args = <String>[
      '--sdk-root',
      'sdkroot',
      '--incremental'
    ];

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

      when(compiler.recompileDelta(entryPoint: null))
          .thenAnswer((Invocation invocation) async {
        recompileCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController
          .add('recompile 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(entryPoint: null),
      ]);
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('recompile one file with widget cache does not fail', () async {
      // The component will not contain the flutter framework sources so
      // this should no-op.
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort recompileCalled = ReceivePort();

      when(compiler.recompileDelta(entryPoint: null))
          .thenAnswer((Invocation invocation) async {
        recompileCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        <String>[...args, '--flutter-widget-cache'],
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('recompile abc\nfile1.dart\nabc\n'.codeUnits);
      await recompileCalled.first;

      verifyInOrder(<void>[
        compiler.invalidate(Uri.base.resolve('file1.dart')),
        await compiler.recompileDelta(entryPoint: null),
      ]);
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

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

      when(compiler.recompileDelta(entryPoint: 'file2.dart'))
          .thenAnswer((Invocation invocation) async {
        recompileCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.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(entryPoint: 'file2.dart'),
      ]);
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('accept', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort acceptCalled = ReceivePort();
      when(compiler.acceptLastDelta()).thenAnswer((Invocation invocation) {
        acceptCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('accept\n'.codeUnits);
      await acceptCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('reset', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort resetCalled = ReceivePort();
      when(compiler.resetIncrementalCompiler())
          .thenAnswer((Invocation invocation) {
        resetCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('reset\n'.codeUnits);
      await resetCalled.first;
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    test('compile then recompile', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final ReceivePort recompileCalled = ReceivePort();

      when(compiler.recompileDelta(entryPoint: null))
          .thenAnswer((Invocation invocation) async {
        recompileCalled.sendPort.send(true);
      });
      Future<int> result = starter(
        args,
        compiler: compiler,
        input: inputStreamController.stream,
      );
      inputStreamController.add('compile file1.dart\n'.codeUnits);
      inputStreamController.add('accept\n'.codeUnits);
      inputStreamController
          .add('recompile def\nfile2.dart\nfile3.dart\ndef\n'.codeUnits);
      await recompileCalled.first;

      verifyInOrder(<void>[
        await compiler.compile('file1.dart', any,
            generator: anyNamed('generator')),
        compiler.acceptLastDelta(),
        compiler.invalidate(Uri.base.resolve('file2.dart')),
        compiler.invalidate(Uri.base.resolve('file3.dart')),
        await compiler.recompileDelta(entryPoint: null),
      ]);
      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });
  });

  group('interactive incremental compile with mocked IKG', () {
    final List<String> args = <String>[
      '--sdk-root',
      'sdkroot',
      '--incremental',
    ];

    Directory tempDir;
    setUp(() {
      tempDir = Directory.systemTemp.createTempSync();
    });
    tearDown(() {
      tempDir.delete(recursive: true);
    });

    test('compile then accept', () async {
      final StreamController<List<int>> inputStreamController =
          StreamController<List<int>>();
      final StreamController<List<int>> stdoutStreamController =
          StreamController<List<int>>();
      final IOSink ioSink = IOSink(stdoutStreamController.sink);
      ReceivePort receivedResult = ReceivePort();

      String boundaryKey;
      stdoutStreamController.stream
          .transform(utf8.decoder)
          .transform(const LineSplitter())
          .listen((String s) {
        const String RESULT_OUTPUT_SPACE = 'result ';
        if (boundaryKey == null) {
          if (s.startsWith(RESULT_OUTPUT_SPACE)) {
            boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
          }
        } else {
          if (s.startsWith(boundaryKey)) {
            boundaryKey = null;
            receivedResult.sendPort.send(true);
          }
        }
      });

      final _MockedIncrementalCompiler generator = _MockedIncrementalCompiler();
      when(generator.initialized).thenAnswer((_) => false);
      when(generator.compile()).thenAnswer((_) =>
          Future<IncrementalCompilerResult>.value(
              IncrementalCompilerResult(Component())));
      when(generator.compile(entryPoints: anyNamed("entryPoints"))).thenAnswer(
          (_) => Future<IncrementalCompilerResult>.value(
              IncrementalCompilerResult(Component())));
      final _MockedBinaryPrinterFactory printerFactory =
          _MockedBinaryPrinterFactory();
      when(printerFactory.newBinaryPrinter(any))
          .thenReturn(_MockedBinaryPrinter());
      Future<int> result = starter(
        args,
        compiler: null,
        input: inputStreamController.stream,
        output: ioSink,
        generator: generator,
        binaryPrinterFactory: printerFactory,
      );

      final source = File('${tempDir.path}/file1.dart');
      inputStreamController.add('compile ${source.path}\n'.codeUnits);
      await receivedResult.first;
      inputStreamController.add('accept\n'.codeUnits);
      receivedResult = ReceivePort();
      inputStreamController
          .add('recompile def\n${source.path}\ndef\n'.codeUnits);
      await receivedResult.first;

      inputStreamController.add('quit\n'.codeUnits);
      expect(await result, 0);
      inputStreamController.close();
    });

    group('compile with output path', () {
      final CompilerInterface compiler = _MockedCompiler();
      when(compiler.compile(any, any, generator: anyNamed('generator')))
          .thenAnswer((_) => Future.value(true));

      test('compile from command line', () async {
        final List<String> args = <String>[
          'server.dart',
          '--sdk-root',
          'sdkroot',
          '--output-dill',
          '/foo/bar/server.dart.dill',
          '--output-incremental-dill',
          '/foo/bar/server.incremental.dart.dill',
        ];
        expect(await starter(args, compiler: compiler), 0);
        final List<dynamic> capturedArgs = verify(compiler.compile(
          argThat(equals('server.dart')),
          captureAny,
          generator: anyNamed('generator'),
        )).captured;
        expect(capturedArgs.single['sdk-root'], equals('sdkroot'));
      });
    });
  });

  group('full compiler tests', () {
    final platformKernel =
        computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
    final ddcPlatformKernel =
        computePlatformBinariesLocation().resolve('ddc_outline_sound.dill');
    final ddcPlatformKernelWeak =
        computePlatformBinariesLocation().resolve('ddc_sdk.dill');
    final sdkRoot = computePlatformBinariesLocation();

    Directory tempDir;
    setUp(() {
      var systemTempDir = Directory.systemTemp;
      tempDir = systemTempDir.createTempSync('frontendServerTest');
      new Directory('${tempDir.path}/.dart_tool').createSync();
    });

    tearDown(() {
      tempDir.delete(recursive: true);
    });

    test('compile expression', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n}\n");
      var dillFile = File('${tempDir.path}/app.dill');

      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // First request is to 'compile', which results in full kernel file.
          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);
          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);
          count += 1;
        } else if (count == 2) {
          expect(result.errorsCount, equals(0));
          // Second request is to 'compile-expression', which results in
          // kernel file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          expect(outputFile.existsSync(), equals(true));
          expect(outputFile.lengthSync(), isPositive);

          streamController.add('compile foo.bar\n'.codeUnits);
          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);
        }
      });

      expect(await result, 0);
      expect(count, 3);
    });

    test('mixed compile expression commands with non-web target', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {}\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}'
      ];

      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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // First request is to 'compile', which results in full kernel file.
          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\n'
                  '2+2\nabc\nabc\n${file.uri}\n\nfalse\n'
              .codeUnits);
          count += 1;
        } else if (count == 1) {
          expect(result.errorsCount, equals(0));
          // Second request is to 'compile-expression', which results in
          // kernel file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          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);
          count += 1;
        } else if (count == 2) {
          // Third request is to 'compile-expression-to-js' that fails
          // due to non-web target
          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);
          count += 1;
        } else if (count == 3) {
          expect(result.errorsCount, equals(0));
          // Fourth request is to 'compile-expression', which results in
          // kernel file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          expect(outputFile.existsSync(), equals(true));
          expect(outputFile.lengthSync(), isPositive);

          streamController.add('quit\n'.codeUnits);
        }
      });

      expect(await result, 0);
      expect(count, 3);
    });

    test('compiler reports correct sources added', () async {
      var libFile = File('${tempDir.path}/lib.dart')
        ..createSync(recursive: true)
        ..writeAsStringSync("var foo = 42;");
      var mainFile = File('${tempDir.path}/main.dart')
        ..createSync(recursive: true)
        ..writeAsStringSync("main() => print('foo');\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--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);
      int count = 0;
      receivedResults.stream.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);
          mainFile
              .writeAsStringSync("import 'lib.dart';  main() => print(foo);\n");
          inputStreamController.add('recompile ${mainFile.path} abc\n'
                  '${mainFile.uri}\n'
                  'abc\n'
              .codeUnits);
          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);
        }
      });

      expect(await result, 0);
      inputStreamController.close();
    }, timeout: Timeout.factor(100));

    test('compiler reports correct sources removed', () async {
      var libFile = File('${tempDir.path}/lib.dart')
        ..createSync(recursive: true)
        ..writeAsStringSync("var foo = 42;");
      var mainFile = File('${tempDir.path}/main.dart')
        ..createSync(recursive: true)
        ..writeAsStringSync("import 'lib.dart'; main() => print(foo);\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--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);
      int count = 0;
      receivedResults.stream.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);
          mainFile.writeAsStringSync("main() => print('foo');\n");
          inputStreamController.add('recompile ${mainFile.path} abc\n'
                  '${mainFile.uri}\n'
                  'abc\n'
              .codeUnits);
          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);
        }
      });

      expect(await result, 0);
      inputStreamController.close();
    }, timeout: Timeout.factor(100));

    test('compile expression when delta is rejected', () async {
      var fileLib = File('${tempDir.path}/lib.dart')..createSync();
      fileLib.writeAsStringSync("foo() => 42;\n");
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("import 'lib.dart'; main1() => print(foo);\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // First request was to 'compile', which resulted in full kernel file.
          expect(result.errorsCount, 0);
          expect(dillFile.existsSync(), equals(true));
          expect(result.filename, dillFile.path);
          inputStreamController.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;
          inputStreamController.add('''
compile-expression abc
main1
abc
abc
${file.uri}

true
'''
              .codeUnits);
          count += 1;
        } else if (count == 1) {
          // Second request was to 'compile-expression', which resulted in
          // kernel file with a function that wraps compiled expression.
          expect(result.errorsCount, 0);
          File outputFile = File(result.filename);
          expect(outputFile.existsSync(), equals(true));
          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);

          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);
          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);
          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);
        }
      });

      expect(await result, 0);
      inputStreamController.close();
    }, timeout: Timeout.factor(100));

    test('recompile request keeps incremental output dill filename', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {}\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--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);
      int count = 0;
      receivedResults.stream.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);
          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);
        } else {
          expect(count, 1);
          // Second request is to 'recompile', which results in incremental
          // kernel file.
          var dillIncFile = File('${dillFile.path}.incremental.dill');
          compiledResult.expectNoErrors(filename: dillIncFile.path);
          expect(dillIncFile.existsSync(), equals(true));
          inputStreamController.add('quit\n'.codeUnits);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test(
        'recompile request with flutter widget cache outputs change in class name',
        () async {
      var frameworkDirectory = Directory('${tempDir.path}/flutter');
      var flutterFramework =
          File('${frameworkDirectory.path}/lib/src/widgets/framework.dart')
            ..createSync(recursive: true);
      flutterFramework.writeAsStringSync('''
abstract class Widget {}
class StatelessWidget extends Widget {}
class StatefulWidget extends Widget {}
class State<T extends StatefulWidget> {}
''');

      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";

void main() {}

class FooWidget extends StatelessWidget {}

class FizzWidget extends StatefulWidget {}

class BarState extends State<FizzWidget> {}
""");
      var config = File('${tempDir.path}/package_config.json')..createSync();
      config.writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "flutter",
      "rootUri": "${frameworkDirectory.uri}",
      "packageUri": "lib/"
    }
  ]
}
''');

      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--flutter-widget-cache',
        '--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);
      int count = 0;
      receivedResults.stream.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);
          file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";

void main() {}

class FooWidget extends StatelessWidget {
  // Added.
}

class FizzWidget extends StatefulWidget {}

class BarState extends State<FizzWidget> {}
""");
          inputStreamController.add('recompile ${file.path} abc\n'
                  '${file.uri}\n'
                  'abc\n'
              .codeUnits);
        } else if (count == 1) {
          expect(count, 1);
          // Second request is to 'recompile', which results in incremental
          // kernel file and invalidation of StatelessWidget.
          var dillIncFile = File('${dillFile.path}.incremental.dill');
          var widgetCacheFile =
              File('${dillFile.path}.incremental.dill.widget_cache');
          compiledResult.expectNoErrors(filename: dillIncFile.path);
          expect(dillIncFile.existsSync(), equals(true));
          expect(widgetCacheFile.existsSync(), equals(true));
          expect(widgetCacheFile.readAsStringSync(), 'FooWidget');
          count += 1;
          inputStreamController.add('accept\n'.codeUnits);

          file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";

void main() {}

class FooWidget extends StatelessWidget {
  // Added.
}

class FizzWidget extends StatefulWidget {
  // Added.
}

class BarState extends State<FizzWidget> {}
""");
          inputStreamController.add('recompile ${file.path} abc\n'
                  '${file.uri}\n'
                  'abc\n'
              .codeUnits);
        } else if (count == 2) {
          // Second request is to 'recompile', which results in incremental
          // kernel file and invalidation of StatelessWidget.
          var dillIncFile = File('${dillFile.path}.incremental.dill');
          var widgetCacheFile =
              File('${dillFile.path}.incremental.dill.widget_cache');
          compiledResult.expectNoErrors(filename: dillIncFile.path);
          expect(dillIncFile.existsSync(), equals(true));
          expect(widgetCacheFile.existsSync(), equals(true));
          expect(widgetCacheFile.readAsStringSync(), 'FizzWidget');
          count += 1;
          inputStreamController.add('accept\n'.codeUnits);

          file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";

void main() {}

class FooWidget extends StatelessWidget {
  // Added.
}

class FizzWidget extends StatefulWidget {
  // Added.
}

class BarState extends State<FizzWidget> {
  // Added.
}
""");
          inputStreamController.add('recompile ${file.path} abc\n'
                  '${file.uri}\n'
                  'abc\n'
              .codeUnits);
        } else if (count == 3) {
          // Third request is to 'recompile', which results in incremental
          // kernel file and invalidation of State class.
          var dillIncFile = File('${dillFile.path}.incremental.dill');
          var widgetCacheFile =
              File('${dillFile.path}.incremental.dill.widget_cache');
          compiledResult.expectNoErrors(filename: dillIncFile.path);
          expect(dillIncFile.existsSync(), equals(true));
          expect(widgetCacheFile.existsSync(), equals(true));
          expect(widgetCacheFile.readAsStringSync(), 'FizzWidget');
          count += 1;
          inputStreamController.add('accept\n'.codeUnits);

          file.writeAsStringSync("""
import "package:flutter/src/widgets/framework.dart";

void main() {}

// Added

class FooWidget extends StatelessWidget {
  // Added.
}

class FizzWidget extends StatefulWidget {
  // Added.
}

class BarState extends State<FizzWidget> {
  // Added.
}
""");
          inputStreamController.add('recompile ${file.path} abc\n'
                  '${file.uri}\n'
                  'abc\n'
              .codeUnits);
        } else if (count == 4) {
          // Fourth request is to 'recompile', which results in incremental
          // kernel file and no widget cache
          var dillIncFile = File('${dillFile.path}.incremental.dill');
          var widgetCacheFile =
              File('${dillFile.path}.incremental.dill.widget_cache');
          compiledResult.expectNoErrors(filename: dillIncFile.path);
          expect(dillIncFile.existsSync(), equals(true));
          expect(widgetCacheFile.existsSync(), equals(false));
          inputStreamController.add('quit\n'.codeUnits);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test('unsafe-package-serialization', () async {
      // Package A.
      var file = File('${tempDir.path}/pkgA/a.dart')
        ..createSync(recursive: true);
      file.writeAsStringSync("pkgA() {}");

      // Package B.
      file = File('${tempDir.path}/pkgB/a.dart')..createSync(recursive: true);
      file.writeAsStringSync("pkgB_a() {}");
      file = File('${tempDir.path}/pkgB/b.dart')..createSync(recursive: true);
      file.writeAsStringSync("import 'package:pkgA/a.dart';"
          "pkgB_b() { pkgA(); }");

      // Application.
      File('${tempDir.path}/app/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "pkgA",
        "rootUri": "${tempDir.uri.resolve('pkgA')}",
        "packageUri": "./"
      },
      {
        "name": "pkgB",
        "rootUri": "${tempDir.uri.resolve('pkgB')}",
        "packageUri": "./"
      }
    ]
  }
''');
      // Entry point A uses both package A and B.
      file = File('${tempDir.path}/app/a.dart')..createSync(recursive: true);
      file.writeAsStringSync("import 'package:pkgB/b.dart';"
          "import 'package:pkgB/a.dart';"
          "appA() { pkgB_a(); pkgB_b(); }");

      // Entry point B uses only package B.
      var fileB = File('${tempDir.path}/app/B.dart')
        ..createSync(recursive: true);
      fileB.writeAsStringSync("import 'package:pkgB/a.dart';"
          "appB() { pkgB_a(); }");

      // Other setup.
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));

      // First compile app entry point A.
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--unsafe-package-serialization',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        switch (count) {
          case 0:
            expect(dillFile.existsSync(), equals(true));
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);
            count += 1;
            inputStreamController.add('accept\n'.codeUnits);
            inputStreamController.add('reset\n'.codeUnits);

            inputStreamController.add('recompile ${fileB.path} abc\n'
                    '${fileB.uri}\n'
                    'abc\n'
                .codeUnits);
            break;
          case 1:
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);
            inputStreamController.add('quit\n'.codeUnits);

            // Loadable.
            Component component = loadComponentFromBinary(dillFile.path);

            // Contains (at least) the 2 files we want.
            expect(
                component.libraries
                    .where((l) =>
                        l.importUri.toString() == "package:pkgB/a.dart" ||
                        l.fileUri == fileB.uri)
                    .length,
                2);

            // Verifiable (together with the platform file).
            component =
                loadComponentFromBinary(platformKernel.toFilePath(), component);
            verifyComponent(component);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test('incremental-serialization', () async {
      // Package A.
      var file = File('${tempDir.path}/pkgA/a.dart')
        ..createSync(recursive: true);
      file.writeAsStringSync("pkgA() {}");

      // Package B.
      file = File('${tempDir.path}/pkgB/a.dart')..createSync(recursive: true);
      file.writeAsStringSync("pkgB_a() {}");
      file = File('${tempDir.path}/pkgB/b.dart')..createSync(recursive: true);
      file.writeAsStringSync("import 'package:pkgA/a.dart';"
          "pkgB_b() { pkgA(); }");

      // Application.
      File('${tempDir.path}/app/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "pkgA",
        "rootUri": "${tempDir.uri.resolve('pkgA')}",
        "packageUri": "./"
      },
      {
        "name": "pkgB",
        "rootUri": "${tempDir.uri.resolve('pkgB')}",
        "packageUri": "./"
      }
    ]
  }
''');
      file = File('${tempDir.path}/app/.dart_tool/package_config.json')
        ..createSync(recursive: true);
      file.writeAsStringSync(jsonEncode({
        "configVersion": 2,
        "packages": [
          {
            "name": "pkgA",
            "rootUri": "../../pkgA",
          },
          {
            "name": "pkgB",
            "rootUri": "../../pkgB",
          },
        ],
      }));

      // Entry point A uses both package A and B.
      file = File('${tempDir.path}/app/a.dart')..createSync(recursive: true);
      file.writeAsStringSync("import 'package:pkgB/b.dart';"
          "import 'package:pkgB/a.dart';"
          "appA() { pkgB_a(); pkgB_b(); }");

      // Entry point B uses only package B.
      var fileB = File('${tempDir.path}/app/B.dart')
        ..createSync(recursive: true);
      fileB.writeAsStringSync("import 'package:pkgB/a.dart';"
          "appB() { pkgB_a(); }");

      // Other setup.
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));

      // First compile app entry point A.
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        switch (count) {
          case 0:
            expect(dillFile.existsSync(), equals(true));
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);
            count += 1;
            inputStreamController.add('accept\n'.codeUnits);
            inputStreamController.add('reset\n'.codeUnits);

            inputStreamController.add('recompile ${fileB.path} abc\n'
                    '${fileB.uri}\n'
                    'abc\n'
                .codeUnits);
            break;
          case 1:
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);
            inputStreamController.add('quit\n'.codeUnits);

            // Loadable.
            Component component = loadComponentFromBinary(dillFile.path);

            // Contains (at least) the 2 files we want.
            expect(
                component.libraries
                    .where((l) =>
                        l.importUri.toString() == "package:pkgB/a.dart" ||
                        l.fileUri == fileB.uri)
                    .length,
                2);

            // Verifiable (together with the platform file).
            component =
                loadComponentFromBinary(platformKernel.toFilePath(), component);
            verifyComponent(component);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test('incremental-serialization with reject', () async {
      // Basically a reproduction of
      // https://github.com/flutter/flutter/issues/44384.
      var file = File('${tempDir.path}/pkgA/.dart_tool/package_config.json')
        ..createSync(recursive: true);
      file.writeAsStringSync(jsonEncode({
        "configVersion": 2,
        "packages": [
          {
            "name": "pkgA",
            "rootUri": "..",
          },
        ],
      }));
      file = File('${tempDir.path}/pkgA/a.dart')..createSync(recursive: true);
      file.writeAsStringSync("pkgA() {}");

      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        switch (count) {
          case 0:
            expect(dillFile.existsSync(), equals(true));
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);

            // Loadable.
            Component component = loadComponentFromBinary(dillFile.path);

            // Contain the file we want.
            var libs = component.libraries
                .where((l) => l.importUri.toString() == "package:pkgA/a.dart");
            expect(libs.length, 1);

            // Has 1 procedure.
            expect(libs.first.procedures.length, 1);

            file.writeAsStringSync("pkgA() {} pkgA_2() {}");

            count += 1;
            outputParser.expectSources = false;
            inputStreamController.add('reject\n'.codeUnits);
            break;
          case 1:
            count += 1;
            inputStreamController.add('reset\n'.codeUnits);
            inputStreamController.add('recompile ${file.path} abc\n'
                    '${file.uri}\n'
                    'abc\n'
                .codeUnits);
            break;
          case 2:
            expect(dillFile.existsSync(), equals(true));
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);

            // Loadable.
            Component component = loadComponentFromBinary(dillFile.path);

            // Contain the file we want.
            var libs = component.libraries
                .where((l) => l.importUri.toString() == "package:pkgA/a.dart");
            expect(libs.length, 1);

            // Has 2 procedure.
            expect(libs.first.procedures.length, 2);

            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);
            break;
          case 3:
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 0);
            inputStreamController.add('quit\n'.codeUnits);

            // Loadable.
            Component component = loadComponentFromBinary(dillFile.path);

            // Contain the file we want.
            var libs = component.libraries
                .where((l) => l.importUri.toString() == "package:pkgA/a.dart");
            expect(libs.length, 1);

            // Has 3 procedures.
            expect(libs.first.procedures.length, 3);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test('compile and recompile report non-zero error count', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() { foo(); bar(); }\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        switch (count) {
          case 0:
            expect(dillFile.existsSync(), equals(true));
            expect(result.filename, dillFile.path);
            expect(result.errorsCount, 2);
            count += 1;
            inputStreamController.add('accept\n'.codeUnits);
            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);
            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);
            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);
            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);
        }
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    test('compile and recompile with MultiRootFileSystem', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {}\n");
      File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync()
        ..writeAsStringSync('{"configVersion": 2, "packages": []}');
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--packages=test-scheme:///.dart_tool/package_config.json',
        '--filesystem-root=${tempDir.path}',
        '--filesystem-scheme=test-scheme',
        'test-scheme:///foo.dart'
      ];
      expect(await starter(args), 0);
    });

    test('compile multiple sources', () async {
      final src1 = File('${tempDir.path}/src1.dart')
        ..createSync()
        ..writeAsStringSync("main() {}\n");
      final src2 = File('${tempDir.path}/src2.dart')
        ..createSync()
        ..writeAsStringSync("entryPoint2() {}\n");
      final src3 = File('${tempDir.path}/src3.dart')
        ..createSync()
        ..writeAsStringSync("entryPoint3() {}\n");
      final packagesFile =
          File('${tempDir.path}/.dart_tool/package_config.json')
            ..createSync()
            ..writeAsStringSync('{"configVersion": 2, "packages": []}');
      final dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--packages=${packagesFile.path}',
        '--source=${src2.path}',
        '--source=${src3.path}',
        '--platform=${platformKernel.path}',
        '--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) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        expect(dillFile.existsSync(), equals(true));
        expect(result.filename, dillFile.path);
        expect(result.errorsCount, 0);

        final component = loadComponentFromBinary(dillFile.path);
        // Contains (at least) the 3 files we want.
        final srcUris = {src1.uri, src2.uri, src3.uri};
        expect(
            component.libraries
                .where((lib) => srcUris.contains(lib.fileUri))
                .length,
            srcUris.length);
        inputStreamController.add('quit\n'.codeUnits);
      });
      expect(await result, 0);
      inputStreamController.close();
    });

    group('http uris', () {
      var host = 'localhost';
      File dillFile;
      int port;
      HttpServer server;

      setUp(() async {
        dillFile = File('${tempDir.path}/app.dill');
        server = await HttpServer.bind(host, 0);
        port = server.port;
        server.listen((request) {
          var path = request.uri.path;
          var file = File('${tempDir.path}$path');
          var response = request.response;
          if (!file.existsSync()) {
            response.statusCode = 404;
          } else {
            response.statusCode = 200;
            response.add(file.readAsBytesSync());
          }
          response.close();
        });
        var main = File('${tempDir.path}/foo.dart')..createSync();
        main.writeAsStringSync(
            "import 'package:foo/foo.dart'; main() {print(foo);}\n");
        File('${tempDir.path}/.dart_tool/package_config.json')
          ..createSync(recursive: true)
          ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "foo",
        "rootUri": "http://$host:$port/packages/foo",
        "packageUri": "./"
      }
    ]
  }
''');
        File('${tempDir.path}/packages/foo/foo.dart')
          ..createSync(recursive: true)
          ..writeAsStringSync("var foo = 'hello';");
      });

      tearDown(() async {
        await server.close();
        print('closed');
      });

      test('compile with http uris', () async {
        expect(dillFile.existsSync(), equals(false));
        final List<String> args = <String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--incremental',
          '--platform=${platformKernel.path}',
          '--output-dill=${dillFile.path}',
          '--enable-http-uris',
          '--packages=http://$host:$port/.dart_tool/package_config.json',
          'http://$host:$port/foo.dart',
        ];
        expect(await starter(args), 0);
        expect(dillFile.existsSync(), equals(true));
      });

      test('compile with an http file system root', () async {
        expect(dillFile.existsSync(), equals(false));
        final List<String> args = <String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--incremental',
          '--platform=${platformKernel.path}',
          '--output-dill=${dillFile.path}',
          '--enable-http-uris',
          '--packages=test-app:///.dart_tool/package_config.json',
          '--filesystem-root=http://$host:$port/',
          '--filesystem-scheme=test-app',
          'test-app:///foo.dart',
        ];
        expect(await starter(args), 0);
        expect(dillFile.existsSync(), equals(true));
      });
    });

    group('binary protocol', () {
      var fileContentMap = <Uri, String>{};

      setUp(() {
        fileContentMap = {};
      });

      void addFileCallbacks(RequestChannel requestChannel) {
        requestChannel.add('file.exists', (uriStr) async {
          final uri = Uri.parse(uriStr as String);
          return fileContentMap.containsKey(uri);
        });
        requestChannel.add('file.readAsBytes', (uriStr) async {
          final uri = Uri.parse(uriStr as String);
          final content = fileContentMap[uri];
          return content != null ? utf8.encode(content) : Uint8List(0);
        });
        requestChannel.add('file.readAsStringSync', (uriStr) async {
          final uri = Uri.parse(uriStr as String);
          return fileContentMap[uri] ?? '';
        });
      }

      Future<ServerSocket> loopbackServerSocket() async {
        try {
          return await ServerSocket.bind(InternetAddress.loopbackIPv6, 0);
        } on SocketException catch (_) {
          return await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
        }
      }

      Uri registerKernelBlob(Uint8List bytes) {
        bytes = Uint8List.fromList(bytes);
        return (Isolate.current as dynamic).createUriForKernelBlob(bytes);
      }

      Future<void> runWithServer(
        Future<void> Function(RequestChannel) f,
      ) async {
        final testFinished = Completer<void>();
        final serverSocket = await loopbackServerSocket();

        serverSocket.listen((socket) async {
          final requestChannel = RequestChannel(socket);

          try {
            await f(requestChannel);
          } finally {
            requestChannel.sendRequest('stop', {});
            socket.destroy();
            serverSocket.close();
            testFinished.complete();
          }
        });

        final host = serverSocket.address.address;
        final addressStr = '$host:${serverSocket.port}';
        expect(await starter(['--binary-protocol-address=${addressStr}']), 0);

        await testFinished.future;
      }

      group('dill.put', () {
        test('not Map argument', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('dill.put', 42);
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('no field: uri', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('dill.put', {});
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('no field: bytes', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('dill.put', {
                'uri': 'vm:dill',
              });
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('OK', () async {
          await runWithServer((requestChannel) async {
            await requestChannel.sendRequest<Uint8List>('dill.put', {
              'uri': 'vm:dill',
              'bytes': Uint8List(256),
            });
          });
        });
      });

      group('dill.remove', () {
        test('not Map argument', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('dill.remove', 42);
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('no field: uri', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('dill.remove', {});
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('OK', () async {
          await runWithServer((requestChannel) async {
            await requestChannel.sendRequest<Uint8List>('dill.remove', {
              'uri': 'vm:dill',
            });
          });
        });
      });

      group('kernelForProgram', () {
        test('not Map argument', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>(
                'kernelForProgram',
                42,
              );
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('no field: sdkSummary', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>(
                'kernelForProgram',
                {},
              );
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('no field: uri', () async {
          await runWithServer((requestChannel) async {
            try {
              await requestChannel.sendRequest<Uint8List>('kernelForProgram', {
                'sdkSummary': 'dill:vm',
              });
              fail('Expected RemoteException');
            } on RemoteException {}
          });
        });

        test('compiles', () async {
          await runWithServer((requestChannel) async {
            addFileCallbacks(requestChannel);

            await requestChannel.sendRequest<void>('dill.put', {
              'uri': 'dill:vm',
              'bytes': File(
                path.join(
                  path.dirname(path.dirname(Platform.resolvedExecutable)),
                  'lib',
                  '_internal',
                  'vm_platform_strong.dill',
                ),
              ).readAsBytesSync(),
            });

            fileContentMap[Uri.parse('file:///home/test/lib/test.dart')] = r'''
import 'dart:isolate';
void main(List<String> arguments, SendPort sendPort) {
  sendPort.send(42);
}
''';

            final kernelBytes = await requestChannel.sendRequest<Uint8List>(
              'kernelForProgram',
              {
                'sdkSummary': 'dill:vm',
                'uri': 'file:///home/test/lib/test.dart',
              },
            );

            expect(kernelBytes, hasLength(greaterThan(200)));
            final kernelUri = registerKernelBlob(kernelBytes);

            final receivePort = ReceivePort();
            await Isolate.spawnUri(kernelUri, [], receivePort.sendPort);
            expect(await receivePort.first, 42);
          });
        });
      });
    });

    test('compile to JavaScript', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n}\n");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');
      var dillFile = File('${tempDir.path}/app.dill');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--packages=${packageConfig.path}',
        '--target=dartdevc',
        file.path,
      ];

      expect(await starter(args), 0);
    });

    test('compile to JavaScript with package scheme', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n}\n");
      var packages = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync()
        ..writeAsStringSync(jsonEncode({
          "configVersion": 2,
          "packages": [
            {
              "name": "hello",
              "rootUri": "${tempDir.uri}",
            },
          ],
        }));
      var dillFile = File('${tempDir.path}/app.dill');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernelWeak.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--packages=${packages.path}',
        'package:hello/foo.dart'
      ];

      expect(await starter(args), 0);
    }, skip: 'https://github.com/dart-lang/sdk/issues/43959');

    test('compile to JavaScript weak null safety', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
      var packages = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync()
        ..writeAsStringSync(jsonEncode({
          "configVersion": 2,
          "packages": [
            {
              "name": "hello",
              "rootUri": "${tempDir.uri}",
            },
          ],
        }));
      var dillFile = File('${tempDir.path}/app.dill');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernelWeak.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--packages=${packages.path}',
        'package:hello/foo.dart'
      ];

      expect(await starter(args), 0);
    }, skip: 'https://github.com/dart-lang/sdk/issues/43959');

    test('compile to JavaScript weak null safety then non-existent file',
        () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("// @dart = 2.9\nmain() {\n}\n");
      var packages = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync()
        ..writeAsStringSync(jsonEncode({
          "configVersion": 2,
          "packages": [
            {
              "name": "hello",
              "rootUri": "${tempDir.uri}",
            },
          ],
        }));
      var dillFile = File('${tempDir.path}/app.dill');

      expect(dillFile.existsSync(), false);

      var library = 'package:hello/foo.dart';

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernelWeak.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      var count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        count++;
        if (count == 1) {
          // 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);
        } 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);
        }
      });

      expect(await result, 0);
      expect(count, 2);
    }, skip: 'https://github.com/dart-lang/sdk/issues/43959');

    test('compile to JavaScript with no metadata', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n\n}\n");

      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      var library = 'package:hello/foo.dart';

      var dillFile = File('${tempDir.path}/app.dill');
      var sourceFile = File('${dillFile.path}.sources');
      var manifestFile = File('${dillFile.path}.json');
      var sourceMapsFile = File('${dillFile.path}.map');
      var metadataFile = File('${dillFile.path}.metadata');

      expect(dillFile.existsSync(), false);
      expect(sourceFile.existsSync(), false);
      expect(manifestFile.existsSync(), false);
      expect(sourceMapsFile.existsSync(), false);
      expect(metadataFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      var count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        count++;
        // Request to 'compile', which results in full JavaScript and no
        // metadata.
        expect(result.errorsCount, equals(0));
        expect(sourceFile.existsSync(), equals(true));
        expect(manifestFile.existsSync(), equals(true));
        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);
      });

      expect(await result, 0);
      expect(count, 1);
    });

    test('compile to JavaScript with metadata', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n\n}\n");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      var library = 'package:hello/foo.dart';

      var dillFile = File('${tempDir.path}/app.dill');
      var sourceFile = File('${dillFile.path}.sources');
      var manifestFile = File('${dillFile.path}.json');
      var sourceMapsFile = File('${dillFile.path}.map');
      var metadataFile = File('${dillFile.path}.metadata');
      var symbolsFile = File('${dillFile.path}.symbols');

      expect(dillFile.existsSync(), false);
      expect(sourceFile.existsSync(), false);
      expect(manifestFile.existsSync(), false);
      expect(sourceMapsFile.existsSync(), false);
      expect(metadataFile.existsSync(), false);
      expect(symbolsFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--packages=${packageConfig.path}',
        '--experimental-emit-debug-metadata',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        count++;
        // Request to 'compile', which results in full JavaScript and metadata.
        expect(result.errorsCount, equals(0));
        expect(sourceFile.existsSync(), equals(true));
        expect(manifestFile.existsSync(), equals(true));
        expect(sourceMapsFile.existsSync(), equals(true));
        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);
      });

      expect(await result, 0);
      expect(count, 1);
    });

    test('compile to JavaScript all modules with unsound null safety',
        () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("import 'bar.dart'; "
          "typedef myType = void Function(int); main() { fn is myType; }\n");
      file = File('${tempDir.path}/bar.dart')..createSync();
      file.writeAsStringSync("void Function(int) fn = (int i) => null;\n");
      var library = 'package:hello/foo.dart';

      var dillFile = File('${tempDir.path}/app.dill');
      var sourceFile = File('${dillFile.path}.sources');

      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
    {
      "configVersion": 2,
      "packages": [
        {
          "name": "hello",
          "rootUri": "../",
          "packageUri": "./",
          "languageVersion": "2.9"
        }
      ]
    }
    ''');

      final List<String> args = <String>[
        '--verbose',
        '--no-sound-null-safety',
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernelWeak.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      var count = 0;
      var expectationCompleter = Completer<bool>();
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        count++;
        // Request to 'compile', which results in full JavaScript and no
        // metadata.
        expect(result.errorsCount, equals(0));
        expect(sourceFile.existsSync(), equals(true));
        expect(result.filename, dillFile.path);

        var source = sourceFile.readAsStringSync();
        // Split on the comment at the end of each module.
        var jsModules = source.split(RegExp("\/\/# sourceMappingURL=.*\.map"));

        // Both modules should include the unsound null safety check.
        expect(
            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);
        expectationCompleter.complete(true);
      });

      await expectationCompleter.future;
      expect(await result, 0);
      expect(count, 1);
    }, timeout: Timeout.none);

    test('compile to JavaScript, all modules with sound null safety', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync(
          "import 'bar.dart'; typedef myType = void Function(int); "
          "main() { fn is myType; }\n");
      file = File('${tempDir.path}/bar.dart')..createSync();
      file.writeAsStringSync("void Function(int) fn = (int i) => null;\n");

      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
    {
      "configVersion": 2,
      "packages": [
        {
          "name": "hello",
          "rootUri": "../",
          "packageUri": "./"
        }
      ]
    }
    ''');

      var library = 'package:hello/foo.dart';

      var dillFile = File('${tempDir.path}/app.dill');
      var sourceFile = File('${dillFile.path}.sources');

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      var count = 0;
      var expectationCompleter = Completer<bool>();
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        count++;
        // Request to 'compile', which results in full JavaScript and no
        // metadata.
        expect(result.errorsCount, equals(0));
        expect(sourceFile.existsSync(), equals(true));
        expect(result.filename, dillFile.path);

        var source = sourceFile.readAsStringSync();
        // Split on the comment at the end of each module.
        var jsModules = source.split(RegExp("\/\/# sourceMappingURL=.*\.map"));

        // Both modules should include the sound null safety validation.
        expect(
            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);
        expectationCompleter.complete(true);
      });

      await expectationCompleter.future;
      expect(await result, 0);
      expect(count, 1);
    });

    test('compile expression to Javascript', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n}\n");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      var library = 'package:hello/foo.dart';
      var module = 'packages/hello/foo.dart';

      var dillFile = File('${tempDir.path}/foo.dart.dill');
      var sourceFile = File('${dillFile.path}.sources');
      var manifestFile = File('${dillFile.path}.json');
      var sourceMapsFile = File('${dillFile.path}.map');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // First request is to 'compile', which results in full JavaScript
          expect(result.errorsCount, equals(0));
          expect(sourceFile.existsSync(), equals(true));
          expect(manifestFile.existsSync(), equals(true));
          expect(sourceMapsFile.existsSync(), equals(true));
          expect(result.filename, dillFile.path);
          streamController.add('accept\n'.codeUnits);

          // '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);
          count += 1;
        } else if (count == 1) {
          // Second request is to 'compile-expression-to-js' that fails
          // due to incorrect input - empty expression
          expect(result.errorsCount, 1);
          expect(compiledResult.status, (String status) {
            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);
          count += 1;
        } else if (count == 2) {
          expect(result.errorsCount, equals(0));
          // Third request is to 'compile-expression-to-js', which results in
          // js file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          expect(outputFile.existsSync(), equals(true));
          expect(outputFile.lengthSync(), isPositive);

          streamController.add('compile foo.bar\n'.codeUnits);
          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);
        }
      });

      expect(await result, 0);
      expect(count, 3);
    });

    test('compiled Javascript includes web library environment defines',
        () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync(
          "main() {print(const bool.fromEnvironment('dart.library.html'));}\n");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      var library = 'package:hello/foo.dart';
      var module = 'packages/hello/foo.dart';

      var dillFile = File('${tempDir.path}/foo.dart.dill');
      var sourceFile = File('${dillFile.path}.sources');
      var manifestFile = File('${dillFile.path}.json');
      var sourceMapsFile = File('${dillFile.path}.map');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // Request to 'compile', which results in full JavaScript.
          expect(result.errorsCount, equals(0));
          expect(sourceFile.existsSync(), equals(true));
          expect(manifestFile.existsSync(), equals(true));
          expect(sourceMapsFile.existsSync(), equals(true));
          expect(result.filename, dillFile.path);

          var compiledOutput = sourceFile.readAsStringSync();
          // The constant environment variable should be inlined as a boolean
          // literal.
          expect(compiledOutput, contains('print(true);'));

          streamController.add('accept\n'.codeUnits);

          // '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);
          count += 1;
        } else {
          expect(count, 1);
          // Second request is to 'compile-expression-to-js' that should
          // result in a literal `true` .
          expect(result.errorsCount, 0);
          var resultFile = File(result.filename);
          // 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);
        }
      });
      expect(await result, 0);
      expect(count, 2);
    });

    test('mixed compile expression commands with web target', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {\n\n}\n");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');
      var library = 'package:hello/foo.dart';
      var module = 'packages/hello/foo.dart';

      var dillFile = File('${tempDir.path}/foo.dart.dill');
      var sourceFile = File('${dillFile.path}.sources');
      var manifestFile = File('${dillFile.path}.json');
      var sourceMapsFile = File('${dillFile.path}.map');

      expect(dillFile.existsSync(), false);

      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${ddcPlatformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--target=dartdevc',
        '--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);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        CompilationResult result =
            CompilationResult.parse(compiledResult.status);
        if (count == 0) {
          // First request is to 'compile', which results in full JavaScript
          expect(result.errorsCount, equals(0));
          expect(sourceFile.existsSync(), equals(true));
          expect(manifestFile.existsSync(), equals(true));
          expect(sourceMapsFile.existsSync(), equals(true));
          expect(result.filename, dillFile.path);
          streamController.add('accept\n'.codeUnits);

          // '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);
          count += 1;
        } else if (count == 1) {
          expect(result.errorsCount, equals(0));
          // Second request is to 'compile-expression-to-js', which results in
          // js file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          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);
          count += 1;
        } else if (count == 2) {
          expect(result.errorsCount, equals(0));
          // Third request is to 'compile-expression', which results in
          // kernel file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          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);
          count += 1;
        } else if (count == 3) {
          expect(result.errorsCount, equals(0));
          // Fourth request is to 'compile-expression-to-js', which results in
          // js file with a function that wraps compiled expression.
          File outputFile = File(result.filename);
          expect(outputFile.existsSync(), equals(true));
          expect(outputFile.lengthSync(), isPositive);

          streamController.add('quit\n'.codeUnits);
        }
      });

      expect(await result, 0);
      expect(count, 3);
    });

    test('compile "package:"-file', () async {
      Directory lib = Directory('${tempDir.path}/lib')..createSync();
      File('${lib.path}/foo.dart')
        ..createSync()
        ..writeAsStringSync("main() {}\n");
      File packages = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync()
        ..writeAsStringSync(jsonEncode({
          "configVersion": 2,
          "packages": [
            {
              "name": "test",
              "rootUri": "../lib",
            },
          ],
        }));
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      var depFile = File('${tempDir.path}/the depfile');
      expect(depFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--depfile=${depFile.path}',
        '--packages=${packages.path}',
        'package:test/foo.dart'
      ];
      expect(await starter(args), 0);
      expect(depFile.existsSync(), true);
      var depContents = depFile.readAsStringSync();
      var depContentsParsed = depContents.split(': ');
      expect(path.basename(depContentsParsed[0]), path.basename(dillFile.path));
      expect(depContentsParsed[1], isNotEmpty);
    });

    test('compile and produce deps file', () async {
      var file = File('${tempDir.path}/foo.dart')..createSync();
      file.writeAsStringSync("main() {}\n");
      var dillFile = File('${tempDir.path}/app.dill');
      expect(dillFile.existsSync(), equals(false));
      var depFile = File('${tempDir.path}/the depfile');
      expect(depFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--depfile=${depFile.path}',
        file.path
      ];
      expect(await starter(args), 0);
      expect(depFile.existsSync(), true);
      var depContents = depFile.readAsStringSync();
      var depContentsParsed = depContents.split(': ');
      expect(path.basename(depContentsParsed[0]), path.basename(dillFile.path));
      expect(depContentsParsed[1], isNotEmpty);
    });

    void checkIsEqual(List<int> a, List<int> b) {
      int length = a.length;
      if (b.length < length) {
        length = b.length;
      }
      for (int i = 0; i < length; ++i) {
        if (a[i] != b[i]) {
          fail("Data differs at byte ${i + 1}.");
        }
      }
      expect(a.length, equals(b.length));
    }

    test('mimic flutter benchmark', () async {
      // This is based on what flutters "hot_mode_dev_cycle__benchmark" does.
      var dillFile = File('${tempDir.path}/full.dill');
      var incrementalDillFile = File('${tempDir.path}/incremental.dill');
      expect(dillFile.existsSync(), equals(false));
      final List<String> args = <String>[
        '--sdk-root=${sdkRoot.toFilePath()}',
        '--incremental',
        '--platform=${platformKernel.path}',
        '--output-dill=${dillFile.path}',
        '--output-incremental-dill=${incrementalDillFile.path}'
      ];
      File dart2js = File.fromUri(
          Platform.script.resolve("../../../pkg/compiler/bin/dart2js.dart"));
      expect(dart2js.existsSync(), equals(true));
      File dart2jsOtherFile = File.fromUri(Platform.script
          .resolve("../../../pkg/compiler/lib/src/compiler.dart"));
      expect(dart2jsOtherFile.existsSync(), equals(true));

      int libraryCount = -1;
      int sourceCount = -1;

      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);
        int count = 0;
        receivedResults.stream.listen((Result compiledResult) {
          CompilationResult result =
              CompilationResult.parse(compiledResult.status);
          String outputFilename = result.filename;
          print("$outputFilename -- count $count");

          // Ensure that kernel file produced when compiler was initialized
          // from compiled kernel files matches kernel file produced when
          // compiler was initialized from sources on the first run.
          if (serverCloses == 0) {
            compiledKernels.add(File(dillFile.path).readAsBytesSync());
          } else {
            checkIsEqual(
                compiledKernels[count], File(dillFile.path).readAsBytesSync());
          }
          if (count == 0) {
            // First request is to 'compile', which results in full kernel file.
            expect(dillFile.existsSync(), equals(true));
            expect(outputFilename, dillFile.path);

            // Dill file can be loaded and includes data.
            Component component = loadComponentFromBinary(dillFile.path);
            if (serverCloses == 0) {
              libraryCount = component.libraries.length;
              sourceCount = component.uriToSource.length;
              expect(libraryCount > 100, equals(true));
              expect(sourceCount >= libraryCount, equals(true),
                  reason: "Expects >= source entries than libraries.");
            } else {
              expect(component.libraries.length, equals(libraryCount),
                  reason: "Expects the same number of libraries "
                      "when compiling after a restart");
              expect(component.uriToSource.length, equals(sourceCount),
                  reason: "Expects the same number of sources "
                      "when compiling after a restart");
            }

            // Include platform and verify.
            component =
                loadComponentFromBinary(platformKernel.toFilePath(), component);
            expect(component.mainMethod, isNotNull);
            verifyComponent(component);

            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);
          } else if (count == 1) {
            // Restart. Expect full kernel file.
            expect(dillFile.existsSync(), equals(true));
            expect(outputFilename, dillFile.path);

            // Dill file can be loaded and includes data.
            Component component = loadComponentFromBinary(dillFile.path);
            expect(component.libraries.length, equals(libraryCount),
                reason: "Expect the same number of libraries after a reset.");
            expect(component.uriToSource.length, equals(sourceCount),
                reason: "Expect the same number of sources after a reset.");

            // Include platform and verify.
            component =
                loadComponentFromBinary(platformKernel.toFilePath(), component);
            expect(component.mainMethod, isNotNull);
            verifyComponent(component);

            count += 1;

            // Reload with no changes
            inputStreamController.add('accept\n'.codeUnits);
            inputStreamController.add('recompile ${dart2js.path} x$count\n'
                    'x$count\n'
                .codeUnits);
          } else if (count == 2) {
            // Partial file. Expect to be empty.
            expect(incrementalDillFile.existsSync(), equals(true));
            expect(outputFilename, incrementalDillFile.path);

            // Dill file can be loaded and includes no data.
            Component component =
                loadComponentFromBinary(incrementalDillFile.path);
            expect(component.libraries.length, equals(0));

            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);
          } else if (count == 3) {
            // Partial file. Expect to not be empty.
            expect(incrementalDillFile.existsSync(), equals(true));
            expect(outputFilename, incrementalDillFile.path);

            // Dill file can be loaded and includes some data.
            Component component =
                loadComponentFromBinary(incrementalDillFile.path);
            expect(component.libraries, isNotEmpty);
            expect(component.uriToSource.length >= component.libraries.length,
                equals(true),
                reason: "Expects >= source entries than libraries.");

            count += 1;

            inputStreamController.add('quit\n'.codeUnits);
          }
        });
        expect(await result, 0);
        inputStreamController.close();
      }
    }, timeout: Timeout.factor(8));

    test('compile with(out) warning', () async {
      Future runTest({bool hideWarnings}) async {
        var file = File('${tempDir.path}/foo.dart')..createSync();
        file.writeAsStringSync("""
main() {}
method(int i) => i?.isEven;
""");
        var packageConfig =
            File('${tempDir.path}/.dart_tool/package_config.json')
              ..createSync(recursive: true)
              ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "hello",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');
        var dillFile = File('${tempDir.path}/app.dill');

        expect(dillFile.existsSync(), false);

        final List<String> args = <String>[
          '--sdk-root=${sdkRoot.toFilePath()}',
          '--incremental',
          '--platform=${ddcPlatformKernel.path}',
          '--output-dill=${dillFile.path}',
          '--packages=${packageConfig.path}',
          '--target=dartdevc',
          if (hideWarnings) '--verbosity=error',
          file.path,
        ];
        StringBuffer output = new StringBuffer();
        expect(await starter(args, output: output), 0);
        String result = output.toString();
        Matcher matcher =
            contains("Warning: Operand of null-aware operation '?.' "
                "has type 'int' which excludes null.");
        if (hideWarnings) {
          matcher = isNot(matcher);
        }
        expect(result, matcher);

        file.deleteSync();
        dillFile.deleteSync();
      }

      await runTest(hideWarnings: false);
      await runTest(hideWarnings: true);
    });
  });
}

/// Computes the location of platform binaries, that is, compiled `.dill` files
/// of the platform libraries that are used to avoid recompiling those
/// libraries.
Uri computePlatformBinariesLocation() {
  // The directory of the Dart VM executable.
  Uri vmDirectory =
      Uri.base.resolveUri(Uri.file(Platform.resolvedExecutable)).resolve(".");
  if (vmDirectory.path.endsWith("/bin/")) {
    // Looks like the VM is in a `/bin/` directory, so this is running from a
    // built SDK.
    return vmDirectory.resolve("../lib/_internal/");
  } else {
    // We assume this is running from a build directory (for example,
    // `out/ReleaseX64` or `xcodebuild/ReleaseX64`).
    return vmDirectory;
  }
}

class CompilationResult {
  String filename;
  int errorsCount;

  CompilationResult.parse(String filenameAndErrorCount) {
    if (filenameAndErrorCount == null) {
      return;
    }
    int delim = filenameAndErrorCount.lastIndexOf(' ');
    expect(delim > 0, equals(true));
    filename = filenameAndErrorCount.substring(0, delim);
    errorsCount = int.parse(filenameAndErrorCount.substring(delim + 1).trim());
  }
}

class OutputParser {
  bool expectSources = true;
  StreamController<Result> _receivedResults;

  List<String> _receivedSources;
  String _boundaryKey;

  bool _readingSources;
  OutputParser(this._receivedResults);

  void listener(String s) {
    if (_boundaryKey == null) {
      const String RESULT_OUTPUT_SPACE = 'result ';
      if (s.startsWith(RESULT_OUTPUT_SPACE)) {
        _boundaryKey = s.substring(RESULT_OUTPUT_SPACE.length);
      }
      _readingSources = false;
      _receivedSources?.clear();
      return;
    }

    if (s.startsWith(_boundaryKey)) {
      // First boundaryKey separates compiler output from list of sources
      // (if we expect list of sources, which is indicated by receivedSources
      // being not null)
      if (expectSources && !_readingSources) {
        _readingSources = true;
        return;
      }
      // Second boundaryKey indicates end of frontend server response
      expectSources = true;
      _receivedResults.add(Result(
          s.length > _boundaryKey.length
              ? s.substring(_boundaryKey.length + 1)
              : null,
          _receivedSources));
      _boundaryKey = null;
    } else {
      if (_readingSources) {
        if (_receivedSources == null) {
          _receivedSources = <String>[];
        }
        _receivedSources.add(s);
      }
    }
  }
}

class Result {
  String status;
  List<String> sources;

  Result(this.status, this.sources);

  void expectNoErrors({String filename}) {
    var result = CompilationResult.parse(status);
    expect(result.errorsCount, equals(0));
    if (filename != null) {
      expect(result.filename, equals(filename));
    }
  }
}

class _MockedBinaryPrinter extends Mock implements BinaryPrinter {}

class _MockedBinaryPrinterFactory extends Mock implements BinaryPrinterFactory {
}

class _MockedCompiler extends Mock implements CompilerInterface {}

class _MockedIncrementalCompiler extends Mock implements IncrementalCompiler {}
