Version 2.14.0-171.0.dev

Merge commit 'e2cd8be814d91cbe3ade42933d506508538858e9' into 'dev'
diff --git a/pkg/frontend_server/lib/compute_kernel.dart b/pkg/frontend_server/lib/compute_kernel.dart
deleted file mode 100644
index b6c5616..0000000
--- a/pkg/frontend_server/lib/compute_kernel.dart
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (c) 2021, 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.
-
-// @dart = 2.8
-
-/// A library to invoke the CFE to compute kernel summary files.
-///
-/// Used by `utils/bazel/kernel_worker.dart`.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:build_integration/file_system/multi_root.dart';
-import 'package:compiler/src/kernel/dart2js_target.dart';
-import 'package:dev_compiler/src/kernel/target.dart';
-import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
-import 'package:kernel/ast.dart' show Component, Library, Reference;
-import 'package:kernel/target/targets.dart';
-import 'package:vm/target/flutter.dart';
-import 'package:vm/target/flutter_runner.dart';
-import 'package:vm/target/vm.dart';
-
-/// If the last arg starts with `@`, this reads the file it points to and treats
-/// each line as an additional arg.
-///
-/// This is how individual work request args are differentiated from startup
-/// args in bazel (individual work request args go in that file).
-List<String> preprocessArgs(List<String> args) {
-  args = new List.from(args);
-  if (args.isEmpty) {
-    return args;
-  }
-  String lastArg = args.last;
-  if (lastArg.startsWith('@')) {
-    File argsFile = new File(lastArg.substring(1));
-    try {
-      args.removeLast();
-      args.addAll(argsFile.readAsLinesSync());
-    } on FileSystemException catch (e) {
-      throw new Exception('Failed to read file specified by $lastArg : $e');
-    }
-  }
-  return args;
-}
-
-/// An [ArgParser] for generating kernel summaries.
-final summaryArgsParser = new ArgParser()
-  ..addFlag('help', negatable: false, abbr: 'h')
-  ..addFlag('exclude-non-sources',
-      negatable: false,
-      help: 'Whether source files loaded implicitly should be included as '
-          'part of the summary.')
-  ..addFlag('summary-only',
-      defaultsTo: true,
-      negatable: true,
-      help: 'Whether to only build summary files.')
-  ..addOption('target',
-      allowed: const [
-        'vm',
-        'flutter',
-        'flutter_runner',
-        'dart2js',
-        'ddc',
-      ],
-      help: 'Build kernel for the vm, flutter, flutter_runner, dart2js or ddc')
-  ..addOption('dart-sdk-summary')
-  ..addMultiOption('input-summary')
-  ..addMultiOption('input-linked')
-  ..addMultiOption('multi-root')
-  ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-multi-root')
-  ..addOption('libraries-file')
-  ..addOption('packages-file')
-  ..addMultiOption('source')
-  ..addOption('output')
-  ..addFlag('reuse-compiler-result', defaultsTo: false)
-  ..addFlag('use-incremental-compiler', defaultsTo: false)
-  ..addOption('used-inputs')
-  ..addFlag('track-widget-creation', defaultsTo: false)
-  ..addMultiOption('enable-experiment',
-      help: 'Enable a language experiment when invoking the CFE.')
-  ..addMultiOption('define', abbr: 'D')
-  ..addFlag('verbose', defaultsTo: false)
-  ..addFlag('sound-null-safety', defaultsTo: false)
-  ..addOption('verbosity',
-      defaultsTo: fe.Verbosity.defaultValue,
-      help: 'Sets the verbosity level used for filtering messages during '
-          'compilation.',
-      allowed: fe.Verbosity.allowedValues,
-      allowedHelp: fe.Verbosity.allowedValuesHelp);
-
-class ComputeKernelResult {
-  final bool succeeded;
-  final fe.InitializedCompilerState previousState;
-
-  ComputeKernelResult(this.succeeded, this.previousState);
-}
-
-/// Computes a kernel file based on [args].
-///
-/// If [isWorker] is true then exit codes will not be set on failure.
-///
-/// If [outputBuffer] is provided then messages will be written to that buffer
-/// instead of printed to the console.
-///
-/// Returns whether or not the summary was successfully output.
-Future<ComputeKernelResult> computeKernel(List<String> args,
-    {bool isWorker: false,
-    StringBuffer outputBuffer,
-    Map<Uri, List<int>> inputDigests,
-    fe.InitializedCompilerState previousState}) async {
-  inputDigests ??= <Uri, List<int>>{};
-  dynamic out = outputBuffer ?? stderr;
-  bool succeeded = true;
-
-  var parsedArgs = summaryArgsParser.parse(args);
-
-  if (parsedArgs['help']) {
-    out.writeln(summaryArgsParser.usage);
-    if (!isWorker) exit(0);
-    return new ComputeKernelResult(false, previousState);
-  }
-
-  // Bazel creates an overlay file system where some files may be located in the
-  // source tree, some in a gendir, and some in a bindir. The multi-root file
-  // system hides this from the front end.
-  var multiRoots = parsedArgs['multi-root'].map(Uri.base.resolve).toList();
-  if (multiRoots.isEmpty) multiRoots.add(Uri.base);
-  var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'],
-      multiRoots, fe.StandardFileSystem.instance);
-  var sources = (parsedArgs['source'] as List<String>).map(toUri).toList();
-  var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
-
-  var nnbdMode = parsedArgs['sound-null-safety'] as bool
-      ? fe.NnbdMode.Strong
-      : fe.NnbdMode.Weak;
-  var summaryOnly = parsedArgs['summary-only'] as bool;
-  var trackWidgetCreation = parsedArgs['track-widget-creation'] as bool;
-
-  // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
-  // compatible while we migrate existing clients of this tool.
-  var targetName =
-      (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
-  var targetFlags = new TargetFlags(
-      trackWidgetCreation: trackWidgetCreation,
-      enableNullSafety: nnbdMode == fe.NnbdMode.Strong);
-  Target target;
-  switch (targetName) {
-    case 'vm':
-      target = new VmTarget(targetFlags);
-      if (summaryOnly) {
-        out.writeln('error: --summary-only not supported for the vm target');
-      }
-      break;
-    case 'flutter':
-      target = new FlutterTarget(targetFlags);
-      if (summaryOnly) {
-        throw new ArgumentError(
-            'error: --summary-only not supported for the flutter target');
-      }
-      break;
-    case 'flutter_runner':
-      target = new FlutterRunnerTarget(targetFlags);
-      if (summaryOnly) {
-        throw new ArgumentError('error: --summary-only not supported for the '
-            'flutter_runner target');
-      }
-      break;
-    case 'dart2js':
-      target = new Dart2jsTarget('dart2js', targetFlags);
-      if (summaryOnly) {
-        out.writeln(
-            'error: --summary-only not supported for the dart2js target');
-      }
-      break;
-    case 'ddc':
-      // TODO(jakemac):If `generateKernel` changes to return a summary
-      // component, process the component instead.
-      target =
-          new DevCompilerSummaryTarget(sources, excludeNonSources, targetFlags);
-      if (!summaryOnly) {
-        out.writeln('error: --no-summary-only not supported for the '
-            'ddc target');
-      }
-      break;
-    default:
-      out.writeln('error: unsupported target: $targetName');
-  }
-
-  List<Uri> linkedInputs =
-      (parsedArgs['input-linked'] as List<String>).map(toUri).toList();
-
-  List<Uri> summaryInputs =
-      (parsedArgs['input-summary'] as List<String>).map(toUri).toList();
-
-  fe.InitializedCompilerState state;
-  bool usingIncrementalCompiler = false;
-  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
-  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
-  var verbose = parsedArgs['verbose'] as bool;
-  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
-
-  if (parsedArgs['use-incremental-compiler']) {
-    usingIncrementalCompiler = true;
-
-    // If digests weren't given and if not in worker mode, create fake data and
-    // ensure we don't have a previous state (as that wouldn't be safe with
-    // fake input digests).
-    if (!isWorker && inputDigests.isEmpty) {
-      previousState = null;
-      inputDigests[toUri(parsedArgs['dart-sdk-summary'])] = const [0];
-      for (Uri uri in summaryInputs) {
-        inputDigests[uri] = const [0];
-      }
-      for (Uri uri in linkedInputs) {
-        inputDigests[uri] = const [0];
-      }
-    }
-
-    state = await fe.initializeIncrementalCompiler(
-        previousState,
-        {
-          "target=$targetName",
-          "trackWidgetCreation=$trackWidgetCreation",
-          "multiRootScheme=${fileSystem.markerScheme}",
-          "multiRootRoots=${fileSystem.roots}",
-        },
-        toUri(parsedArgs['dart-sdk-summary']),
-        toUri(parsedArgs['packages-file']),
-        toUri(parsedArgs['libraries-file']),
-        [...summaryInputs, ...linkedInputs],
-        inputDigests,
-        target,
-        fileSystem,
-        (parsedArgs['enable-experiment'] as List<String>),
-        summaryOnly,
-        environmentDefines,
-        trackNeededDillLibraries: recordUsedInputs,
-        verbose: verbose,
-        nnbdMode: nnbdMode);
-  } else {
-    state = await fe.initializeCompiler(
-        // TODO(sigmund): pass an old state once we can make use of it.
-        null,
-        toUri(parsedArgs['dart-sdk-summary']),
-        toUri(parsedArgs['libraries-file']),
-        toUri(parsedArgs['packages-file']),
-        [...summaryInputs, ...linkedInputs],
-        target,
-        fileSystem,
-        parsedArgs['enable-experiment'] as List<String>,
-        environmentDefines,
-        verbose: verbose,
-        nnbdMode: nnbdMode);
-  }
-
-  void onDiagnostic(fe.DiagnosticMessage message) {
-    if (fe.Verbosity.shouldPrint(verbosity, message)) {
-      fe.printDiagnosticMessage(message, out.writeln);
-    }
-    if (message.severity == fe.Severity.error) {
-      succeeded = false;
-    }
-  }
-
-  List<int> kernel;
-  bool wroteUsedDills = false;
-  if (usingIncrementalCompiler) {
-    state.options.onDiagnostic = onDiagnostic;
-    Component incrementalComponent = await state.incrementalCompiler
-        .computeDelta(entryPoints: sources, fullComponent: true);
-
-    if (recordUsedInputs) {
-      Set<Uri> usedOutlines = {};
-      for (Library lib in state.incrementalCompiler.neededDillLibraries) {
-        if (lib.importUri.scheme == "dart") continue;
-        Uri uri = state.libraryToInputDill[lib.importUri];
-        if (uri == null) {
-          throw new StateError("Library ${lib.importUri} was recorded as used, "
-              "but was not in the list of known libraries.");
-        }
-        usedOutlines.add(uri);
-      }
-      var outputUsedFile = new File(parsedArgs["used-inputs"]);
-      outputUsedFile.createSync(recursive: true);
-      outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
-      wroteUsedDills = true;
-    }
-
-    kernel = await state.incrementalCompiler.context.runInContext((_) {
-      if (summaryOnly) {
-        incrementalComponent.uriToSource.clear();
-        incrementalComponent.problemsAsJson = null;
-        incrementalComponent.setMainMethodAndMode(
-            null, true, incrementalComponent.mode);
-        target.performOutlineTransformations(incrementalComponent);
-        makeStable(incrementalComponent);
-        return Future.value(fe.serializeComponent(incrementalComponent,
-            includeSources: false, includeOffsets: false));
-      }
-
-      makeStable(incrementalComponent);
-
-      return Future.value(fe.serializeComponent(incrementalComponent,
-          filter: excludeNonSources
-              ? (library) => sources.contains(library.importUri)
-              : null,
-          includeOffsets: true));
-    });
-  } else if (summaryOnly) {
-    kernel = await fe.compileSummary(state, sources, onDiagnostic,
-        includeOffsets: false);
-  } else {
-    Component component =
-        await fe.compileComponent(state, sources, onDiagnostic);
-    kernel = fe.serializeComponent(component,
-        filter: excludeNonSources
-            ? (library) => sources.contains(library.importUri)
-            : null,
-        includeOffsets: true);
-  }
-  state.options.onDiagnostic = null; // See http://dartbug.com/36983.
-
-  if (!wroteUsedDills && recordUsedInputs) {
-    // The path taken didn't record inputs used: Say we used everything.
-    var outputUsedFile = new File(parsedArgs["used-inputs"]);
-    outputUsedFile.createSync(recursive: true);
-    Set<Uri> allFiles = {...summaryInputs, ...linkedInputs};
-    outputUsedFile.writeAsStringSync(allFiles.join("\n"));
-    wroteUsedDills = true;
-  }
-
-  if (kernel != null) {
-    var outputFile = new File(parsedArgs['output']);
-    outputFile.createSync(recursive: true);
-    outputFile.writeAsBytesSync(kernel);
-  } else {
-    assert(!succeeded);
-  }
-
-  return new ComputeKernelResult(succeeded, state);
-}
-
-/// Make sure the output is stable by sorting libraries and additional exports.
-void makeStable(Component c) {
-  // Make sure the output is stable.
-  c.libraries.sort((l1, l2) {
-    return "${l1.fileUri}".compareTo("${l2.fileUri}");
-  });
-  c.problemsAsJson?.sort();
-  c.computeCanonicalNames();
-  for (Library library in c.libraries) {
-    library.additionalExports.sort((Reference r1, Reference r2) {
-      return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
-    });
-    library.problemsAsJson?.sort();
-  }
-}
-
-/// Extends the DevCompilerTarget to transform outlines to meet the requirements
-/// of summaries in bazel and package-build.
-///
-/// Build systems like package-build may provide the same input file twice to
-/// the summary worker, but only intends to have it in one output summary.  The
-/// convention is that if it is listed as a source, it is intended to be part of
-/// the output, if the source file was loaded as a dependency, then it was
-/// already included in a different summary.  The transformation below ensures
-/// that the output summary doesn't include those implicit inputs.
-///
-/// Note: this transformation is destructive and is only intended to be used
-/// when generating summaries.
-class DevCompilerSummaryTarget extends DevCompilerTarget {
-  final List<Uri> sources;
-  final bool excludeNonSources;
-
-  DevCompilerSummaryTarget(
-      this.sources, this.excludeNonSources, TargetFlags targetFlags)
-      : super(targetFlags);
-
-  @override
-  void performOutlineTransformations(Component component) {
-    super.performOutlineTransformations(component);
-    if (!excludeNonSources) return;
-
-    List<Library> libraries = new List.from(component.libraries);
-    component.libraries.clear();
-    Set<Uri> include = sources.toSet();
-    for (var lib in libraries) {
-      if (include.contains(lib.importUri)) {
-        component.libraries.add(lib);
-      } else {
-        // Excluding the library also means that their canonical names will not
-        // be computed as part of serialization, so we need to do that
-        // preemtively here to avoid errors when serializing references to
-        // elements of these libraries.
-        component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
-        lib.computeCanonicalNames();
-      }
-    }
-  }
-}
-
-Uri toUri(String uriString) {
-  if (uriString == null) return null;
-  // Windows-style paths use '\', so convert them to '/' in case they've been
-  // concatenated with Unix-style paths.
-  return Uri.base.resolve(uriString.replaceAll("\\", "/"));
-}
-
-Map<String, String> _parseEnvironmentDefines(List<String> args) {
-  var environment = <String, String>{};
-
-  for (var arg in args) {
-    var eq = arg.indexOf('=');
-    if (eq <= 0) {
-      var kind = eq == 0 ? 'name' : 'value';
-      throw FormatException('no $kind given to -D option `$arg`');
-    }
-    var name = arg.substring(0, eq);
-    var value = arg.substring(eq + 1);
-    environment[name] = value;
-  }
-
-  return environment;
-}
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 504c493..7932dab 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -8,10 +8,6 @@
 
 dependencies:
   args: ^1.4.4
