| Index: lib/src/compiler/command.dart
|
| diff --git a/lib/src/compiler/command.dart b/lib/src/compiler/command.dart
|
| index 2b0eca1c297132f40c324d4c4c14dccb066bb00d..fe83d8be0155223046252d35858ca4008a56e529 100644
|
| --- a/lib/src/compiler/command.dart
|
| +++ b/lib/src/compiler/command.dart
|
| @@ -4,10 +4,12 @@
|
|
|
| import 'dart:convert' show JSON;
|
| import 'dart:io';
|
| +import 'package:args/args.dart';
|
| import 'package:args/command_runner.dart';
|
| import 'package:analyzer/src/generated/source.dart' show Source;
|
| import 'package:analyzer/src/summary/package_bundle_reader.dart'
|
| show InSummarySource;
|
| +import 'package:bazel_worker/bazel_worker.dart';
|
| import 'compiler.dart'
|
| show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler;
|
| import '../analyzer/context.dart' show AnalyzerOptions;
|
| @@ -20,26 +22,38 @@ class CompileCommand extends Command {
|
|
|
| CompileCommand() {
|
| argParser.addOption('out', abbr: 'o', help: 'Output file (required)');
|
| + argParser.addFlag('persistent_worker',
|
| + help: 'Run in a persistent Bazel worker (http://bazel.io/)\n',
|
| + defaultsTo: false,
|
| + hide: true);
|
| CompilerOptions.addArguments(argParser);
|
| AnalyzerOptions.addArguments(argParser);
|
| }
|
|
|
| @override
|
| void run() {
|
| - var compilerOptions = new CompilerOptions.fromArguments(argResults);
|
| var compiler =
|
| new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults));
|
| + if (argResults['persistent_worker']) {
|
| + new _CompilerWorker(compiler, argParser, this, argResults.rest).run();
|
| + } else {
|
| + compile(compiler, new CompilerOptions.fromArguments(argResults),
|
| + argResults['out'], argResults.rest);
|
| + }
|
| + }
|
|
|
| - var outPath = argResults['out'];
|
| + void compile(ModuleCompiler compiler, CompilerOptions compilerOptions,
|
| + String outPath, List<String> extraArgs,
|
| + {void forEachError(String error): print}) {
|
| if (outPath == null) {
|
| usageException('Please include the output file location. For example:\n'
|
| ' -o PATH/TO/OUTPUT_FILE.js');
|
| }
|
| - var unit = new BuildUnit(path.basenameWithoutExtension(outPath),
|
| - argResults.rest, _moduleForLibrary);
|
| + var unit = new BuildUnit(
|
| + path.basenameWithoutExtension(outPath), extraArgs, _moduleForLibrary);
|
|
|
| JSModuleFile module = compiler.compile(unit, compilerOptions);
|
| - module.errors.forEach(print);
|
| + module.errors.forEach(forEachError);
|
|
|
| if (!module.isValid) throw new CompileErrorException();
|
|
|
| @@ -68,7 +82,82 @@ class CompileCommand extends Command {
|
| }
|
| }
|
|
|
| +/// Handles [error] in a uniform fashion. Returns the proper exit code and calls
|
| +/// [messageHandler] with messages.
|
| +int handleError(dynamic error, dynamic stackTrace, List<String> args,
|
| + {void messageHandler(Object message): print}) {
|
| + if (error is UsageException) {
|
| + // Incorrect usage, input file not found, etc.
|
| + messageHandler(error);
|
| + return 64;
|
| + } else if (error is CompileErrorException) {
|
| + // Code has error(s) and failed to compile.
|
| + messageHandler(error);
|
| + return 1;
|
| + } else {
|
| + // Anything else is likely a compiler bug.
|
| + //
|
| + // --unsafe-force-compile is a bit of a grey area, but it's nice not to
|
| + // crash while compiling
|
| + // (of course, output code may crash, if it had errors).
|
| + //
|
| + messageHandler("");
|
| + messageHandler("We're sorry, you've found a bug in our compiler.");
|
| + messageHandler("You can report this bug at:");
|
| + messageHandler(" https://github.com/dart-lang/dev_compiler/issues");
|
| + messageHandler("");
|
| + messageHandler(
|
| + "Please include the information below in your report, along with");
|
| + messageHandler(
|
| + "any other information that may help us track it down. Thanks!");
|
| + messageHandler("");
|
| + messageHandler(" dartdevc arguments: " + args.join(' '));
|
| + messageHandler(" dart --version: ${Platform.version}");
|
| + messageHandler("");
|
| + messageHandler("```");
|
| + messageHandler(error);
|
| + messageHandler(stackTrace);
|
| + messageHandler("```");
|
| + return 1;
|
| + }
|
| +}
|
| +
|
| /// Thrown when the input source code has errors.
|
| class CompileErrorException implements Exception {
|
| toString() => '\nPlease fix all errors before compiling (warnings are okay).';
|
| }
|
| +
|
| +/// Runs the compiler worker loop.
|
| +class _CompilerWorker extends SyncWorkerLoop {
|
| + final ModuleCompiler compiler;
|
| + final ArgParser argParser;
|
| + final CompileCommand compileCommand;
|
| + final List<String> extraArgs;
|
| +
|
| + _CompilerWorker(
|
| + this.compiler, this.argParser, this.compileCommand, this.extraArgs)
|
| + : super();
|
| +
|
| + WorkResponse performRequest(WorkRequest request) {
|
| + var argResults = argParser.parse(request.arguments);
|
| + var output = new StringBuffer();
|
| + try {
|
| + compileCommand.compile(
|
| + compiler,
|
| + new CompilerOptions.fromArguments(argResults),
|
| + argResults['out'],
|
| + new List.from(argResults.rest)..addAll(extraArgs),
|
| + forEachError: output.writeln);
|
| + return new WorkResponse()
|
| + ..exitCode = EXIT_CODE_OK
|
| + ..output = output.toString();
|
| + } catch (e, s) {
|
| + var response = new WorkResponse();
|
| + var output = new StringBuffer();
|
| + response.exitCode =
|
| + handleError(e, s, request.arguments, messageHandler: output.writeln);
|
| + response.output = output.toString();
|
| + return response;
|
| + }
|
| + }
|
| +}
|
|
|