blob: 0e3ed28b12267b24c765c280c60851216d29aa20 [file] [log] [blame]
// Copyright (c) 2012, 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.
package com.google.dart.compiler;
import com.google.common.collect.Lists;
import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
import com.google.dart.compiler.util.apache.StringUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Options that can be specified on the command line.
*/
public class CommandLineOptions {
/**
* Command line options accepted by the {@link DartCompiler} entry point.
*/
public static class CompilerOptions {
@Option(name = "--batch", aliases = { "-batch" },
usage = "Batch mode (for unit testing)")
private boolean batch = false;
@Option(name = "--error_format",
usage = "Format errors as normal or machine")
private String errorFormat = "";
@Option(name = "--machine", //
usage = "Print errors in a format suitable for parsing")
private boolean machineFormat = false;
@Option(name = "--extended-exit-code",
usage = "0 - clean; 1 - has warnings; 2 - has errors")
private boolean extendedExitCode = false;
@Option(name = "--enable_type_checks",
usage = "Generate runtime type checks")
private boolean developerModeChecks = false;
@Option(name = "--ignore-unrecognized-flags",
usage = "Ignore unrecognized command line flags")
private boolean ignoreUnrecognizedFlags = false;
@Option(name = "--jvm-metrics-detail",
usage = "Display summary (default) or\n verbose metrics")
private String jvmMetricDetail = "summary";
@Option(name = "--jvm-metrics-format",
usage = "Output metrics in tabular (default)\n or pretty format")
private String jvmMetricFormat = "tabular";
@Option(name = "--jvm-metrics-type",
usage = "Comma-separated list to display:\n "
+ " all: (default) all stat types\n "
+ " gc: show garbage collection stats\n "
+ " mem: show memory stats\n "
+ " jit: show jit stats")
private String jvmMetricType = "all";
// leave the command line flag for legacy purposes.
@SuppressWarnings("unused")
@Option(name = "--noincremental",
usage = "Disable incremental compilation (default)")
private boolean noincremental = true; // not used, just a placeholder for arg parsing
@Option(name = "--incremental",
usage = "Enable incremental compilation")
private boolean incremental = false;
@Option(name = "--work", aliases = { "-out" },
usage = "Directory to receive compiler output\n for future incremental builds")
private File workDirectory = new File("out");
@Option(name = "--help", aliases = { "-?", "-help" },
usage = "Prints this help message")
private boolean showHelp = false;
@Option(name = "--jvm-metrics",
usage = "Print jvm metrics at end of compile")
private boolean showJvmMetrics = false;
@Option(name = "--metrics",
usage = "Print compilation metrics")
private boolean showMetrics = false;
@Option(name = "--fatal-type-errors", aliases = { "-fatal-type-errors" },
usage = "Treat type errors as fatal")
private boolean typeErrorsAreFatal = false;
@Option(name = "--fatal-warnings", aliases = { "-Werror" },
usage = "Treat non-type warnings as fatal")
private boolean warningsAreFatal = false;
@Option(name = "--platform",
usage = "Platform libraries to analyze (e.g. dartium, vm, dart2js, any)")
private String platformName = PackageLibraryManager.DEFAULT_PLATFORM;
@Option(name = "--dart-sdk",
usage = "Path to dart sdk. (system property com.google.dart.sdk)")
private File dartSdkPath = PackageLibraryManager.DEFAULT_SDK_PATH;
@Option(name = "--package-root",
usage = "Root directory used for the package: scheme")
private File packageRoot = PackageLibraryManager.DEFAULT_PACKAGE_ROOT;
@Option(name = "--show-sdk-warnings", usage = "show warnings from SDK source")
private boolean showSdkWarnings = false;
@Option(name = "--source-from-ast",
usage = "For debugging, reconstitute source code from the parsed AST.")
private boolean showSourceFromAst = false;
@Option(name = "--resolve-on-parse-error",
usage = "For debugging, continue on with resolution even if there are parse errors.")
private boolean resolveDespiteParseErrors;
@Option(name = "--type-checks-for-inferred-types",
usage = "[not in spec] Enables 'interface has no method/field' for receivers with inferred types.")
private boolean typeChecksForInferredTypes = false;
@Option(name = "--version",
usage = "Show analyzer version")
private boolean showVersion = false;
@Argument
private final List<String> sourceFiles = new ArrayList<String>();
public String getJvmMetricOptions() {
if (!showJvmMetrics) {
return null;
}
return jvmMetricDetail + ":" + jvmMetricFormat + ":" + jvmMetricType;
}
public String getPlatformName() {
return platformName;
}
/**
* @return the packageRoot
*/
public File getPackageRoot() {
return packageRoot;
}
public File getDartSdkPath() {
return dartSdkPath;
}
public boolean extendedExitCode() {
return extendedExitCode;
}
/**
* Returns whether warnings from SDK files should be suppressed.
*/
public boolean suppressSdkWarnings() {
return !showSdkWarnings;
}
/**
* Returns whether inferred types should be used for type checks.
*/
public boolean typeChecksForInferredTypes() {
return this.typeChecksForInferredTypes;
}
/**
* Returns whether "no such member" should be reported for classes which implement
* "noSuchMethod" method.
*/
public boolean reportNoMemberWhenHasInterceptor() {
return true;
}
/**
* Returns the list of files passed to the compiler.
*/
public List<String> getSourceFiles() {
return sourceFiles;
}
/**
* Returns the path to receive compiler intermediate output.
*/
public File getWorkDirectory() {
return workDirectory;
}
public boolean ignoreUnrecognizedFlags() {
return ignoreUnrecognizedFlags;
}
/**
* Returns whether the compiler should attempt to incrementally recompile.
*/
public boolean buildIncrementally() {
return incremental;
}
public boolean shouldBatch() {
return batch;
}
public boolean resolveDespiteParseErrors() {
return resolveDespiteParseErrors;
}
/**
* Returns <code>true</code> if the compiler should print it's help message.
*/
public boolean showHelp() {
return showHelp;
}
public boolean showJvmMetrics() {
return showJvmMetrics;
}
public boolean showMetrics() {
return showMetrics;
}
public boolean showVersion() {
return showVersion;
}
/**
* if <code>true</code>, run the AST back through the DartSourceVisitor to create source
* from the parsed AST and print to stdout.
*/
public boolean showSourceFromAst() {
return showSourceFromAst;
}
/**
* Returns whether type errors are fatal.
*/
public boolean typeErrorsAreFatal() {
return typeErrorsAreFatal;
}
/**
* Returns whether warnings (excluding type warnings) are fatal.
*/
public boolean warningsAreFatal() {
return warningsAreFatal;
}
public boolean developerModeChecks() {
return developerModeChecks;
}
/**
* @return the format to use for printing errors
*/
public ErrorFormat printErrorFormat() {
if (machineFormat) {
return ErrorFormat.MACHINE;
}
String lowerError = errorFormat.toLowerCase();
if ("machine".equals(lowerError)) {
return ErrorFormat.MACHINE;
}
return ErrorFormat.NORMAL;
}
}
/**
* Parses command line options, handling the feature to ignore unrecognized
* flags.
*
* If one of the options is 'ignore-unrecognized-flags', then any exceptions
* for 'not a valid option' are suppressed.
*
* @param args Arguments passed from main()
* @param parsedOptions [out parameter] parsed options
* @throws CmdLineException Thrown if there is a problem parsing the options.
*/
public static CmdLineParser parse(String[] args, CompilerOptions parsedOptions)
throws CmdLineException {
// convert new "--name=value" into old "--name value" style
{
List<String> argList = Lists.newArrayList();
for (String arg : args) {
String[] parts = StringUtils.split(arg, '=');
Collections.addAll(argList, parts);
}
args = argList.toArray(new String[argList.size()]);
}
boolean ignoreUnrecognized = false;
for (String arg : args) {
if (arg.equals("--ignore-unrecognized-flags")) {
ignoreUnrecognized = true;
break;
}
}
if (!ignoreUnrecognized) {
CmdLineParser cmdLineParser = new CmdLineParser(parsedOptions);
cmdLineParser.parseArgument(args);
return cmdLineParser;
}
CmdLineParser cmdLineParser = new CmdLineParser(parsedOptions);
for (int i = 0, len = args.length; i < len; i++) {
try {
cmdLineParser.parseArgument(args);
} catch (CmdLineException e) {
String msg = e.getMessage();
if (e.getMessage().endsWith(" is not a valid option")) {
String option = msg.substring(1);
int closeQuote = option.indexOf('\"');
option = option.substring(0, closeQuote);
List<String> newArgs = Lists.newArrayList();
for (String arg : args) {
if (arg.equals(option)) {
System.out.println("(Ignoring unrecognized flag: " + arg + ")");
continue;
}
newArgs.add(arg);
}
args = newArgs.toArray(new String[newArgs.size()]);
cmdLineParser = new CmdLineParser(parsedOptions);
continue;
}
}
break;
}
return cmdLineParser;
}
}