-  build_integration:
-    path: ../build_integration
-  compiler:
-    path: ../compiler
   dev_compiler:
     path: ../dev_compiler
   front_end:
diff --git a/tools/VERSION b/tools/VERSION
index f6daae7..dcce38e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 170
+PRERELEASE 171
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/utils/bazel/kernel_worker.dart b/utils/bazel/kernel_worker.dart
index 3e68ac6..96f1e9a 100644
--- a/utils/bazel/kernel_worker.dart
+++ b/utils/bazel/kernel_worker.dart
@@ -15,9 +15,17 @@
 import 'dart:io';
 import 'dart:isolate';
 
+import 'package:args/args.dart';
 import 'package:bazel_worker/bazel_worker.dart';
+import 'package:build_integration/file_system/multi_root.dart';
+import 'package:dev_compiler/src/kernel/target.dart';
 import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
-import 'package:frontend_server/compute_kernel.dart';
+import 'package:kernel/ast.dart' show Component, Library, Reference;
+import 'package:kernel/target/targets.dart';
+import 'package:vm/target/vm.dart';
+import 'package:vm/target/flutter.dart';
+import 'package:vm/target/flutter_runner.dart';
+import 'package:compiler/src/kernel/dart2js_target.dart';
 
 /// [sendPort] may be passed in when started in an isolate. If provided, it is
 /// used for bazel worker communication instead of stdin/stdout.
