// Copyright (c) 2017, 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. /// A tool that invokes the CFE to compute kernel summary files. /// /// This script can be used as a command-line command or a persistent server. /// The server is implemented using the bazel worker protocol, so it can be used /// within bazel as is. Other tools (like pub-build and package-build) also /// use this persistent worker via the same protocol. import 'dart:async'; import 'dart:io'; import 'dart:isolate'; import 'package:bazel_worker/bazel_worker.dart'; import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe; import 'package:frontend_server/compute_kernel.dart'; /// [sendPort] may be passed in when started in an isolate. If provided, it is /// used for bazel worker communication instead of stdin/stdout. main(List args, SendPort? sendPort) async { args = preprocessArgs(args); if (args.contains('--persistent_worker')) { if (args.length != 1) { throw new StateError( "unexpected args, expected only --persistent-worker but got: $args", ); } await new KernelWorker(sendPort: sendPort).run(); } else { var result = await computeKernel(args); if (!result.succeeded) { exitCode = 15; } } } /// A bazel worker loop that can compute full or summary kernel files. class KernelWorker extends AsyncWorkerLoop { fe.InitializedCompilerState? previousState; /// If [sendPort] is provided it is used for bazel worker communication /// instead of stdin/stdout. KernelWorker({SendPort? sendPort}) : super( connection: sendPort == null ? null : SendPortAsyncWorkerConnection(sendPort), ); Future performRequest(WorkRequest request) async { var outputBuffer = new StringBuffer(); var response = new WorkResponse()..exitCode = 0; try { fe.InitializedCompilerState? previousStateToPass; if (request.arguments.contains("--reuse-compiler-result")) { previousStateToPass = previousState; } else { previousState = null; } /// Build a map of uris to digests. final inputDigests = >{}; for (var input in request.inputs) { inputDigests[toUri(input.path)] = input.digest; } var result = await computeKernel( request.arguments, isWorker: true, outputBuffer: outputBuffer, inputDigests: inputDigests, previousState: previousStateToPass, ); previousState = result.previousState; if (!result.succeeded) { response.exitCode = 15; } } catch (e, s) { outputBuffer.writeln(e); outputBuffer.writeln(s); response.exitCode = 15; } response.output = outputBuffer.toString(); return response; } }