// Copyright (c) 2018, 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 file.

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

import 'package:collection/collection.dart' show IterableExtension;
import 'package:front_end/src/api_unstable/vm.dart'
    show
        CompilerOptions,
        DiagnosticMessage,
        ExperimentalFlag,
        computePlatformBinariesLocation;
import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc;
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/text/ast_to_text.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:web_socket_channel/io.dart';

import 'package:vm/incremental_compiler.dart';
import 'package:vm/target/vm.dart';

import 'common_test_utils.dart';

main() {
  final platformKernel =
      computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
  final sdkRoot = computePlatformBinariesLocation();

  CompilerOptions getFreshOptions() {
    return new CompilerOptions()
      ..sdkRoot = sdkRoot
      ..target = new VmTarget(new TargetFlags())
      ..additionalDills = <Uri>[platformKernel]
      ..onDiagnostic = (DiagnosticMessage message) {
        fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
      }
      ..environmentDefines = const {};
  }

  final options = getFreshOptions();

  group('basic', () {
    late Directory mytest;
    late File main;

    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental');
      main = new File('${mytest.path}/main.dart')..createSync();
      main.writeAsStringSync("main() {}\n");
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
    });

    test('compile', () async {
      IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
      Component component = await compiler.compile();

      final StringBuffer buffer = new StringBuffer();
      new Printer(buffer, showMetadata: true)
          .writeLibraryFile(component.mainMethod!.enclosingLibrary);
      expect(
          buffer.toString(),
          equals('library /*isNonNullableByDefault*/;\n'
              'import self as self;\n'
              '\n'
              'static method main() → dynamic {}\n'));
    });

    test('compile exclude sources', () async {
      CompilerOptions optionsExcludeSources = getFreshOptions()
        ..embedSourceText = false;
      IncrementalCompiler compiler =
          new IncrementalCompiler(optionsExcludeSources, main.uri);
      Component component = await compiler.compile();

      for (Source source in component.uriToSource.values) {
        expect(source.source.length, equals(0));
      }

      final StringBuffer buffer = new StringBuffer();
      new Printer(buffer, showMetadata: true)
          .writeLibraryFile(component.mainMethod!.enclosingLibrary);
      expect(
          buffer.toString(),
          equals('library /*isNonNullableByDefault*/;\n'
              'import self as self;\n'
              '\n'
              'static method main() → dynamic {}\n'));
    });

    test('compile expressions errors are not re-reported', () async {
      var errorsReported = 0;
      CompilerOptions optionsAcceptErrors = getFreshOptions()
        ..onDiagnostic = (DiagnosticMessage message) {
          errorsReported++;
          message.plainTextFormatted.forEach(print);
        };
      IncrementalCompiler compiler =
          new IncrementalCompiler(optionsAcceptErrors, main.uri);
      await compiler.compile();
      compiler.accept();
      {
        Procedure? procedure = await compiler.compileExpression('main',
            <String>[], <String>[], main.uri.toString(), null, null, true);
        expect(procedure, isNotNull);
        expect(errorsReported, equals(0));
      }
      {
        Procedure? procedure = await compiler.compileExpression('main1',
            <String>[], <String>[], main.uri.toString(), null, null, true);
        expect(procedure, isNotNull);
        expect(errorsReported, equals(1));
        errorsReported = 0;
      }
      await compiler.compile();
      expect(errorsReported, equals(0));
    });
  });

  /// Collects coverage for "main.dart", "lib.dart", "lib1.dart" and "lib2.dart"
  /// checks that all tokens can be translated to line and column,
  /// return the hit positions for "lib1.dart".
  /// If [getAllSources] is false it will ask specifically for report
  /// (and thus hits) for "lib1.dart" only.
  Future<Set<int>> collectAndCheckCoverageData(int port, bool getAllSources,
      {bool resume: true,
      bool onGetAllVerifyCount: true,
      Set<int>? coverageForLines}) async {
    RemoteVm remoteVm = new RemoteVm(port);

    // Wait for the script to have finished.
    while (true) {
      Map isolate = await remoteVm.getIsolate();
      Map pauseEvent = isolate["pauseEvent"];
      if (pauseEvent["kind"] == "PauseExit") break;
    }

    // Collect coverage for the two user scripts.
    List<Map> sourceReports = <Map>[];
    if (getAllSources) {
      Map sourceReport = await remoteVm.getSourceReport();
      sourceReports.add(sourceReport);
    } else {
      Map scriptsMap = await remoteVm.getScripts();
      List scripts = scriptsMap["scripts"];
      Set<String> scriptIds = new Set<String>();
      for (int i = 0; i < scripts.length; i++) {
        Map script = scripts[i];
        String scriptUri = script["uri"];
        if (scriptUri.contains("lib1.dart")) {
          scriptIds.add(script["id"]);
        }
      }

      for (String scriptId in scriptIds) {
        Map sourceReport = await remoteVm.getSourceReport(scriptId);
        sourceReports.add(sourceReport);
      }
    }

    List<String> errorMessages = <String>[];
    Set<int> hits = new Set<int>();

    // Ensure that we can get a line and column number for all reported
    // positions in the scripts we care about.
    for (Map sourceReport in sourceReports) {
      List<Map> scripts = sourceReport["scripts"].cast<Map>();
      Map<String, int> scriptIdToIndex = new Map<String, int>();
      Set<int> lib1scriptIndices = new Set<int>();
      int i = 0;
      for (Map script in scripts) {
        if (script["uri"].toString().endsWith("main.dart") ||
            script["uri"].toString().endsWith("lib.dart") ||
            script["uri"].toString().endsWith("lib1.dart") ||
            script["uri"].toString().endsWith("lib2.dart")) {
          scriptIdToIndex[script["id"]] = i;
          if (script["uri"].toString().endsWith("lib1.dart")) {
            lib1scriptIndices.add(i);
          }
        }
        i++;
      }
      if (getAllSources && onGetAllVerifyCount) {
        expect(scriptIdToIndex.length >= 2, isTrue);
      }

      // Ensure the scripts all have a non-null 'tokenPosTable' entry.
      Map<int, Map> scriptIndexToScript = new Map<int, Map>();
      for (String scriptId in scriptIdToIndex.keys) {
        Map script = await remoteVm.getObject(scriptId);
        int scriptIdx = scriptIdToIndex[scriptId]!;
        scriptIndexToScript[scriptIdx] = script;
        List? tokenPosTable = script["tokenPosTable"];
        if (tokenPosTable == null) {
          errorMessages.add("Script with uri ${script['uri']} "
              "and id ${script['id']} "
              "has null tokenPosTable.");
        } else if (tokenPosTable.isEmpty) {
          errorMessages.add("Script with uri ${script['uri']} "
              "and id ${script['id']} "
              "has empty tokenPosTable.");
        }
      }

      List<Map> ranges = sourceReport["ranges"].cast<Map>();
      Set<int> scriptIndexesSet = new Set<int>.from(scriptIndexToScript.keys);
      for (Map range in ranges) {
        if (scriptIndexesSet.contains(range["scriptIndex"])) {
          Set<int> positions = new Set<int>();
          positions.add(range["startPos"]);
          positions.add(range["endPos"]);
          Map coverage = range["coverage"];
          for (int pos in coverage["hits"]) {
            positions.add(pos);
            if (lib1scriptIndices.contains(range["scriptIndex"])) {
              hits.add(pos);
            }
          }
          for (int pos in coverage["misses"]) positions.add(pos);
          if (range["possibleBreakpoints"] != null) {
            for (int pos in range["possibleBreakpoints"]) positions.add(pos);
          }
          Map script = scriptIndexToScript[range["scriptIndex"]]!;
          Set<int> knownPositions = new Set<int>();
          Map<int, int> tokenPosToLine = {};
          if (script["tokenPosTable"] != null) {
            for (List tokenPosTableLine in script["tokenPosTable"]) {
              for (int i = 1; i < tokenPosTableLine.length; i += 2) {
                tokenPosToLine[tokenPosTableLine[i]] = tokenPosTableLine[0];
                knownPositions.add(tokenPosTableLine[i]);
              }
            }
          }
          for (int pos in positions) {
            if (!knownPositions.contains(pos)) {
              errorMessages.add("Script with uri ${script['uri']} "
                  "and id ${script['id']} "
                  "references position $pos which cannot be translated to "
                  "line and column.");
            }
          }

          if (coverageForLines != null) {
            for (int pos in coverage["hits"]) {
              if (lib1scriptIndices.contains(range["scriptIndex"])) {
                coverageForLines.add(tokenPosToLine[pos]!);
              }
            }
          }
        }
      }
    }
    expect(errorMessages, isEmpty);
    if (resume) {
      remoteVm.resume();
    }
    return hits;
  }

  group('multiple kernels', () {
    late Directory mytest;
    late File main;
    late File lib;
    late Process vm;
    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental');
      main = new File('${mytest.path}/main.dart')..createSync();
      main.writeAsStringSync("""
      import 'lib.dart';
      main() => print(foo());
      class C1 extends Object with C2, C3 {
        c1method() {
          print("c1");
        }
      }
      class C3 {
        c3method() {
          print("c3");
        }
      }
      """);
      lib = new File('${mytest.path}/lib.dart')..createSync();
      lib.writeAsStringSync("""
      import 'main.dart';
      foo() => 'foo';
      main() => print('bar');
      class C2 extends Object with C3 {
        c2method() {
          print("c2");
        }
      }
      """);
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
    });

    compileAndSerialize(
        File mainDill, File libDill, IncrementalCompiler compiler) async {
      Component component = await compiler.compile();
      new BinaryPrinter(new DevNullSink<List<int>>())
          .writeComponentFile(component);
      IOSink sink = mainDill.openWrite();
      BinaryPrinter printer = new BinaryPrinter(sink,
          libraryFilter: (lib) => lib.fileUri.path.endsWith("main.dart"));
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      sink = libDill.openWrite();
      printer = new BinaryPrinter(sink,
          libraryFilter: (lib) => lib.fileUri.path.endsWith("lib.dart"));
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
    }

    test('main first, lib second', () async {
      Directory dir = mytest.createTempSync();
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      File libDill = File(p.join(dir.path, p.basename(lib.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
      await compileAndSerialize(mainDill, libDill, compiler);

      var list = new File(p.join(dir.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
      vm =
          await Process.start(Platform.resolvedExecutable, <String>[list.path]);

      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stdout: $s");
        if (!portLineCompleter.isCompleted) {
          portLineCompleter.complete(s);
        }
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      expect(await portLineCompleter.future, equals('foo'));
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });

    test('main second, lib first', () async {
      Directory dir = mytest.createTempSync();
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      File libDill = File(p.join(dir.path, p.basename(lib.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, lib.uri);
      await compileAndSerialize(mainDill, libDill, compiler);

      var list = new File(p.join(dir.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync("#@dill\n${libDill.path}\n${mainDill.path}\n");
      vm =
          await Process.start(Platform.resolvedExecutable, <String>[list.path]);

      final splitter = new LineSplitter();

      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stdout: $s");
        if (!portLineCompleter.isCompleted) {
          portLineCompleter.complete(s);
        }
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      expect(await portLineCompleter.future, equals('bar'));
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });

    test('empty list', () async {
      var list = new File(p.join(mytest.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync("#@dill\n");
      vm =
          await Process.start(Platform.resolvedExecutable, <String>[list.path]);

      Completer<int> exitCodeCompleter = new Completer<int>();
      vm.exitCode.then((exitCode) {
        print("Compiler terminated with $exitCode exit code");
        exitCodeCompleter.complete(exitCode);
      });
      expect(await exitCodeCompleter.future, equals(254));
    });

    test('fallback to source compilation if fail to load', () async {
      var list = new File('${mytest.path}/myMain.dilllist')..createSync();
      list.writeAsStringSync("main() => print('baz');\n");
      vm =
          await Process.start(Platform.resolvedExecutable, <String>[list.path]);

      final splitter = new LineSplitter();

      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stdout: $s");
        if (!portLineCompleter.isCompleted) {
          portLineCompleter.complete(s);
        }
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      expect(await portLineCompleter.future, equals('baz'));
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });

    test('relative paths', () async {
      Directory dir = mytest.createTempSync();
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      File libDill = File(p.join(dir.path, p.basename(lib.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
      await compileAndSerialize(mainDill, libDill, compiler);

      var list = new File(p.join(dir.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync("#@dill\nmain.dart.dill\nlib.dart.dill\n");
      Directory runFrom = new Directory(dir.path + "/runFrom")..createSync();
      vm = await Process.start(Platform.resolvedExecutable, <String>[list.path],
          workingDirectory: runFrom.path);

      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stdout: $s");
        if (!portLineCompleter.isCompleted) {
          portLineCompleter.complete(s);
        }
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      expect(await portLineCompleter.future, equals('foo'));
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });

    test('collect coverage', () async {
      Directory dir = mytest.createTempSync();
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      File libDill = File(p.join(dir.path, p.basename(lib.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
      await compileAndSerialize(mainDill, libDill, compiler);

      var list = new File(p.join(dir.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
      vm = await Process.start(Platform.resolvedExecutable, <String>[
        "--pause-isolates-on-exit",
        "--enable-vm-service:0",
        "--disable-service-auth-codes",
        "--disable-dart-dev",
        list.path
      ]);

      const kObservatoryListening = 'Observatory listening on ';
      final RegExp observatoryPortRegExp =
          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
      int port;
      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout
          .transform(utf8.decoder)
          .transform(splitter)
          .listen((String s) async {
        if (s.startsWith(kObservatoryListening)) {
          expect(observatoryPortRegExp.hasMatch(s), isTrue);
          final match = observatoryPortRegExp.firstMatch(s)!;
          port = int.parse(match.group(1)!);
          await collectAndCheckCoverageData(port, true);
          if (!portLineCompleter.isCompleted) {
            portLineCompleter.complete("done");
          }
        }
        print("vm stdout: $s");
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      await portLineCompleter.future;
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });
  });

  group('multiple kernels constant coverage', () {
    late Directory mytest;
    late File main;
    late File lib1;
    late int lineForUnnamedConstructor;
    late int lineForNamedConstructor;
    late Process vm;
    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental');
      main = new File('${mytest.path}/main.dart')..createSync();
      main.writeAsStringSync("""
        // This file - combined with the lib - should have coverage for both
        // constructors of Foo.
        import 'lib1.dart' as lib1;

        void testFunction() {
          const foo = lib1.Foo.named();
          const foo2 = lib1.Foo.named();
          if (!identical(foo, foo2)) throw "what?";
        }

        main() {
          lib1.testFunction();
          testFunction();
          print("main");
        }
      """);
      lib1 = new File('${mytest.path}/lib1.dart')..createSync();
      lib1.writeAsStringSync("""
        // Compiling this file should mark the default constructor - but not the
        // named constructor - as having coverage.
        class Foo {
          final int x;
          const Foo([int? x]) : this.x = x ?? 42;
          const Foo.named([int? x]) : this.x = x ?? 42;
        }

        void testFunction() {
          const foo = Foo();
          const foo2 = Foo();
          if (!identical(foo, foo2)) throw "what?";
        }

        main() {
          testFunction();
          print("lib1");
        }
      """);
      lineForUnnamedConstructor = 5;
      lineForNamedConstructor = 6;
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
    });

    Future<Set<int>> runAndGetLineCoverage(
        File list, String expectStdoutContains) async {
      vm = await Process.start(Platform.resolvedExecutable, <String>[
        "--pause-isolates-on-exit",
        "--enable-vm-service:0",
        "--disable-service-auth-codes",
        "--disable-dart-dev",
        list.path
      ]);

      const kObservatoryListening = 'Observatory listening on ';
      final RegExp observatoryPortRegExp =
          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
      int port;
      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      Set<int> coverageLines = {};
      bool foundExpectedString = false;
      vm.stdout
          .transform(utf8.decoder)
          .transform(splitter)
          .listen((String s) async {
        if (s == expectStdoutContains) {
          foundExpectedString = true;
        }
        if (s.startsWith(kObservatoryListening)) {
          expect(observatoryPortRegExp.hasMatch(s), isTrue);
          final match = observatoryPortRegExp.firstMatch(s)!;
          port = int.parse(match.group(1)!);
          await collectAndCheckCoverageData(port, true,
              onGetAllVerifyCount: false, coverageForLines: coverageLines);
          if (!portLineCompleter.isCompleted) {
            portLineCompleter.complete("done");
          }
        }
        print("vm stdout: $s");
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      await portLineCompleter.future;
      print("Compiler terminated with ${await vm.exitCode} exit code");
      expect(foundExpectedString, isTrue);
      return coverageLines;
    }

    test('compile seperatly, check coverage', () async {
      Directory dir = mytest.createTempSync();

      // First compile lib, run and verify coverage (un-named constructor
      // covered, but not the named constructor).
      // Note that it's called 'lib1' to match with expectations from coverage
      // collector helper in this file.
      File libDill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, lib1.uri);
      Component component = await compiler.compile();
      expect(component.libraries.length, equals(1));
      expect(component.libraries.single.fileUri, equals(lib1.uri));
      IOSink sink = libDill.openWrite();
      BinaryPrinter printer = new BinaryPrinter(sink);
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      File list = new File(p.join(dir.path, 'dill.list'))..createSync();
      list.writeAsStringSync("#@dill\n${libDill.path}\n");
      Set<int> lineCoverage = await runAndGetLineCoverage(list, "lib1");
      // Expect coverage for unnamed constructor but not for the named one.
      expect(
          lineCoverage.intersection(
              {lineForUnnamedConstructor, lineForNamedConstructor}),
          equals({lineForUnnamedConstructor}));

      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
      // Accept the compile to not include the lib again.
      compiler.accept();

      // Then compile lib, run and verify coverage (un-named constructor
      // covered, and the named constructor coveraged too).
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      component = await compiler.compile(entryPoint: main.uri);
      expect(component.libraries.length, equals(1));
      expect(component.libraries.single.fileUri, equals(main.uri));
      sink = mainDill.openWrite();
      printer = new BinaryPrinter(sink);
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
      lineCoverage = await runAndGetLineCoverage(list, "main");

      // Expect coverage for both unnamed constructor and for the named one.
      expect(
          lineCoverage.intersection(
              {lineForUnnamedConstructor, lineForNamedConstructor}),
          equals({lineForUnnamedConstructor, lineForNamedConstructor}));

      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
      // Accept the compile to not include the lib again.
      compiler.accept();

      // Finally, change lib to shift the constructors so the old line numbers
      // doesn't match. Compile lib by itself, compile lib, run with the old
      // main and verify coverage is still correct (both un-named constructor
      // and named constructor (at new line numbers) are covered, and the old
      // line numbers are not coverage.

      lib1.writeAsStringSync("""
        //
        // Shift lines down by five
        // lines so the original
        // lines can't be coverred
        //
        class Foo {
          final int x;
          const Foo([int? x]) : this.x = x ?? 42;
          const Foo.named([int? x]) : this.x = x ?? 42;
        }

        void testFunction() {
          const foo = Foo();
          const foo2 = Foo();
          if (!identical(foo, foo2)) throw "what?";
        }

        main() {
          testFunction();
          print("lib1");
        }
      """);
      int newLineForUnnamedConstructor = 8;
      int newLineForNamedConstructor = 9;
      compiler.invalidate(lib1.uri);
      component = await compiler.compile(entryPoint: lib1.uri);
      expect(component.libraries.length, equals(1));
      expect(component.libraries.single.fileUri, equals(lib1.uri));
      sink = libDill.openWrite();
      printer = new BinaryPrinter(sink);
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
      lineCoverage = await runAndGetLineCoverage(list, "main");

      // Expect coverage for both unnamed constructor and for the named one on
      // the new positions, but no coverage on the old positions.
      expect(
          lineCoverage.intersection({
            lineForUnnamedConstructor,
            lineForNamedConstructor,
            newLineForUnnamedConstructor,
            newLineForNamedConstructor
          }),
          equals({newLineForUnnamedConstructor, newLineForNamedConstructor}));

      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
      // Accept the compile to not include the lib again.
      compiler.accept();
    });
  });

  group('multiple kernels 2', () {
    late Directory mytest;
    late File main;
    late File lib1;
    late File lib2;
    late Process vm;
    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental');
      main = new File('${mytest.path}/main.dart')..createSync();
      main.writeAsStringSync("""
        import 'lib1.dart';
        import 'lib2.dart';

        void main() {
          TestA().foo();
          bar();
        }

        class TestA with A {}
      """);
      lib1 = new File('${mytest.path}/lib1.dart')..createSync();
      lib1.writeAsStringSync("""
        mixin A {
          void foo() {
            print('foo');
          }
          void bar() {
            print('bar');
          }
        }
      """);
      lib2 = new File('${mytest.path}/lib2.dart')..createSync();
      lib2.writeAsStringSync("""
        import 'lib1.dart';
        void bar() {
          TestB().bar();
        }
        class TestB with A {}
      """);
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
    });

    compileAndSerialize(File mainDill, File lib1Dill, File lib2Dill,
        IncrementalCompiler compiler) async {
      Component component = await compiler.compile();
      new BinaryPrinter(new DevNullSink<List<int>>())
          .writeComponentFile(component);
      IOSink sink = mainDill.openWrite();
      BinaryPrinter printer = new BinaryPrinter(sink,
          libraryFilter: (lib) => lib.fileUri.path.endsWith("main.dart"));
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      sink = lib1Dill.openWrite();
      printer = new BinaryPrinter(sink,
          libraryFilter: (lib) => lib.fileUri.path.endsWith("lib1.dart"));
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
      sink = lib2Dill.openWrite();
      printer = new BinaryPrinter(sink,
          libraryFilter: (lib) => lib.fileUri.path.endsWith("lib2.dart"));
      printer.writeComponentFile(component);
      await sink.flush();
      await sink.close();
    }

    test('collect coverage hits', () async {
      Directory dir = mytest.createTempSync();
      File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
      File lib1Dill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
      File lib2Dill = File(p.join(dir.path, p.basename(lib2.path + ".dill")));
      IncrementalCompiler compiler = new IncrementalCompiler(options, main.uri);
      await compileAndSerialize(mainDill, lib1Dill, lib2Dill, compiler);

      var list = new File(p.join(dir.path, 'myMain.dilllist'))..createSync();
      list.writeAsStringSync(
          "#@dill\n${mainDill.path}\n${lib1Dill.path}\n${lib2Dill.path}\n");
      vm = await Process.start(Platform.resolvedExecutable, <String>[
        "--pause-isolates-on-exit",
        "--enable-vm-service:0",
        "--disable-service-auth-codes",
        "--disable-dart-dev",
        list.path
      ]);

      const kObservatoryListening = 'Observatory listening on ';
      final RegExp observatoryPortRegExp =
          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
      int port;
      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout
          .transform(utf8.decoder)
          .transform(splitter)
          .listen((String s) async {
        if (s.startsWith(kObservatoryListening)) {
          expect(observatoryPortRegExp.hasMatch(s), isTrue);
          final match = observatoryPortRegExp.firstMatch(s)!;
          port = int.parse(match.group(1)!);
          Set<int> hits1 =
              await collectAndCheckCoverageData(port, true, resume: false);
          Set<int> hits2 =
              await collectAndCheckCoverageData(port, false, resume: true);
          expect(hits1.toList()..sort(), equals(hits2.toList()..sort()));
          if (!portLineCompleter.isCompleted) {
            portLineCompleter.complete("done");
          }
        }
        print("vm stdout: $s");
      });
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });
      await portLineCompleter.future;
      print("Compiler terminated with ${await vm.exitCode} exit code");
    });
  });

  group('reload', () {
    late Directory mytest;

    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental');
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
    });

    test('picks up after rejected delta', () async {
      var file = new File('${mytest.path}/foo.dart')..createSync();
      file.writeAsStringSync("import 'bar.dart';\n"
          "import 'baz.dart';\n"
          "main() {\n"
          "  new A();\n"
          "  openReceivePortSoWeWontDie();"
          "}\n");

      var fileBar = new File('${mytest.path}/bar.dart')..createSync();
      fileBar.writeAsStringSync("class A<T> { int _a = 0; }\n");

      var fileBaz = new File('${mytest.path}/baz.dart')..createSync();
      fileBaz.writeAsStringSync("import 'dart:isolate';\n"
          "openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");

      IncrementalCompiler compiler = new IncrementalCompiler(options, file.uri);
      Component component = await compiler.compile();

      File outputFile = new File('${mytest.path}/foo.dart.dill');
      await _writeProgramToFile(component, outputFile);

      final List<String> vmArgs = [
        '--trace_reload',
        '--trace_reload_verbose',
        '--enable-vm-service=0', // Note: use 0 to avoid port collisions.
        '--pause_isolates_on_start',
        '--disable-service-auth-codes',
        '--disable-dart-dev',
        outputFile.path
      ];
      final vm = await Process.start(Platform.resolvedExecutable, vmArgs);

      final splitter = new LineSplitter();

      vm.exitCode.then((exitCode) {
        print("Compiler terminated with $exitCode exit code");
      });

      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stdout: $s");
        if (!portLineCompleter.isCompleted) {
          portLineCompleter.complete(s);
        }
      });

      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
      });

      String portLine = await portLineCompleter.future;

      final RegExp observatoryPortRegExp =
          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
      expect(observatoryPortRegExp.hasMatch(portLine), isTrue);
      final match = observatoryPortRegExp.firstMatch(portLine)!;
      final port = int.parse(match.group(1)!);

      var remoteVm = new RemoteVm(port);
      await remoteVm.resume();
      compiler.accept();

      // Confirm that without changes VM reloads nothing.
      component = await compiler.compile();
      await _writeProgramToFile(component, outputFile);
      var reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
      expect(reloadResult['success'], isTrue);
      expect(reloadResult['details']['loadedLibraryCount'], equals(0));

      // Introduce a change that force VM to reject the change.
      fileBar.writeAsStringSync("class A<T,U> { int _a = 0; }\n");
      compiler.invalidate(fileBar.uri);
      component = await compiler.compile();
      await _writeProgramToFile(component, outputFile);
      reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
      expect(reloadResult['success'], isFalse);

      // Fix a change so VM is happy to accept the change.
      fileBar.writeAsStringSync("class A<T> { int _a = 0; hi() => _a; }\n");
      compiler.invalidate(fileBar.uri);
      component = await compiler.compile();
      await _writeProgramToFile(component, outputFile);
      reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
      expect(reloadResult['success'], isTrue);
      expect(reloadResult['details']['loadedLibraryCount'], equals(2));
      compiler.accept();

      vm.kill();
    });
  });

  group('reject', () {
    late Directory mytest;
    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('incremental_reject');
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
    });

    test('compile, reject, compile again', () async {
      var packageUri = Uri.file('${mytest.path}/.packages');
      new File(packageUri.toFilePath()).writeAsStringSync('foo:lib/\n');
      new Directory(mytest.path + "/lib").createSync();
      var fooUri = Uri.file('${mytest.path}/lib/foo.dart');
      new File(fooUri.toFilePath())
          .writeAsStringSync("import 'package:foo/bar.dart';\n"
              "import 'package:foo/baz.dart';\n"
              "main() {\n"
              "  new A();\n"
              "  openReceivePortSoWeWontDie();"
              "}\n");

      var barUri = Uri.file('${mytest.path}/lib/bar.dart');
      new File(barUri.toFilePath())
          .writeAsStringSync("class A { static int a; }\n");

      var bazUri = Uri.file('${mytest.path}/lib/baz.dart');
      new File(bazUri.toFilePath()).writeAsStringSync("import 'dart:isolate';\n"
          "openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");

      Uri packageEntry = Uri.parse('package:foo/foo.dart');

      CompilerOptions optionsModified = getFreshOptions()
        ..packagesFileUri = packageUri;
      IncrementalCompiler compiler =
          new IncrementalCompiler(optionsModified, packageEntry);
      {
        Component component = await compiler.compile(entryPoint: packageEntry);
        File outputFile = new File('${mytest.path}/foo.dart.dill');
        await _writeProgramToFile(component, outputFile);
      }
      compiler.accept();
      {
        Procedure? procedure = await compiler.compileExpression('a', <String>[],
            <String>[], 'package:foo/bar.dart', 'A', null, true);
        expect(procedure, isNotNull);
      }

      new File(barUri.toFilePath())
          .writeAsStringSync("class A { static int b; }\n");
      compiler.invalidate(barUri);
      {
        Component component = await compiler.compile(entryPoint: packageEntry);
        File outputFile = new File('${mytest.path}/foo1.dart.dill');
        await _writeProgramToFile(component, outputFile);
      }
      await compiler.reject();
      {
        Procedure? procedure = await compiler.compileExpression('a', <String>[],
            <String>[], 'package:foo/bar.dart', 'A', null, true);
        expect(procedure, isNotNull);
      }
    });

    /// This test basicaly verifies that components `relink` method is correctly
    /// called when rejecting (i.e. logically going back in time to before a
    /// rejected compilation).
    test('check links after reject', () async {
      final Uri fooUri = Uri.file('${mytest.path}/foo.dart');
      new File.fromUri(fooUri).writeAsStringSync("""
        import 'bar.dart';
        main() {
          A a = new A();
          print(a.b());
          print(A.a);
        }
        """);

      final Uri barUri = Uri.file('${mytest.path}/bar.dart');
      new File.fromUri(barUri).writeAsStringSync("""
        class A {
          static int a;
          int b() { return 42; }
        }
        """);

      final CompilerOptions optionsModified = getFreshOptions();
      optionsModified.explicitExperimentalFlags[
          ExperimentalFlag.alternativeInvalidationStrategy] = true;

      final IncrementalCompiler compiler =
          new IncrementalCompiler(optionsModified, fooUri);
      Library fooLib;
      Library barLib;
      {
        final Component component = await compiler.compile(entryPoint: fooUri);
        expect(component.libraries.length, equals(2));
        fooLib = component.libraries.firstWhere((lib) => lib.fileUri == fooUri);
        barLib = component.libraries.firstWhere((lib) => lib.fileUri == barUri);
        // Verify that foo only has links to this bar.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        fooLib.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{barLib}));
      }
      compiler.accept();
      {
        final Procedure procedure = (await compiler.compileExpression(
            'a', <String>[], <String>[], barUri.toString(), 'A', null, true))!;
        // Verify that the expression only has links to the only bar we know
        // about.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        procedure.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{barLib}));
      }

      new File.fromUri(barUri).writeAsStringSync("""
        class A {
          static int a;
          int b() { return 84; }
        }
        """);
      compiler.invalidate(barUri);
      {
        final Component component = await compiler.compile(entryPoint: fooUri);
        final Library? fooLib2 = component.libraries
            .firstWhereOrNull((lib) => lib.fileUri == fooUri);
        expect(fooLib2, isNull);
        final Library barLib2 =
            component.libraries.firstWhere((lib) => lib.fileUri == barUri);
        // Verify that the fooLib (we only have the original one) only has
        // links to the newly compiled bar.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        fooLib.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{barLib2}));
      }
      await compiler.reject();
      {
        // Verify that the original foo library only has links to the original
        // compiled bar.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        fooLib.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{barLib}));
      }
      {
        // Verify that the saved "last known good" compnent only contains links
        // to the original 'foo' and 'bar' libraries.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        compiler.lastKnownGoodComponent!.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{fooLib, barLib}));
      }
      {
        final Procedure procedure = (await compiler.compileExpression(
            'a', <String>[], <String>[], barUri.toString(), 'A', null, true))!;
        // Verify that the expression only has links to the original bar.
        final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
        procedure.accept(lrc);
        expect(lrc.librariesReferenced, equals(<Library>{barLib}));
      }
    });
  });

  group('expression evaluation', () {
    late Directory mytest;
    late Process vm;

    setUpAll(() {
      mytest = Directory.systemTemp.createTempSync('expression_evaluation');
    });

    tearDownAll(() {
      try {
        mytest.deleteSync(recursive: true);
      } catch (_) {
        // Ignore errors;
      }
      try {
        vm.kill();
      } catch (_) {
        // Ignore errors;
      }
    });

    launchBreakAndEvaluate(File scriptOrDill, String scriptUriToBreakIn,
        int lineToBreakAt, List<String> expressionsAndExpectedResults,
        {Future Function(RemoteVm remoteVm)? callback}) async {
      vm = await Process.start(Platform.resolvedExecutable, <String>[
        "--pause-isolates-on-start",
        "--enable-vm-service:0",
        "--disable-service-auth-codes",
        "--disable-dart-dev",
        scriptOrDill.path
      ]);

      const kObservatoryListening = 'Observatory listening on ';
      final RegExp observatoryPortRegExp =
          new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
      int port;
      final splitter = new LineSplitter();
      Completer<String> portLineCompleter = new Completer<String>();
      vm.stdout
          .transform(utf8.decoder)
          .transform(splitter)
          .listen((String s) async {
        print("vm stdout: $s");
        if (s.startsWith(kObservatoryListening)) {
          expect(observatoryPortRegExp.hasMatch(s), isTrue);
          final match = observatoryPortRegExp.firstMatch(s)!;
          port = int.parse(match.group(1)!);
          RemoteVm remoteVm = new RemoteVm(port);

          // Wait for the script to have loaded.
          while (true) {
            Map isolate = await remoteVm.getIsolate();
            Map pauseEvent = isolate["pauseEvent"];
            if (pauseEvent["kind"] == "PauseStart") break;
          }

          var breakpoint = await findScriptAndBreak(
              remoteVm, scriptUriToBreakIn, lineToBreakAt);
          await remoteVm.resume();
          await waitForScriptToHavePaused(remoteVm);
          await evaluateExpressions(expressionsAndExpectedResults, remoteVm);
          await deletePossibleBreakpoint(remoteVm, breakpoint);

          if (callback != null) {
            await callback(remoteVm);
          }

          await remoteVm.resume();

          if (!portLineCompleter.isCompleted) {
            portLineCompleter.complete("done");
          }
        }
      });
      bool gotStdErrOutput = false;
      vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
        print("vm stderr: $s");
        gotStdErrOutput = true;
      });
      await portLineCompleter.future;
      int exitCode = await vm.exitCode;
      print("Compiler terminated with ${exitCode} exit code");
      expect(exitCode, equals(0));
      expect(gotStdErrOutput, isFalse);
    }

    test('from source', () async {
      Directory dir = mytest.createTempSync();
      File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
      mainFile.writeAsStringSync(r"""
        var hello = "Hello";
        main() {
          var s = "$hello world!";
          print(s);
        }
        int extra() { return 22; }
      """);

      await launchBreakAndEvaluate(mainFile, mainFile.uri.toString(), 4, [
        // 1st expression
        "s.length",
        "12",

        // 2nd expression
        "s",
        "Hello world!",

        // 3rd expression
        "hello",
        "Hello",

        // 4th expression
        "extra()",
        "22",
      ]);
    });

    test('from dill', () async {
      Directory dir = mytest.createTempSync();
      File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
      mainFile.writeAsStringSync(r"""
        var hello = "Hello";
        main() {
          var s = "$hello world!";
          print(s);
        }
        int extra() { return 22; }
      """);
      IncrementalCompiler compiler =
          new IncrementalCompiler(options, mainFile.uri);
      Component component = await compiler.compile();
      File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
      IOSink sink = mainDill.openWrite();
      new BinaryPrinter(sink).writeComponentFile(component);
      await sink.flush();
      await sink.close();

      mainFile.deleteSync();

      await launchBreakAndEvaluate(mainDill, mainFile.uri.toString(), 4, [
        // 1st expression
        "s.length",
        "12",

        // 2nd expression
        "s",
        "Hello world!",

        // 3rd expression
        "hello",
        "Hello",

        // 4th expression
        "extra()",
        "22",
      ]);
    });

    test('from dill with reload', () async {
      Directory dir = mytest.createTempSync();
      File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
      mainFile.writeAsStringSync(r"""
        import 'dart:async';
        import 'helper.dart';
        main() {
          int latestReloadTime = -1;
          int noChangeCount = 0;
          int numChanges = 0;
          new Timer.periodic(new Duration(milliseconds: 5), (timer) async {
            var result = reloadTime();
            if (latestReloadTime != result) {
              latestReloadTime = result;
              numChanges++;
              helperMethod();
            } else {
              noChangeCount++;
            }
            if (latestReloadTime == 42) {
              timer.cancel();
            }
            if (numChanges > 20) {
              timer.cancel();
            }
            if (noChangeCount >= 400) {
              // ~2 seconds with no change.
              throw "Expected to be done but wasn't";
            }
          });
        }
      """);
      File helperFile = new File.fromUri(dir.uri.resolve("helper.dart"));
      helperFile.writeAsStringSync(r"""
        int reloadTime() {
          return 0;
        }
        void helperMethod() {
          var hello = "Hello";
          var s = "$hello world!";
          print(s);
        }
      """);
      IncrementalCompiler compiler =
          new IncrementalCompiler(options, mainFile.uri);
      Component component = await compiler.compile();
      File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
      IOSink sink = mainDill.openWrite();
      new BinaryPrinter(sink).writeComponentFile(component);
      await sink.flush();
      await sink.close();
      print("=> Notice main file has size ${mainDill.lengthSync()}");

      helperFile.writeAsStringSync(r"""
        int reloadTime() {
          return 1;
        }
        void helperMethod() {
          var hello = "Hello";
          var s = "$hello world!!!";
          print(s);
        }
        int helperMethod2() {
          return 42;
        }
      """);
      compiler.invalidate(helperFile.uri);
      component = await compiler.compile();
      File partial1Dill =
          new File.fromUri(mainFile.uri.resolve("partial1.dill"));
      sink = partial1Dill.openWrite();
      new BinaryPrinter(sink).writeComponentFile(component);
      await sink.flush();
      await sink.close();
      print("=> Notice partial file #1 has size ${partial1Dill.lengthSync()}");

      helperFile.writeAsStringSync(r"""
        int reloadTime() {
          return 2;
        }
        void helperMethod() {
          var hello = "Hello";
          var s = "$hello world!!!!";
          print(s);
        }
        int helperMethod2() {
          return 21;
        }
        int helperMethod3() {
          return 84;
        }
      """);
      compiler.invalidate(helperFile.uri);
      component = await compiler.compile();
      File partial2Dill =
          new File.fromUri(mainFile.uri.resolve("partial2.dill"));
      sink = partial2Dill.openWrite();
      new BinaryPrinter(sink).writeComponentFile(component);
      await sink.flush();
      await sink.close();
      print("=> Notice partial file #2 has size ${partial2Dill.lengthSync()}");

      mainFile.deleteSync();
      helperFile.deleteSync();

      await launchBreakAndEvaluate(mainDill, helperFile.uri.toString(), 7, [
        // 1st expression
        "s.length",
        "12",

        // 2nd expression
        "s",
        "Hello world!",

        // 3rd expression
        "hello",
        "Hello",

        // 4th expression
        "reloadTime()",
        "0",
      ], callback: (RemoteVm remoteVm) async {
        for (int q = 0; q < 10; q++) {
          Map reloadResult = await remoteVm.reload(partial1Dill.uri);
          expect(reloadResult["success"], equals(true));

          await remoteVm.forceGc();

          var breakpoint =
              await findScriptAndBreak(remoteVm, helperFile.uri.toString(), 7);
          await remoteVm.resume();
          await waitForScriptToHavePaused(remoteVm);
          await evaluateExpressions([
            // 1st expression
            "s.length",
            "14",

            // 2nd expression
            "s",
            "Hello world!!!",

            // 3rd expression
            "hello",
            "Hello",

            // 4th expression
            "reloadTime()",
            "1",

            // 5th expression
            "helperMethod2()",
            "42",
          ], remoteVm);
          await deletePossibleBreakpoint(remoteVm, breakpoint);

          reloadResult = await remoteVm.reload(partial2Dill.uri);
          expect(reloadResult["success"], equals(true));

          await remoteVm.forceGc();

          breakpoint =
              await findScriptAndBreak(remoteVm, helperFile.uri.toString(), 7);
          await remoteVm.resume();
          await waitForScriptToHavePaused(remoteVm);
          await evaluateExpressions([
            // 1st expression
            "s.length",
            "15",

            // 2nd expression
            "s",
            "Hello world!!!!",

            // 3rd expression
            "hello",
            "Hello",

            // 4th expression
            "reloadTime()",
            "2",

            // 5th expression
            "helperMethod2()",
            "21",

            // 6th expression
            "helperMethod3()",
            "84",
          ], remoteVm);
          await deletePossibleBreakpoint(remoteVm, breakpoint);
        }
      });
    });

    test('from dill with package uri', () async {
      // 2 iterations: One where the .packages file is deleted, and one where
      // it is not.
      for (int i = 0; i < 2; i++) {
        Directory dir = mytest.createTempSync();
        File mainFile = new File.fromUri(dir.uri.resolve("main.dart"));
        mainFile.writeAsStringSync(r"""
          var hello = "Hello";
          main() {
            var s = "$hello world!";
            print(s);
          }
          int extra() { return 22; }
        """);

        File packagesFile = new File.fromUri(dir.uri.resolve(".packages"));
        packagesFile.writeAsStringSync("foo:.");

        Uri mainUri = Uri.parse("package:foo/main.dart");

        CompilerOptions optionsModified = getFreshOptions()
          ..packagesFileUri = packagesFile.uri;
        IncrementalCompiler compiler =
            new IncrementalCompiler(optionsModified, mainUri);

        Component component = await compiler.compile();
        File mainDill = new File.fromUri(mainFile.uri.resolve("main.dill"));
        IOSink sink = mainDill.openWrite();
        new BinaryPrinter(sink).writeComponentFile(component);
        await sink.flush();
        await sink.close();

        mainFile.deleteSync();
        if (i == 0) {
          packagesFile.deleteSync();
        }

        await launchBreakAndEvaluate(mainDill, mainUri.toString(), 4, [
          // 1st expression
          "s.length",
          "12",

          // 2nd expression
          "s",
          "Hello world!",

          // 3rd expression
          "hello",
          "Hello",

          // 4th expression
          "extra()",
          "22",
        ]);

        try {
          dir.deleteSync(recursive: true);
        } catch (e) {
          // ignore.
        }
      }
    });
  });
}

Future evaluateExpressions(
    List<String> expressionsAndExpectedResults, RemoteVm remoteVm) async {
  for (int i = 0; i < expressionsAndExpectedResults.length; i += 2) {
    String expression = expressionsAndExpectedResults[i];
    String expectedResult = expressionsAndExpectedResults[i + 1];

    print("Evaluating $expression (expecting $expectedResult)");
    var result = await remoteVm.evaluateInFrame(expression);
    expect(result is Map, isTrue);
    expect(result["type"], equals("@Instance"));
    expect(result["valueAsString"], equals(expectedResult));
  }
}

Future waitForScriptToHavePaused(RemoteVm remoteVm) async {
  // Wait for the script to have paused.
  while (true) {
    Map isolate = await remoteVm.getIsolate();
    Map pauseEvent = isolate["pauseEvent"];
    if (pauseEvent["kind"] == "PauseBreakpoint") break;
  }
}

Future findScriptAndBreak(
    RemoteVm remoteVm, String scriptUriToBreakIn, int lineToBreakAt) async {
  Map scriptsMap = await remoteVm.getScripts();
  List scripts = scriptsMap["scripts"];
  String? scriptId;
  for (int i = 0; i < scripts.length; i++) {
    Map script = scripts[i];
    String scriptUri = script["uri"];
    if (scriptUri == scriptUriToBreakIn) {
      scriptId = script["id"];
      break;
    }
  }
  expect(scriptId, isNotNull);

  return await remoteVm.addBreakpoint(scriptId!, lineToBreakAt);
}

Future deletePossibleBreakpoint(
    RemoteVm remoteVm, dynamic possibleBreakpoint) async {
  if (possibleBreakpoint is Map && possibleBreakpoint["id"] is String) {
    return await remoteVm.removeBreakpoint(possibleBreakpoint["id"]);
  }
}

_writeProgramToFile(Component component, File outputFile) async {
  final IOSink sink = outputFile.openWrite();
  final BinaryPrinter printer = new BinaryPrinter(sink);
  printer.writeComponentFile(component);
  await sink.flush();
  await sink.close();
}

class LibraryReferenceCollector extends RecursiveVisitor {
  Set<Library> librariesReferenced = {};

  void defaultMemberReference(Member node) {
    Library lib = node.enclosingLibrary;
    if (lib.importUri.scheme != "dart") {
      librariesReferenced.add(lib);
    }
    return super.defaultMemberReference(node);
  }
}

/// APIs to communicate with a remote VM via the VM's service protocol.
///
/// Only supports APIs to resume the program execution (when isolates are paused
/// at startup) and to trigger hot reloads.
class RemoteVm {
  /// Port used to connect to the vm service protocol, typically 8181.
  final int port;

  /// An peer point used to send service protocol messages. The service
  /// protocol uses JSON rpc on top of web-sockets.
  json_rpc.Peer get rpc => _rpc ??= _createPeer();
  json_rpc.Peer? _rpc;

  /// The main isolate ID of the running VM. Needed to indicate to the VM which
  /// isolate to reload.
  FutureOr<String> get mainId async => _mainId ??= await _computeMainId();
  String? _mainId;

  RemoteVm([this.port = 8181]);

  /// Establishes the JSON rpc connection.
  json_rpc.Peer _createPeer() {
    var socket = new IOWebSocketChannel.connect('ws://127.0.0.1:$port/ws');
    var peer = new json_rpc.Peer(socket.cast<String>());
    peer.listen().then((_) {
      print('connection to vm-service closed');
      return disconnect();
    }).catchError((e) {
      print('error connecting to the vm-service');
      return disconnect();
    });
    return peer;
  }

  /// Retrieves the ID of the main isolate using the service protocol.
  Future<String> _computeMainId() async {
    var vm = await rpc.sendRequest('getVM', {});
    var isolates = vm['isolates'];
    for (var isolate in isolates) {
      if (isolate['name'].contains(r'$main')) {
        return isolate['id'];
      }
    }
    return isolates.first['id'];
  }

  /// Send a request to the VM to reload sources from [entryUri].
  ///
  /// This will establish a connection with the VM assuming it is running on the
  /// local machine and listening on [port] for service protocol requests.
  ///
  /// The result is the JSON map received from the reload request.
  Future<Map> reload(Uri entryUri) async {
    print("reload($entryUri)");
    var id = await mainId;
    print("got $id, sending reloadSources rpc request");
    var result = await rpc.sendRequest('reloadSources', {
      'isolateId': id,
      'rootLibUri': entryUri.toString(),
    });
    print("got rpc result $result");
    return result;
  }

  Future resume() async {
    var id = await mainId;
    await rpc.sendRequest('resume', {'isolateId': id});
  }

  Future<Map> getIsolate() async {
    var id = await mainId;
    return (await rpc.sendRequest('getIsolate', {'isolateId': id})) as Map;
  }

  Future<Map> getScripts() async {
    var id = await mainId;
    return (await rpc.sendRequest('getScripts', {
      'isolateId': id,
    })) as Map;
  }

  Future<Map> getSourceReport([String? scriptId]) async {
    var id = await mainId;
    return (await rpc.sendRequest('getSourceReport', {
      'isolateId': id,
      if (scriptId != null) 'scriptId': scriptId,
      'reports': ['Coverage', 'PossibleBreakpoints'],
      'forceCompile': true,
    })) as Map;
  }

  Future<Map> getObject(String objectId) async {
    var id = await mainId;
    return (await rpc.sendRequest('getObject', {
      'isolateId': id,
      'objectId': objectId,
    })) as Map;
  }

  Future addBreakpoint(String scriptId, int line) async {
    var id = await mainId;
    return await rpc.sendRequest('addBreakpoint', {
      'isolateId': id,
      'scriptId': scriptId,
      'line': line,
    });
  }

  Future removeBreakpoint(String breakpointId) async {
    var id = await mainId;
    return await rpc.sendRequest('removeBreakpoint', {
      'isolateId': id,
      'breakpointId': breakpointId,
    });
  }

  Future evaluateInFrame(String expression) async {
    var id = await mainId;
    var frameIndex = 0;
    return await rpc.sendRequest('evaluateInFrame', {
      'isolateId': id,
      "frameIndex": frameIndex,
      'expression': expression,
    });
  }

  Future forceGc() async {
    int expectGcAfter = new DateTime.now().millisecondsSinceEpoch;
    while (true) {
      var id = await mainId;
      Map result = (await rpc.sendRequest('getAllocationProfile', {
        'isolateId': id,
        "gc": true,
      })) as Map;
      String? lastGc = result["dateLastServiceGC"];
      if (lastGc != null && int.parse(lastGc) >= expectGcAfter) return;
    }
  }

  /// Close any connections used to communicate with the VM.
  Future disconnect() async {
    final rpc = this._rpc;
    if (rpc == null) return null;
    this._mainId = null;
    if (!rpc.isClosed) {
      var future = rpc.close();
      _rpc = null;
      return future;
    }
    return null;
  }
}