@@ -60,17 +68,10 @@
       } else {
         previousState = null;
       }
-
-      /// Build a map of uris to digests.
-      final inputDigests = <Uri, List<int>>{};
-      for (var input in request.inputs) {
-        inputDigests[toUri(input.path)] = input.digest;
-      }
-
       var result = await computeKernel(request.arguments,
           isWorker: true,
           outputBuffer: outputBuffer,
-          inputDigests: inputDigests,
+          inputs: request.inputs,
           previousState: previousStateToPass);
       previousState = result.previousState;
       if (!result.succeeded) {
@@ -85,3 +86,413 @@
     return response;
   }
 }
+
+/// If the last arg starts with `@`, this reads the file it points to and treats
+/// each line as an additional arg.
+///
+/// This is how individual work request args are differentiated from startup
+/// args in bazel (inidividual work request args go in that file).
+List<String> preprocessArgs(List<String> args) {
+  args = new List.from(args);
+  if (args.isEmpty) {
+    return args;
+  }
+  String lastArg = args.last;
+  if (lastArg.startsWith('@')) {
+    File argsFile = new File(lastArg.substring(1));
+    try {
+      args.removeLast();
+      args.addAll(argsFile.readAsLinesSync());
+    } on FileSystemException catch (e) {
+      throw new Exception('Failed to read file specified by $lastArg : $e');
+    }
+  }
+  return args;
+}
+
+/// An [ArgParser] for generating kernel summaries.
+final summaryArgsParser = new ArgParser()
+  ..addFlag('help', negatable: false, abbr: 'h')
+  ..addFlag('exclude-non-sources',
+      negatable: false,
+      help: 'Whether source files loaded implicitly should be included as '
+          'part of the summary.')
+  ..addFlag('summary-only',
+      defaultsTo: true,
+      negatable: true,
+      help: 'Whether to only build summary files.')
+  ..addOption('target',
+      allowed: const [
+        'vm',
+        'flutter',
+        'flutter_runner',
+        'dart2js',
+        'ddc',
+      ],
+      help: 'Build kernel for the vm, flutter, flutter_runner, dart2js or ddc')
+  ..addOption('dart-sdk-summary')
+  ..addMultiOption('input-summary')
+  ..addMultiOption('input-linked')
+  ..addMultiOption('multi-root')
+  ..addOption('multi-root-scheme', defaultsTo: 'org-dartlang-multi-root')
+  ..addOption('libraries-file')
+  ..addOption('packages-file')
+  ..addMultiOption('source')
+  ..addOption('output')
+  ..addFlag('reuse-compiler-result', defaultsTo: false)
+  ..addFlag('use-incremental-compiler', defaultsTo: false)
+  ..addOption('used-inputs')
+  ..addFlag('track-widget-creation', defaultsTo: false)
+  ..addMultiOption('enable-experiment',
+      help: 'Enable a language experiment when invoking the CFE.')
+  ..addMultiOption('define', abbr: 'D')
+  ..addFlag('verbose', defaultsTo: false)
+  ..addFlag('sound-null-safety', defaultsTo: false)
+  ..addOption('verbosity',
+      defaultsTo: fe.Verbosity.defaultValue,
+      help: 'Sets the verbosity level used for filtering messages during '
+          'compilation.',
+      allowed: fe.Verbosity.allowedValues,
+      allowedHelp: fe.Verbosity.allowedValuesHelp);
+
+class ComputeKernelResult {
+  final bool succeeded;
+  final fe.InitializedCompilerState previousState;
+
+  ComputeKernelResult(this.succeeded, this.previousState);
+}
+
+/// Computes a kernel file based on [args].
+///
+/// If [isWorker] is true then exit codes will not be set on failure.
+///
+/// If [outputBuffer] is provided then messages will be written to that buffer
+/// instead of printed to the console.
+///
+/// Returns whether or not the summary was successfully output.
+Future<ComputeKernelResult> computeKernel(List<String> args,
+    {bool isWorker: false,
+    StringBuffer outputBuffer,
+    Iterable<Input> inputs,
+    fe.InitializedCompilerState previousState}) async {
+  dynamic out = outputBuffer ?? stderr;
+  bool succeeded = true;
+
+  var parsedArgs = summaryArgsParser.parse(args);
+
+  if (parsedArgs['help']) {
+    out.writeln(summaryArgsParser.usage);
+    if (!isWorker) exit(0);
+    return new ComputeKernelResult(false, previousState);
+  }
+
+  // Bazel creates an overlay file system where some files may be located in the
+  // source tree, some in a gendir, and some in a bindir. The multi-root file
+  // system hides this from the front end.
+  var multiRoots = parsedArgs['multi-root'].map(Uri.base.resolve).toList();
+  if (multiRoots.isEmpty) multiRoots.add(Uri.base);
+  var fileSystem = new MultiRootFileSystem(parsedArgs['multi-root-scheme'],
+      multiRoots, fe.StandardFileSystem.instance);
+  var sources = (parsedArgs['source'] as List<String>).map(_toUri).toList();
+  var excludeNonSources = parsedArgs['exclude-non-sources'] as bool;
+
+  var nnbdMode = parsedArgs['sound-null-safety'] as bool
+      ? fe.NnbdMode.Strong
+      : fe.NnbdMode.Weak;
+  var summaryOnly = parsedArgs['summary-only'] as bool;
+  var trackWidgetCreation = parsedArgs['track-widget-creation'] as bool;
+
+  // TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
+  // compatible while we migrate existing clients of this tool.
+  var targetName =
+      (parsedArgs['target'] as String) ?? (summaryOnly ? 'ddc' : 'vm');
+  var targetFlags = new TargetFlags(
+      trackWidgetCreation: trackWidgetCreation,
+      enableNullSafety: nnbdMode == fe.NnbdMode.Strong);
+  Target target;
+  switch (targetName) {
+    case 'vm':
+      target = new VmTarget(targetFlags);
+      if (summaryOnly) {
+        out.writeln('error: --summary-only not supported for the vm target');
+      }
+      break;
+    case 'flutter':
+      target = new FlutterTarget(targetFlags);
+      if (summaryOnly) {
+        throw new ArgumentError(
+            'error: --summary-only not supported for the flutter target');
+      }
+      break;
+    case 'flutter_runner':
+      target = new FlutterRunnerTarget(targetFlags);
+      if (summaryOnly) {
+        throw new ArgumentError('error: --summary-only not supported for the '
+            'flutter_runner target');
+      }
+      break;
+    case 'dart2js':
+      target = new Dart2jsTarget('dart2js', targetFlags);
+      if (summaryOnly) {
+        out.writeln(
+            'error: --summary-only not supported for the dart2js target');
+      }
+      break;
+    case 'ddc':
+      // TODO(jakemac):If `generateKernel` changes to return a summary
+      // component, process the component instead.
+      target =
+          new DevCompilerSummaryTarget(sources, excludeNonSources, targetFlags);
+      if (!summaryOnly) {
+        out.writeln('error: --no-summary-only not supported for the '
+            'ddc target');
+      }
+      break;
+    default:
+      out.writeln('error: unsupported target: $targetName');
+  }
+
+  List<Uri> linkedInputs =
+      (parsedArgs['input-linked'] as List<String>).map(_toUri).toList();
+
+  List<Uri> summaryInputs =
+      (parsedArgs['input-summary'] as List<String>).map(_toUri).toList();
+
+  fe.InitializedCompilerState state;
+  bool usingIncrementalCompiler = false;
+  bool recordUsedInputs = parsedArgs["used-inputs"] != null;
+  var environmentDefines = _parseEnvironmentDefines(parsedArgs['define']);
+  var verbose = parsedArgs['verbose'] as bool;
+  var verbosity = fe.Verbosity.parseArgument(parsedArgs['verbosity']);
+
+  if (parsedArgs['use-incremental-compiler']) {
+    usingIncrementalCompiler = true;
+
+    /// Build a map of uris to digests.
+    final inputDigests = <Uri, List<int>>{};
+    if (inputs != null) {
+      for (var input in inputs) {
+        inputDigests[_toUri(input.path)] = input.digest;
+      }
+    }
+
+    // If digests weren't given and if not in worker mode, create fake data and
+    // ensure we don't have a previous state (as that wouldn't be safe with
+    // fake input digests).
+    if (!isWorker && inputDigests.isEmpty) {
+      previousState = null;
+      inputDigests[_toUri(parsedArgs['dart-sdk-summary'])] = const [0];
+      for (Uri uri in summaryInputs) {
+        inputDigests[uri] = const [0];
+      }
+      for (Uri uri in linkedInputs) {
+        inputDigests[uri] = const [0];
+      }
+    }
+
+    state = await fe.initializeIncrementalCompiler(
+        previousState,
+        {
+          "target=$targetName",
+          "trackWidgetCreation=$trackWidgetCreation",
+          "multiRootScheme=${fileSystem.markerScheme}",
+          "multiRootRoots=${fileSystem.roots}",
+        },
+        _toUri(parsedArgs['dart-sdk-summary']),
+        _toUri(parsedArgs['packages-file']),
+        _toUri(parsedArgs['libraries-file']),
+        [...summaryInputs, ...linkedInputs],
+        inputDigests,
+        target,
+        fileSystem,
+        (parsedArgs['enable-experiment'] as List<String>),
+        summaryOnly,
+        environmentDefines,
+        trackNeededDillLibraries: recordUsedInputs,
+        verbose: verbose,
+        nnbdMode: nnbdMode);
+  } else {
+    state = await fe.initializeCompiler(
+        // TODO(sigmund): pass an old state once we can make use of it.
+        null,
+        _toUri(parsedArgs['dart-sdk-summary']),
+        _toUri(parsedArgs['libraries-file']),
+        _toUri(parsedArgs['packages-file']),
+        [...summaryInputs, ...linkedInputs],
+        target,
+        fileSystem,
+        parsedArgs['enable-experiment'] as List<String>,
+        environmentDefines,
+        verbose: verbose,
+        nnbdMode: nnbdMode);
+  }
+
+  void onDiagnostic(fe.DiagnosticMessage message) {
+    if (fe.Verbosity.shouldPrint(verbosity, message)) {
+      fe.printDiagnosticMessage(message, out.writeln);
+    }
+    if (message.severity == fe.Severity.error) {
+      succeeded = false;
+    }
+  }
+
+  List<int> kernel;
+  bool wroteUsedDills = false;
+  if (usingIncrementalCompiler) {
+    state.options.onDiagnostic = onDiagnostic;
+    Component incrementalComponent = await state.incrementalCompiler
+        .computeDelta(entryPoints: sources, fullComponent: true);
+
+    if (recordUsedInputs) {
+      Set<Uri> usedOutlines = {};
+      for (Library lib in state.incrementalCompiler.neededDillLibraries) {
+        if (lib.importUri.scheme == "dart") continue;
+        Uri uri = state.libraryToInputDill[lib.importUri];
+        if (uri == null) {
+          throw new StateError("Library ${lib.importUri} was recorded as used, "
+              "but was not in the list of known libraries.");
+        }
+        usedOutlines.add(uri);
+      }
+      var outputUsedFile = new File(parsedArgs["used-inputs"]);
+      outputUsedFile.createSync(recursive: true);
+      outputUsedFile.writeAsStringSync(usedOutlines.join("\n"));
+      wroteUsedDills = true;
+    }
+
+    kernel = await state.incrementalCompiler.context.runInContext((_) {
+      if (summaryOnly) {
+        incrementalComponent.uriToSource.clear();
+        incrementalComponent.problemsAsJson = null;
+        incrementalComponent.setMainMethodAndMode(
+            null, true, incrementalComponent.mode);
+        target.performOutlineTransformations(incrementalComponent);
+        makeStable(incrementalComponent);
+        return Future.value(fe.serializeComponent(incrementalComponent,
+            includeSources: false, includeOffsets: false));
+      }
+
+      makeStable(incrementalComponent);
+
+      return Future.value(fe.serializeComponent(incrementalComponent,
+          filter: excludeNonSources
+              ? (library) => sources.contains(library.importUri)
+              : null,
+          includeOffsets: true));
+    });
+  } else if (summaryOnly) {
+    kernel = await fe.compileSummary(state, sources, onDiagnostic,
+        includeOffsets: false);
+  } else {
+    Component component =
+        await fe.compileComponent(state, sources, onDiagnostic);
+    kernel = fe.serializeComponent(component,
+        filter: excludeNonSources
+            ? (library) => sources.contains(library.importUri)
+            : null,
+        includeOffsets: true);
+  }
+  state.options.onDiagnostic = null; // See http://dartbug.com/36983.
+
+  if (!wroteUsedDills && recordUsedInputs) {
+    // The path taken didn't record inputs used: Say we used everything.
+    var outputUsedFile = new File(parsedArgs["used-inputs"]);
+    outputUsedFile.createSync(recursive: true);
+    Set<Uri> allFiles = {...summaryInputs, ...linkedInputs};
+    outputUsedFile.writeAsStringSync(allFiles.join("\n"));
+    wroteUsedDills = true;
+  }
+
+  if (kernel != null) {
+    var outputFile = new File(parsedArgs['output']);
+    outputFile.createSync(recursive: true);
+    outputFile.writeAsBytesSync(kernel);
+  } else {
+    assert(!succeeded);
+  }
+
+  return new ComputeKernelResult(succeeded, state);
+}
+
+/// Make sure the output is stable by sorting libraries and additional exports.
+void makeStable(Component c) {
+  // Make sure the output is stable.
+  c.libraries.sort((l1, l2) {
+    return "${l1.fileUri}".compareTo("${l2.fileUri}");
+  });
+  c.problemsAsJson?.sort();
+  c.computeCanonicalNames();
+  for (Library library in c.libraries) {
+    library.additionalExports.sort((Reference r1, Reference r2) {
+      return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
+    });
+    library.problemsAsJson?.sort();
+  }
+}
+
+/// Extends the DevCompilerTarget to transform outlines to meet the requirements
+/// of summaries in bazel and package-build.
+///
+/// Build systems like package-build may provide the same input file twice to
+/// the summary worker, but only intends to have it in one output summary.  The
+/// convention is that if it is listed as a source, it is intended to be part of
+/// the output, if the source file was loaded as a dependency, then it was
+/// already included in a different summary.  The transformation below ensures
+/// that the output summary doesn't include those implicit inputs.
+///
+/// Note: this transformation is destructive and is only intended to be used
+/// when generating summaries.
+class DevCompilerSummaryTarget extends DevCompilerTarget {
+  final List<Uri> sources;
+  final bool excludeNonSources;
+
+  DevCompilerSummaryTarget(
+      this.sources, this.excludeNonSources, TargetFlags targetFlags)
+      : super(targetFlags);
+
+  @override
+  void performOutlineTransformations(Component component) {
+    super.performOutlineTransformations(component);
+    if (!excludeNonSources) return;
+
+    List<Library> libraries = new List.from(component.libraries);
+    component.libraries.clear();
+    Set<Uri> include = sources.toSet();
+    for (var lib in libraries) {
+      if (include.contains(lib.importUri)) {
+        component.libraries.add(lib);
+      } else {
+        // Excluding the library also means that their canonical names will not
+        // be computed as part of serialization, so we need to do that
+        // preemtively here to avoid errors when serializing references to
+        // elements of these libraries.
+        component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
+        lib.computeCanonicalNames();
+      }
+    }
+  }
+}
+
+Uri _toUri(String uriString) {
+  if (uriString == null) return null;
+  // Windows-style paths use '\', so convert them to '/' in case they've been
+  // concatenated with Unix-style paths.
+  return Uri.base.resolve(uriString.replaceAll("\\", "/"));
+}
+
+Map<String, String> _parseEnvironmentDefines(List<String> args) {
+  var environment = <String, String>{};
+
+  for (var arg in args) {
+    var eq = arg.indexOf('=');
+    if (eq <= 0) {
+      var kind = eq == 0 ? 'name' : 'value';
+      throw FormatException('no $kind given to -D option `$arg`');
+    }
+    var name = arg.substring(0, eq);
+    var value = arg.substring(eq + 1);
+    environment[name] = value;
+  }
+
+  return environment;
+}