Index: pkg/front_end/tool/bazel/worker.dart |
diff --git a/pkg/front_end/tool/bazel/worker.dart b/pkg/front_end/tool/bazel/worker.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c27ea04dc7ec0182ff889e1d453183bf9f621f12 |
--- /dev/null |
+++ b/pkg/front_end/tool/bazel/worker.dart |
@@ -0,0 +1,110 @@ |
+// 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. |
+import 'dart:async'; |
+import 'dart:io'; |
+ |
+import 'package:args/args.dart'; |
+import 'package:bazel_worker/bazel_worker.dart'; |
+import 'package:front_end/front_end.dart' hide FileSystemException; |
+import 'package:front_end/src/fasta/command_line_reporting.dart'; |
+import 'package:kernel/target/targets.dart'; |
+ |
+main(List<String> args) 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 SummaryWorker().run(); |
+ } else { |
+ await computeSummary(args); |
+ } |
+} |
+ |
+/// A bazel worker loop that can compute summaries. |
+class SummaryWorker extends AsyncWorkerLoop { |
+ Future<WorkResponse> performRequest(WorkRequest request) async { |
+ var outputBuffer = new StringBuffer(); |
+ var response = new WorkResponse()..exitCode = 0; |
+ try { |
+ await computeSummary(request.arguments, |
+ isWorker: true, outputBuffer: outputBuffer); |
+ } catch (_, s) { |
+ outputBuffer.writeln(s); |
+ response.exitCode = 15; |
+ } |
+ response.output = outputBuffer.toString(); |
+ 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() |
+ ..addOption('dart-sdk-summary') |
+ ..addOption('input-summary', allowMultiple: true) |
+ ..addOption('multi-root', allowMultiple: true) |
+ ..addOption('packages-file') |
+ ..addOption('source', allowMultiple: true) |
+ ..addOption('output'); |
+ |
+/// Computes a kernel summary 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. |
+Future computeSummary(List<String> args, |
+ {bool isWorker: false, StringBuffer outputBuffer}) async { |
+ var parsedArgs = summaryArgsParser.parse(args); |
+ var options = new CompilerOptions() |
+ ..packagesFileUri = Uri.parse(parsedArgs['packages-file']) |
+ ..inputSummaries = parsedArgs['input-summary'].map(Uri.parse).toList() |
+ ..sdkSummary = Uri.parse(parsedArgs['dart-sdk-summary']) |
+ ..multiRoots = parsedArgs['multi-root'].map(Uri.parse).toList() |
+ ..target = new NoneTarget(new TargetFlags()); |
+ |
+ if (outputBuffer != null) { |
+ options.onError = (CompilationMessage error) { |
+ var severityString = severityName(error.severity, capitalized: true); |
+ outputBuffer.writeln('$severityString: ${error.message}'); |
+ if (error.severity != Severity.nit) { |
+ throw error; |
+ } |
+ }; |
+ } else { |
+ options.throwOnWarnings = true; |
ahe
2017/08/24 11:14:35
This is an internal option that makes Fasta crash
|
+ } |
+ |
+ var sources = parsedArgs['source'].map(Uri.parse).toList(); |
+ var program = await summaryFor(sources, options); |
+ |
+ var outputFile = new File(parsedArgs['output']); |
+ outputFile.createSync(recursive: true); |
+ outputFile.writeAsBytesSync(program); |
+} |