Index: lib/src/compiler/command.dart |
diff --git a/lib/src/compiler/command.dart b/lib/src/compiler/command.dart |
index 545d1a4850ad19c930dca6b3ac9e67219b025c72..01b026e32da9d753065704c1e81ecb96ac0a1531 100644 |
--- a/lib/src/compiler/command.dart |
+++ b/lib/src/compiler/command.dart |
@@ -4,116 +4,156 @@ |
import 'dart:convert' show JSON; |
import 'dart:io'; |
-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:args/args.dart' show ArgParser, ArgResults; |
+import 'package:args/command_runner.dart' show UsageException; |
+import 'package:path/path.dart' as path; |
+ |
import 'compiler.dart' |
show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler; |
import '../analyzer/context.dart' show AnalyzerOptions; |
-import 'package:path/path.dart' as path; |
-typedef void MessageHandler(Object message); |
- |
-/// The command for invoking the modular compiler. |
-class CompileCommand extends Command { |
- final MessageHandler messageHandler; |
- CompilerOptions _compilerOptions; |
- |
- CompileCommand({MessageHandler messageHandler}) |
- : this.messageHandler = messageHandler ?? print { |
- argParser.addOption('out', abbr: 'o', help: 'Output file (required)'); |
- argParser.addOption('module-root', |
- help: 'Root module directory. ' |
- 'Generated module paths are relative to this root.'); |
- argParser.addOption('library-root', |
- help: 'Root of source files. ' |
- 'Generated library names are relative to this root.'); |
- argParser.addOption('build-root', |
- help: 'Deprecated in favor of --library-root'); |
- CompilerOptions.addArguments(argParser); |
- AnalyzerOptions.addArguments(argParser); |
+final ArgParser _argParser = () { |
Jennifer Messerly
2016/08/12 21:09:23
In case you're curious, our type inference would t
|
+ var argParser = new ArgParser() |
+ ..addOption('out', abbr: 'o', help: 'Output file (required)') |
+ ..addOption('module-root', |
+ help: 'Root module directory.\n' |
+ 'Generated module paths are relative to this root.') |
+ ..addOption('library-root', |
+ help: 'Root of source files.\n' |
+ 'Generated library names are relative to this root.') |
+ ..addOption('build-root', |
+ help: 'Deprecated in favor of --library-root', hide: true); |
+ AnalyzerOptions.addArguments(argParser); |
+ CompilerOptions.addArguments(argParser); |
+ return argParser; |
+}(); |
+ |
+/// The runs a single compile for dartdevc. |
nweiz
2016/08/12 21:16:38
Remove "The".
Jennifer Messerly
2016/08/12 21:58:42
Eeep, good catch!
|
+/// |
+/// This handles argument parsing, usage, error handling. |
+/// See bin/dartdevc.dart for the actual entry point, which includes Bazel |
+/// worker support. |
+int compile(List<String> args, {void printFn(Object obj)}) { |
+ printFn ??= print; |
+ try { |
+ _compile(_argParser.parse(args), printFn); |
+ return 0; |
+ } on UsageException catch (error) { |
+ // Incorrect usage, input file not found, etc. |
+ printFn(error); |
+ return 64; |
+ } on CompileErrorException catch (error) { |
+ // Code has error(s) and failed to compile. |
+ printFn(error); |
+ return 1; |
+ } catch (error, stackTrace) { |
+ // 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). |
+ // |
+ printFn(''' |
+We're sorry, you've found a bug in our compiler. |
+You can report this bug at: |
+ https://github.com/dart-lang/dev_compiler/issues |
+Please include the information below in your report, along with |
+any other information that may help us track it down. Thanks! |
+ dartdevc arguments: ${args.join(' ')} |
+ dart --version: ${Platform.version} |
+``` |
+$error |
+$stackTrace |
+```'''); |
+ return 70; |
} |
+} |
- get name => 'compile'; |
- get description => 'Compile a set of Dart files into a JavaScript module.'; |
- |
- @override |
- void run() { |
- var compiler = |
- new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults)); |
- _compilerOptions = new CompilerOptions.fromArguments(argResults); |
- var outPath = argResults['out']; |
+void _compile(ArgResults argResults, void printFn(Object obj)) { |
+ var compiler = |
+ new ModuleCompiler(new AnalyzerOptions.fromArguments(argResults)); |
+ var compilerOpts = new CompilerOptions.fromArguments(argResults); |
+ var outPath = argResults['out']; |
- if (outPath == null) { |
- usageException('Please include the output file location. For example:\n' |
- ' -o PATH/TO/OUTPUT_FILE.js'); |
- } |
+ if (outPath == null) { |
+ _usageException('Please include the output file location. For example:\n' |
+ ' -o PATH/TO/OUTPUT_FILE.js'); |
+ } |
- var libraryRoot = argResults['library-root'] as String; |
- libraryRoot ??= argResults['build-root'] as String; |
- if (libraryRoot != null) { |
- libraryRoot = path.absolute(libraryRoot); |
- } else { |
- libraryRoot = Directory.current.path; |
- } |
- var moduleRoot = argResults['module-root'] as String; |
- String modulePath; |
- if (moduleRoot != null) { |
- moduleRoot = path.absolute(moduleRoot); |
- if (!path.isWithin(moduleRoot, outPath)) { |
- usageException('Output file $outPath must be within the module root ' |
- 'directory $moduleRoot'); |
- } |
- modulePath = |
- path.withoutExtension(path.relative(outPath, from: moduleRoot)); |
- } else { |
- moduleRoot = path.dirname(outPath); |
- modulePath = path.basenameWithoutExtension(outPath); |
+ var libraryRoot = argResults['library-root'] as String; |
+ libraryRoot ??= argResults['build-root'] as String; |
+ if (libraryRoot != null) { |
+ libraryRoot = path.absolute(libraryRoot); |
+ } else { |
+ libraryRoot = Directory.current.path; |
+ } |
+ var moduleRoot = argResults['module-root'] as String; |
+ String modulePath; |
+ if (moduleRoot != null) { |
+ moduleRoot = path.absolute(moduleRoot); |
+ if (!path.isWithin(moduleRoot, outPath)) { |
+ _usageException('Output file $outPath must be within the module root ' |
+ 'directory $moduleRoot'); |
} |
+ modulePath = |
+ path.withoutExtension(path.relative(outPath, from: moduleRoot)); |
+ } else { |
+ moduleRoot = path.dirname(outPath); |
+ modulePath = path.basenameWithoutExtension(outPath); |
+ } |
- var unit = new BuildUnit(modulePath, libraryRoot, argResults.rest, |
- (source) => _moduleForLibrary(moduleRoot, source)); |
+ var unit = new BuildUnit(modulePath, libraryRoot, argResults.rest, |
+ (source) => _moduleForLibrary(moduleRoot, source, compilerOpts)); |
- JSModuleFile module = compiler.compile(unit, _compilerOptions); |
- module.errors.forEach(messageHandler); |
+ JSModuleFile module = compiler.compile(unit, compilerOpts); |
+ module.errors.forEach(printFn); |
- if (!module.isValid) throw new CompileErrorException(); |
+ if (!module.isValid) throw new CompileErrorException(); |
- // Write JS file, as well as source map and summary (if requested). |
- new File(outPath).writeAsStringSync(module.code); |
- if (module.sourceMap != null) { |
- var mapPath = outPath + '.map'; |
- new File(mapPath) |
- .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath))); |
- } |
- if (module.summaryBytes != null) { |
- var summaryPath = path.withoutExtension(outPath) + |
- '.${_compilerOptions.summaryExtension}'; |
- new File(summaryPath).writeAsBytesSync(module.summaryBytes); |
- } |
+ // Write JS file, as well as source map and summary (if requested). |
+ new File(outPath).writeAsStringSync(module.code); |
+ if (module.sourceMap != null) { |
+ var mapPath = outPath + '.map'; |
+ new File(mapPath) |
+ .writeAsStringSync(JSON.encode(module.placeSourceMap(mapPath))); |
} |
+ if (module.summaryBytes != null) { |
+ var summaryPath = |
+ path.withoutExtension(outPath) + '.${compilerOpts.summaryExtension}'; |
+ new File(summaryPath).writeAsBytesSync(module.summaryBytes); |
+ } |
+} |
- String _moduleForLibrary(String moduleRoot, Source source) { |
- if (source is InSummarySource) { |
- var summaryPath = source.summaryPath; |
- var ext = '.${_compilerOptions.summaryExtension}'; |
- if (path.isWithin(moduleRoot, summaryPath) && summaryPath.endsWith(ext)) { |
- var buildUnitPath = |
- summaryPath.substring(0, summaryPath.length - ext.length); |
- return path.relative(buildUnitPath, from: moduleRoot); |
- } |
- |
- throw usageException( |
- 'Imported file ${source.uri} is not within the module root ' |
- 'directory $moduleRoot'); |
+String _moduleForLibrary( |
+ String moduleRoot, Source source, CompilerOptions compilerOpts) { |
+ if (source is InSummarySource) { |
+ var summaryPath = source.summaryPath; |
+ var ext = '.${compilerOpts.summaryExtension}'; |
+ if (path.isWithin(moduleRoot, summaryPath) && summaryPath.endsWith(ext)) { |
+ var buildUnitPath = |
+ summaryPath.substring(0, summaryPath.length - ext.length); |
+ return path.relative(buildUnitPath, from: moduleRoot); |
} |
- throw usageException( |
- 'Imported file "${source.uri}" was not found as a summary or source ' |
- 'file. Please pass in either the summary or the source file ' |
- 'for this import.'); |
+ _usageException('Imported file ${source.uri} is not within the module root ' |
+ 'directory $moduleRoot'); |
} |
+ |
+ _usageException( |
+ 'Imported file "${source.uri}" was not found as a summary or source ' |
+ 'file. Please pass in either the summary or the source file ' |
+ 'for this import.'); |
+ return null; // unreachable |
+} |
+ |
+void _usageException(String message) { |
+ throw new UsageException( |
+ message, |
+ 'Dart Development Compiler compiles Dart into a JavaScript module.' |
+ '\n\n${_argParser.usage}'); |
} |
/// Thrown when the input source code has errors. |