Implement --help option and generalize option parsing.

Review URL: https://chromiumcodereview.appspot.com//10383086

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@7461 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
ahe@google.com
2012-05-09 14:24:29 +00:00
parent 29678aefe6
commit 6809cd37ff
+95 -29
View File
@@ -16,6 +16,38 @@
final String LIBRARY_ROOT = '../../../..';
typedef void HandleOption(String option);
class OptionHandler {
String pattern;
HandleOption handle;
OptionHandler(this.pattern, this.handle);
}
String extractParameter(String argument) {
return argument.substring(argument.indexOf('=') + 1);
}
void parseCommandLine(List<OptionHandler> handlers, List<String> argv) {
var patterns = <String>[];
for (OptionHandler handler in handlers) {
patterns.add(handler.pattern);
}
var pattern = new RegExp('^(${Strings.join(patterns, ")|(")})\$');
assert(pattern.groupCount() == handlers.length);
OUTER: for (String argument in argv) {
Match match = pattern.firstMatch(argument);
for (int i = 0; i < handlers.length; i++) {
if (match[i + 1] !== null) {
handlers[i].handle(argument);
continue OUTER;
}
}
throw 'Internal error: "$argument" did not match';
}
}
void compile(List<String> argv) {
Uri cwd = getCurrentDirectory();
bool throwOnError = false;
@@ -25,41 +57,43 @@ void compile(List<String> argv) {
Uri out = cwd.resolve('out.js');
List<String> options = new List<String>();
passThrough(String argument) => options.add(argument);
List<String> arguments = <String>[];
for (String argument in argv) {
if ('--throw-on-error' == argument) {
throwOnError = true;
} else if ('--suppress-warnings' == argument) {
showWarnings = false;
} else if ('--verbose' == argument) {
verbose = true;
} else if (argument.startsWith('--library-root=')) {
String path =
nativeToUriPath(argument.substring(argument.indexOf('=') + 1));
List<OptionHandler> handlers = <OptionHandler>[
new OptionHandler('--throw-on-error', (_) => throwOnError = true),
new OptionHandler('--suppress-warnings', (_) => showWarnings = false),
new OptionHandler('--verbose', (_) => verbose = true),
new OptionHandler('--library-root=.*', (String argument) {
String path = nativeToUriPath(extractParameter(argument));
if (!path.endsWith("/")) path = "$path/";
libraryRoot = cwd.resolve(path);
} else if (argument.startsWith('--out=')) {
String path =
nativeToUriPath(argument.substring(argument.indexOf('=') + 1));
out = cwd.resolve(path);
} else if ('--allow-mock-compilation' == argument) {
options.add(argument);
} else if ('--no-colors' == argument) {
colors.enabled = false;
} else if ('--enable-checked-mode' == argument) {
options.add(argument);
} else if (argument.startsWith('-')) {
fail('Unknown option $argument.');
} else {
}),
new OptionHandler('--out=.*', (String argument) {
out = cwd.resolve(nativeToUriPath(extractParameter(argument)));
}),
new OptionHandler('--allow-mock-compilation', passThrough),
new OptionHandler('--no-colors', (_) => colors.enabled = false),
new OptionHandler('--enable-checked-mode|--checked|-c',
(_) => passThrough('--enable_checked_mode')),
new OptionHandler('--help', (_) => helpAndExit()),
// The following two options must come last.
new OptionHandler('-.*', (String argument) {
fail('Error: unknown option "$argument".');
}),
new OptionHandler('.*', (String argument) {
arguments.add(nativeToUriPath(argument));
}
}
})
];
parseCommandLine(handlers, argv);
if (arguments.isEmpty()) {
fail('No file to compile.');
helpAndFail('Error: no file to compile.');
}
if (arguments.length > 1) {
var extra = arguments.getRange(1, arguments.length - 1);
fail('Extra arguments: $extra.');
helpAndFail('Error: extra arguments: ${Strings.join(extra, " ")}');
}
Map<String, SourceFile> sourceFiles = <SourceFile>{};
@@ -104,7 +138,7 @@ void compile(List<String> argv) {
// directly. In effect, we don't support truly asynchronous API.
String code = api.compile(uri, libraryRoot, provider, handler, options).value;
if (code === null) {
fail('Compilation failed.');
fail('Error: compilation failed.');
}
writeString(out, code);
int jsBytesWritten = code.length;
@@ -120,7 +154,7 @@ class AbortLeg {
void writeString(Uri uri, String text) {
if (uri.scheme != 'file') {
fail('Unhandled scheme ${uri.scheme}.');
fail('Error: unhandled scheme ${uri.scheme}.');
}
var file = new File(uriPathToNative(uri.path)).openSync(FileMode.WRITE);
file.writeStringSync(text);
@@ -148,6 +182,38 @@ void compilerMain(Options options) {
compile(argv);
}
void help() {
// This message should be no longer than 22 lines. The default
// terminal size normally 80x24. Two lines are used for the prompts
// before and after running the compiler.
print('''
dart2js [OPTIONS...] DART-FILE
A Dart to JavaScript compiler.
By default, the compiled JavaScript code is saved to a file named
out.js in the current directory.
Common options:
--help Display this message.
--out=FILE Save the output to FILE (default is out.js).
--checked Turn on checked mode in generated JavaScript code.
''');
}
void helpAndExit() {
help();
exit(0);
}
void helpAndFail(String message) {
help();
fail(message);
}
void main() {
try {
compilerMain(new Options());