// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.

// @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:frontend_server/starter.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);
    });

    // This test exercises what happens when a change occurs with a single
    // module of a multi-module compilation.
    test('recompile to JavaScript with in-body change', () async {
      // Five libraries, a to e, in two modules, {a, b} and {c, d, e}:
      //    (a <-> b) -> (c <-> d <-> e)
      // In body changes are performed on d and e. With advanced invalidation,
      // not currently enabled, only the module {c, d, e} will be recompiled.
      File('${tempDir.path}/a.dart')
        ..createSync()
        ..writeAsStringSync("""
import 'b.dart';
main() {
  b();
}
a() => "<<a>>";
""");
      File('${tempDir.path}/b.dart')
        ..createSync()
        ..writeAsStringSync("""
import 'a.dart';
import 'c.dart';
b() {
  a();
  "<<b>>";
  c();
}
""");
      File('${tempDir.path}/c.dart')
        ..createSync()
        ..writeAsStringSync("""
import 'd.dart';
c() {
  "<<c>>";
  d();
}
""");
      var fileD = File('${tempDir.path}/d.dart')
        ..createSync()
        ..writeAsStringSync("""
import 'e.dart';
d() {
  "<<d>>";
  e();
}
""");
      var fileE = File('${tempDir.path}/e.dart')
        ..createSync()
        ..writeAsStringSync("""
import 'c.dart';
e() {
  c();
  "<<e>>";
}
""");
      var packageConfig = File('${tempDir.path}/.dart_tool/package_config.json')
        ..createSync(recursive: true)
        ..writeAsStringSync('''
  {
    "configVersion": 2,
    "packages": [
      {
        "name": "a",
        "rootUri": "../",
        "packageUri": "./"
      }
    ]
  }
  ''');

      var entryPoint = 'package:a/a.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}',
        '--emit-debug-symbols',
      ];

      final StreamController<List<int>> streamController =
          StreamController<List<int>>();
      final StreamController<List<int>> stdoutStreamController =
          StreamController<List<int>>();
      final IOSink ioSink = IOSink(stdoutStreamController.sink);
      StreamController<Result> receivedResults = StreamController<Result>();
      final outputParser = OutputParser(receivedResults);
      stdoutStreamController.stream
          .transform(utf8.decoder)
          .transform(const LineSplitter())
          .listen(outputParser.listener);

      Future<int> result =
          starter(args, input: streamController.stream, output: ioSink);
      streamController.add('compile $entryPoint\n'.codeUnits);
      int count = 0;
      receivedResults.stream.listen((Result compiledResult) {
        switch (count) {
          case 0:
            CompilationResult result =
                CompilationResult.parse(compiledResult.status);
            expect(result.errorsCount, equals(0));
            expect(result.filename, dillFile.path);
            expect(sourceFile.existsSync(), equals(true));

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

            expect(jsModules[0], contains('<<a>>'));
            expect(jsModules[0], contains('<<b>>'));
            expect(jsModules[0], not(contains('<<c>>')));
            expect(jsModules[0], not(contains('<<d>>')));
            expect(jsModules[0], not(contains('<<e>>')));

            expect(jsModules[1], not(contains('<<a>>')));
            expect(jsModules[1], not(contains('<<b>>')));
            expect(jsModules[1], contains('<<c>>'));
            expect(jsModules[1], contains('<<d>>'));
            expect(jsModules[1], contains('<<e>>'));

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

            fileD.writeAsStringSync("""
import 'e.dart';
d() {
  "<<d1>>";
  "<<d2>>";
  e();
}
""");
            // Trigger a recompile that invalidates 'd.dart'. The input uri
            // (a.dart) is passed explicitly.
            streamController.add('recompile ${entryPoint} abc\n'
                    '${fileD.uri}\n'
                    'abc\n'
                .codeUnits);
            break;
          case 1:
            CompilationResult result =
                CompilationResult.parse(compiledResult.status);
            expect(result.errorsCount, equals(0));
            expect(result.filename, '${dillFile.path}.incremental.dill');
            File incrementalSourceFile =
                File('${dillFile.path}.incremental.dill.sources');
            expect(incrementalSourceFile.existsSync(), equals(true));

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

            expect(jsModules[0], not(contains('<<a>>')));
            expect(jsModules[0], not(contains('<<b>>')));
            expect(jsModules[0], contains('<<c>>'));
            expect(jsModules[0], not(contains('<<d>>')));
            expect(jsModules[0], contains('<<d1>>'));
            expect(jsModules[0], contains('<<d2>>'));
            expect(jsModules[0], contains('<<e>>'));

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

            fileE.writeAsStringSync("""
import 'c.dart';
e() {
  c();
  "<<e1>>";
  "<<e2>>";
}
""");
            // Trigger a recompile that invalidates 'd.dart'. The input uri
            // (a.dart) is omitted.
            streamController.add('recompile abc\n'
                    '${fileE.uri}\n'
                    'abc\n'
                .codeUnits);
            break;
            break;
          case 2:
            CompilationResult result =
                CompilationResult.parse(compiledResult.status);
            expect(result.errorsCount, equals(0));
            expect(result.filename, '${dillFile.path}.incremental.dill');
            File incrementalSourceFile =
                File('${dillFile.path}.incremental.dill.sources');
            expect(incrementalSourceFile.existsSync(), equals(true));

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

            expect(jsModules[0], not(contains('<<a>>')));
            expect(jsModules[0], not(contains('<<b>>')));
            expect(jsModules[0], contains('<<c>>'));
            expect(jsModules[0], not(contains('<<d>>')));
            expect(jsModules[0], contains('<<d1>>'));
            expect(jsModules[0], contains('<<d2>>'));
            expect(jsModules[0], not(contains('<<e>>')));
            expect(jsModules[0], contains('<<e1>>'));
            expect(jsModules[0], contains('<<e2>>'));

            streamController.add('accept\n'.codeUnits);
            outputParser.expectSources = false;
            streamController.add('quit\n'.codeUnits);
            break;
          default:
            break;
        }
        count++;
      });

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

    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 {}

/// Creates a matcher for the negation of [matcher].
Matcher not(Matcher matcher) => NotMatcher(matcher);

class NotMatcher extends Matcher {
  final Matcher matcher;

  const NotMatcher(this.matcher);

  @override
  Description describe(Description description) =>
      matcher.describe(description.add('not '));

  @override
  bool matches(item, Map matchState) {
    return !matcher.matches(item, matchState);
  }
}
