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..93bd5e43d41d037fd291e6a5f36e626f2a5bd405 |
--- /dev/null |
+++ b/pkg/front_end/tool/bazel/worker.dart |
@@ -0,0 +1,114 @@ |
+// 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 { |
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
I'm still contemplating whether to put this here o
jakemac
2017/08/21 21:16:37
I don't feel that strongly, but analyzer/ddc both
|
+ 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 (isWorker) { |
+ options.setExitCodeOnProblem = false; |
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
this is already false by default :)
In your case
jakemac
2017/08/21 21:16:37
done
|
+ } |
+ |
+ 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; |
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
`throw` might not be the most user-friendly respon
jakemac
2017/08/21 21:16:37
The bazel worker handles errors and sends a proper
|
+ } |
+ }; |
+ } else { |
+ options.throwOnWarnings = true; |
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
our default error reporting throws and prints to t
jakemac
2017/08/21 21:16:37
I think the default handling is fine
|
+ } |
+ |
+ var sources = parsedArgs['source'].map(Uri.parse).toList(); |
Siggi Cherem (dart-lang)
2017/08/21 20:16:49
we intend to fix this, but we've had issues in the
jakemac
2017/08/21 21:16:37
These will be real uris with schemes yes
|
+ var program = await summaryFor(sources, options); |
+ |
+ var outputFile = new File(parsedArgs['output']); |
+ outputFile.createSync(recursive: true); |
+ outputFile.writeAsBytesSync(program); |
+} |