| Index: lib/src/compiler/command.dart
|
| diff --git a/lib/src/compiler/command.dart b/lib/src/compiler/command.dart
|
| index 545d1a4850ad19c930dca6b3ac9e67219b025c72..acf26675d156a24f6e46bd37d10a9774729a0372 100644
|
| --- a/lib/src/compiler/command.dart
|
| +++ b/lib/src/compiler/command.dart
|
| @@ -4,116 +4,169 @@
|
|
|
| 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 = () {
|
| + var argParser = new ArgParser()
|
| + ..addFlag('help', abbr: 'h', help: 'Display this message.')
|
| + ..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;
|
| +}();
|
| +
|
| +/// Runs a single compile for dartdevc.
|
| +///
|
| +/// 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;
|
| + ArgResults argResults;
|
| + try {
|
| + argResults = _argParser.parse(args);
|
| + } on FormatException catch (error) {
|
| + printFn('$error\n\n$_usageMessage');
|
| + return 64;
|
| }
|
| + try {
|
| + _compile(argResults, 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);
|
| + if (argResults['help']) {
|
| + printFn(_usageMessage);
|
| + return;
|
| + }
|
| + 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
|
| +}
|
| +
|
| +final _usageMessage =
|
| + 'Dart Development Compiler compiles Dart into a JavaScript module.'
|
| + '\n\n${_argParser.usage}';
|
| +
|
| +void _usageException(String message) {
|
| + throw new UsageException(message, _usageMessage);
|
| }
|
|
|
| /// Thrown when the input source code has errors.
|
|
|