8169676: boolean result of Option.process is often ignored
Reviewed-by: ksrini, jlahoda
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileManager.java Wed Nov 16 11:53:24 2016 -0800
@@ -249,8 +249,11 @@
return false;
}
- if (!o.handleOption(helper, current, remaining))
- throw new IllegalArgumentException(current);
+ try {
+ o.handleOption(helper, current, remaining);
+ } catch (Option.InvalidValueException e) {
+ throw new IllegalArgumentException(e.getMessage(), e);
+ }
return true;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Wed Nov 16 11:53:24 2016 -0800
@@ -161,16 +161,6 @@
}
@Override
- public void error(String key, Object... args) {
- Arguments.this.error(key, args);
- }
-
- @Override
- public void error(JCDiagnostic.Error error) {
- Arguments.this.error(error);
- }
-
- @Override
public void addFile(Path p) {
files.add(p);
}
@@ -222,11 +212,6 @@
}
@Override
- public void error(String key, Object... args) {
- Arguments.this.error(key, args);
- }
-
- @Override
public Log getLog() {
return Arguments.this.log;
}
@@ -263,6 +248,17 @@
}
/**
+ * Minimal initialization for tools, like javadoc,
+ * to be able to process javac options for themselves,
+ * and then call validate.
+ * @param ownName the name of this tool; used to prefix messages
+ */
+ public void init(String ownName) {
+ this.ownName = ownName;
+ errorMode = ErrorMode.LOG;
+ }
+
+ /**
* Gets the files to be compiled.
* @return the files to be compiled
*/
@@ -379,7 +375,10 @@
}
if (option != null) {
- if (!option.handleOption(helper, arg, argIter)) {
+ try {
+ option.handleOption(helper, arg, argIter);
+ } catch (Option.InvalidValueException e) {
+ error(e);
return false;
}
continue;
@@ -446,24 +445,23 @@
// It is allowed to compile nothing if just asking for help or version info.
// But also note that none of these options are supported in API mode.
if (options.isSet(Option.HELP)
- || options.isSet(Option.X)
- || options.isSet(Option.VERSION)
- || options.isSet(Option.FULLVERSION)
- || options.isSet(Option.MODULE))
- return true;
-
- if (emptyAllowed)
+ || options.isSet(Option.X)
+ || options.isSet(Option.VERSION)
+ || options.isSet(Option.FULLVERSION)
+ || options.isSet(Option.MODULE)) {
return true;
-
- if (!errors) {
- if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
- error("err.no.source.files.classes");
- } else {
- error("err.no.source.files");
- }
}
- return false;
+ if (!emptyAllowed) {
+ if (!errors) {
+ if (JavaCompiler.explicitAnnotationProcessingRequested(options)) {
+ error("err.no.source.files.classes");
+ } else {
+ error("err.no.source.files");
+ }
+ }
+ return false;
+ }
}
if (!checkDirectory(Option.D)) {
@@ -555,7 +553,6 @@
}
boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
-
if (lintOptions && source.compareTo(Source.DEFAULT) < 0 && !options.isSet(Option.RELEASE)) {
if (fm instanceof BaseFileManager) {
if (((BaseFileManager) fm).isDefaultBootClassPath())
@@ -757,7 +754,7 @@
public boolean isEmpty() {
return ((files == null) || files.isEmpty())
&& ((fileObjects == null) || fileObjects.isEmpty())
- && classNames.isEmpty();
+ && (classNames == null || classNames.isEmpty());
}
public void allowEmpty() {
@@ -886,6 +883,21 @@
}
}
+ void error(Option.InvalidValueException f) {
+ String msg = f.getMessage();
+ errors = true;
+ switch (errorMode) {
+ case ILLEGAL_ARGUMENT: {
+ throw new PropagatedException(new IllegalArgumentException(msg, f.getCause()));
+ }
+ case ILLEGAL_STATE: {
+ throw new PropagatedException(new IllegalStateException(msg, f.getCause()));
+ }
+ case LOG:
+ log.printRawLines(ownName + ": " + msg);
+ }
+ }
+
void warning(String key, Object... args) {
report(key, args);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Wed Nov 16 11:53:24 2016 -0800
@@ -194,7 +194,10 @@
@Override
public void put(String name, String value) { }
};
- Option.HELP.process(h, "-help");
+ try {
+ Option.HELP.process(h, "-help");
+ } catch (Option.InvalidValueException ignore) {
+ }
return Result.CMDERR;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Nov 16 11:53:24 2016 -0800
@@ -93,9 +93,8 @@
G_NONE("-g:none", "opt.g.none", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
helper.put("-g:", "none");
- return false;
}
},
@@ -138,11 +137,10 @@
}
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
String prev = helper.get(XDOCLINT_CUSTOM);
String next = (prev == null) ? option : (prev + " " + option);
helper.put(XDOCLINT_CUSTOM.primaryName, next);
- return false;
}
},
@@ -154,20 +152,18 @@
}
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
String prev = helper.get(XDOCLINT_PACKAGE);
String next = (prev == null) ? option : (prev + " " + option);
helper.put(XDOCLINT_PACKAGE.primaryName, next);
- return false;
}
},
// -nowarn is retained for command-line backward compatibility
NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
helper.put("-Xlint:none", option);
- return false;
}
},
@@ -176,9 +172,8 @@
// -deprecation is retained for command-line backward compatibility
DEPRECATION("-deprecation", "opt.deprecation", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
helper.put("-Xlint:deprecation", option);
- return false;
}
},
@@ -201,15 +196,13 @@
// the the module=path pairs by an invalid path character, NULL.
// The standard file manager code knows to split apart the NULL-separated components.
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
- helper.error("err.no.value.for.option", option);
- return true;
+ throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(PATCH_MODULE);
if (prev == null) {
super.process(helper, option, arg);
- return false;
} else {
String argModulePackage = arg.substring(0, arg.indexOf('='));
boolean isRepeated = Arrays.stream(prev.split("\0"))
@@ -217,16 +210,13 @@
.collect(Collectors.toSet())
.contains(argModulePackage);
if (isRepeated) {
- helper.error("err.repeated.value.for.patch.module", argModulePackage);
- return true;
+ throw helper.newInvalidValueException("err.repeated.value.for.patch.module", argModulePackage);
} else {
super.process(helper, option, prev + '\0' + arg);
- return false;
}
}
} else {
- helper.error("err.bad.value.for.option", option, arg);
- return true;
+ throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@@ -238,10 +228,10 @@
BOOT_CLASS_PATH("--boot-class-path -bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
helper.remove("-Xbootclasspath/p:");
helper.remove("-Xbootclasspath/a:");
- return super.process(helper, option, arg);
+ super.process(helper, option, arg);
}
},
@@ -251,10 +241,10 @@
XBOOTCLASSPATH("-Xbootclasspath:", "opt.arg.path", "opt.bootclasspath", EXTENDED, FILEMANAGER) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
helper.remove("-Xbootclasspath/p:");
helper.remove("-Xbootclasspath/a:");
- return super.process(helper, "-bootclasspath", arg);
+ super.process(helper, "-bootclasspath", arg);
}
},
@@ -262,8 +252,8 @@
DJAVA_EXT_DIRS("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs", EXTENDED, FILEMANAGER) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
- return EXTDIRS.process(helper, "-extdirs", arg);
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
+ EXTDIRS.process(helper, "-extdirs", arg);
}
},
@@ -271,8 +261,8 @@
DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs=", "opt.arg.dirs", "opt.endorseddirs", EXTENDED, FILEMANAGER) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
- return ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
+ ENDORSEDDIRS.process(helper, "-endorseddirs", arg);
}
},
@@ -298,25 +288,23 @@
SOURCE("-source", "opt.arg.release", "opt.source", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String operand) {
+ public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Source source = Source.lookup(operand);
if (source == null) {
- helper.error("err.invalid.source", operand);
- return true;
+ throw helper.newInvalidValueException("err.invalid.source", operand);
}
- return super.process(helper, option, operand);
+ super.process(helper, option, operand);
}
},
TARGET("-target", "opt.arg.release", "opt.target", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String operand) {
+ public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Target target = Target.lookup(operand);
if (target == null) {
- helper.error("err.invalid.target", operand);
- return true;
+ throw helper.newInvalidValueException("err.invalid.target", operand);
}
- return super.process(helper, option, operand);
+ super.process(helper, option, operand);
}
},
@@ -345,46 +333,45 @@
PROFILE("-profile", "opt.arg.profile", "opt.profile", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String operand) {
+ public void process(OptionHelper helper, String option, String operand) throws InvalidValueException {
Profile profile = Profile.lookup(operand);
if (profile == null) {
- helper.error("err.invalid.profile", operand);
- return true;
+ throw helper.newInvalidValueException("err.invalid.profile", operand);
}
- return super.process(helper, option, operand);
+ super.process(helper, option, operand);
}
},
VERSION("-version", "opt.version", STANDARD, INFO) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "version", ownName, JavaCompiler.version());
- return super.process(helper, option);
+ super.process(helper, option);
}
},
FULLVERSION("-fullversion", null, HIDDEN, INFO) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "fullVersion", ownName, JavaCompiler.fullVersion());
- return super.process(helper, option);
+ super.process(helper, option);
}
},
// Note: -h is already taken for "native header output directory".
HELP("--help -help", "opt.help", STANDARD, INFO) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
String ownName = helper.getOwnName();
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.header", ownName);
showHelp(log, OptionKind.STANDARD);
log.printNewline(WriterKind.STDOUT);
- return super.process(helper, option);
+ super.process(helper, option);
}
},
@@ -401,31 +388,28 @@
// Mapping for processor options created in
// JavacProcessingEnvironment
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
int argLength = option.length();
if (argLength == 2) {
- helper.error("err.empty.A.argument");
- return true;
+ throw helper.newInvalidValueException("err.empty.A.argument");
}
int sepIndex = option.indexOf('=');
String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
if (!JavacProcessingEnvironment.isValidOptionName(key)) {
- helper.error("err.invalid.A.key", option);
- return true;
+ throw helper.newInvalidValueException("err.invalid.A.key", option);
}
helper.put(option, option);
- return false;
}
},
X("-X", "opt.X", STANDARD, INFO) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
Log log = helper.getLog();
showHelp(log, OptionKind.EXTENDED);
log.printNewline(WriterKind.STDOUT);
log.printLines(WriterKind.STDOUT, PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
- return super.process(helper, option);
+ super.process(helper, option);
}
},
@@ -433,16 +417,16 @@
// It's actually implemented by the launcher.
J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, ArgKind.ADJACENT) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
throw new AssertionError("the -J flag should be caught by the launcher.");
}
},
MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
Type.moreInfo = true;
- return super.process(helper, option);
+ super.process(helper, option);
}
},
@@ -462,9 +446,8 @@
// display warnings for generic unchecked operations
WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
helper.put("-Xlint:unchecked", option);
- return false;
}
},
@@ -474,15 +457,14 @@
XSTDOUT("-Xstdout", "opt.arg.file", "opt.Xstdout", EXTENDED, INFO) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
try {
Log log = helper.getLog();
log.setWriters(new PrintWriter(new FileWriter(arg), true));
} catch (java.io.IOException e) {
- helper.error("err.error.writing.file", arg, e);
- return true;
+ throw helper.newInvalidValueException("err.error.writing.file", arg, e);
}
- return super.process(helper, option, arg);
+ super.process(helper, option, arg);
}
},
@@ -507,11 +489,10 @@
PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
String p = option.substring(option.indexOf(':') + 1).trim();
String prev = helper.get(PLUGIN);
helper.put(PLUGIN.primaryName, (prev == null) ? p : prev + '\0' + p);
- return false;
}
},
@@ -519,22 +500,22 @@
DEBUG("--debug:", null, HIDDEN, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
- return HiddenGroup.DEBUG.process(helper, option);
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
+ HiddenGroup.DEBUG.process(helper, option);
}
},
SHOULDSTOP("--should-stop:", null, HIDDEN, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
- return HiddenGroup.SHOULDSTOP.process(helper, option);
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
+ HiddenGroup.SHOULDSTOP.process(helper, option);
}
},
DIAGS("--diags:", null, HIDDEN, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
- return HiddenGroup.DIAGS.process(helper, option);
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
+ HiddenGroup.DIAGS.process(helper, option);
}
},
@@ -548,33 +529,29 @@
return s.startsWith(primaryName);
}
@Override
- public boolean process(OptionHelper helper, String option) {
- return process(helper, option, option.substring(primaryName.length()));
+ public void process(OptionHelper helper, String option) {
+ process(helper, option, option.substring(primaryName.length()));
}
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) {
int eq = arg.indexOf('=');
String key = (eq < 0) ? arg : arg.substring(0, eq);
String value = (eq < 0) ? arg : arg.substring(eq+1);
helper.put(key, value);
- return false;
}
},
ADD_EXPORTS("--add-exports", "opt.arg.addExports", "opt.addExports", EXTENDED, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
- helper.error("err.no.value.for.option", option);
- return true;
+ throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_EXPORTS);
helper.put(ADD_EXPORTS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
- return false;
} else {
- helper.error("err.bad.value.for.option", option, arg);
- return true;
+ throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@@ -586,17 +563,14 @@
ADD_READS("--add-reads", "opt.arg.addReads", "opt.addReads", EXTENDED, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
- helper.error("err.no.value.for.option", option);
- return true;
+ throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_READS);
helper.put(ADD_READS.primaryName, (prev == null) ? arg : prev + '\0' + arg);
- return false;
} else {
- helper.error("err.bad.value.for.option", option, arg);
- return true;
+ throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@@ -608,14 +582,12 @@
XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
String prev = helper.get(XMODULE);
if (prev != null) {
- helper.error("err.option.too.many", XMODULE.primaryName);
- return true;
+ throw helper.newInvalidValueException("err.option.too.many", XMODULE.primaryName);
}
helper.put(XMODULE.primaryName, arg);
- return false;
}
},
@@ -623,19 +595,16 @@
ADD_MODULES("--add-modules", "opt.arg.addmods", "opt.addmods", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
- helper.error("err.no.value.for.option", option);
- return true;
+ throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
String prev = helper.get(ADD_MODULES);
// since the individual values are simple names, we can simply join the
// values of multiple --add-modules options with ','
helper.put(ADD_MODULES.primaryName, (prev == null) ? arg : prev + ',' + arg);
- return false;
} else {
- helper.error("err.bad.value.for.option", option, arg);
- return true;
+ throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@@ -647,16 +616,13 @@
LIMIT_MODULES("--limit-modules", "opt.arg.limitmods", "opt.limitmods", STANDARD, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (arg.isEmpty()) {
- helper.error("err.no.value.for.option", option);
- return true;
+ throw helper.newInvalidValueException("err.no.value.for.option", option);
} else if (getPattern().matcher(arg).matches()) {
helper.put(LIMIT_MODULES.primaryName, arg); // last one wins
- return false;
} else {
- helper.error("err.bad.value.for.option", option, arg);
- return true;
+ throw helper.newInvalidValueException("err.bad.value.for.option", option, arg);
}
}
@@ -670,7 +636,7 @@
// It's actually implemented by the CommandLine class.
AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, ArgKind.ADJACENT) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) {
throw new AssertionError("the @ flag should be caught by CommandLine.");
}
},
@@ -690,22 +656,19 @@
}
}
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
if (option.endsWith(".java") ) {
Path p = Paths.get(option);
if (!Files.exists(p)) {
- helper.error("err.file.not.found", p);
- return true;
+ throw helper.newInvalidValueException("err.file.not.found", p);
}
if (!Files.isRegularFile(p)) {
- helper.error("err.file.not.file", p);
- return true;
+ throw helper.newInvalidValueException("err.file.not.file", p);
}
helper.addFile(p);
} else {
helper.addClassName(option);
}
- return false;
}
},
@@ -714,7 +677,7 @@
INHERIT_RUNTIME_ENVIRONMENT("--inherit-runtime-environment", "opt.inherit_runtime_environment",
EXTENDED, BASIC) {
@Override
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
try {
Class.forName(JDK9Wrappers.VMHelper.VM_CLASSNAME);
String[] runtimeArgs = JDK9Wrappers.VMHelper.getRuntimeArguments();
@@ -729,9 +692,8 @@
}
}
} catch (ClassNotFoundException | SecurityException e) {
- helper.error("err.cannot.access.runtime.env");
+ throw helper.newInvalidValueException("err.cannot.access.runtime.env");
}
- return false;
}
private Option[] getSupportedRuntimeOptions() {
@@ -748,6 +710,23 @@
};
/**
+ * This exception is thrown when an invalid value is given for an option.
+ * The detail string gives a detailed, localized message, suitable for use
+ * in error messages reported to the user.
+ */
+ public static class InvalidValueException extends Exception {
+ private static final long serialVersionUID = -1;
+
+ public InvalidValueException(String msg) {
+ super(msg);
+ }
+
+ public InvalidValueException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
+ }
+
+ /**
* The kind of argument, if any, accepted by this option. The kind is augmented
* by characters in the name of the option.
*/
@@ -831,14 +810,13 @@
this.text = text;
}
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
String p = option.substring(option.indexOf(':') + 1).trim();
String[] subOptions = p.split(";");
for (String subOption : subOptions) {
subOption = text + "." + subOption.trim();
XD.process(helper, subOption, subOption);
}
- return false;
}
static boolean skip(String name) {
@@ -1038,7 +1016,7 @@
* @return true if the operation was successful, and false otherwise
* @implNote The return value is the opposite of that used by {@link #process}.
*/
- public boolean handleOption(OptionHelper helper, String arg, Iterator<String> rest) {
+ public void handleOption(OptionHelper helper, String arg, Iterator<String> rest) throws InvalidValueException {
if (hasArg()) {
String option;
String operand;
@@ -1051,15 +1029,14 @@
operand = arg.substring(sep + 1);
} else {
if (!rest.hasNext()) {
- helper.error("err.req.arg", arg);
- return false;
+ throw helper.newInvalidValueException("err.req.arg", arg);
}
option = arg;
operand = rest.next();
}
- return !process(helper, option, operand);
+ process(helper, option, operand);
} else {
- return !process(helper, arg);
+ process(helper, arg);
}
}
@@ -1068,14 +1045,14 @@
* or which contains an argument within it, following a separator.
* @param helper a helper to provide access to the environment
* @param option the option to be processed
- * @return true if an error occurred
+ * @throws InvalidValueException if an error occurred
*/
- public boolean process(OptionHelper helper, String option) {
+ public void process(OptionHelper helper, String option) throws InvalidValueException {
if (argKind == ArgKind.NONE) {
- return process(helper, primaryName, option);
+ process(helper, primaryName, option);
} else {
int sep = findSeparator(option);
- return process(helper, primaryName, option.substring(sep + 1));
+ process(helper, primaryName, option.substring(sep + 1));
}
}
@@ -1085,9 +1062,8 @@
* @param option the option to be processed
* @param arg the value to associate with the option, or a default value
* to be used if the option does not otherwise take an argument.
- * @return true if an error occurred
*/
- public boolean process(OptionHelper helper, String option, String arg) {
+ public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
if (choices != null) {
if (choiceKind == ChoiceKind.ONEOF) {
// some clients like to see just one of option+choice set
@@ -1110,7 +1086,6 @@
helper.put(primaryName, arg);
if (group == OptionGroup.FILEMANAGER)
helper.handleFileManagerOption(this, arg);
- return false;
}
/**
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/OptionHelper.java Wed Nov 16 11:53:24 2016 -0800
@@ -43,29 +43,55 @@
public abstract class OptionHelper {
- /** Get the current value of an option. */
+ /**
+ * Get the current value of an option.
+ * @param option the option
+ * @return the value of the option
+ */
public abstract String get(Option option);
- /** Set the value of an option. */
+ /**
+ * Set the value of an option.
+ * @param name the primary name of the option
+ * @param value the value for the option
+ */
public abstract void put(String name, String value);
- /** Remove any prior value for an option. */
+ /**
+ * Remove any prior value for an option.
+ * @param name the primary name of the option
+ */
public abstract void remove(String name);
- /** Handle a file manager option. */
+ /**
+ * Handle a file manager option.
+ * @param option the option
+ * @param value the value for the option
+ * @return true if the option was handled successfully, and false otherwise
+ */
public abstract boolean handleFileManagerOption(Option option, String value);
- /** Get access to the Log for the compilation. */
+ /**
+ * Get access to the Log for the compilation.
+ * @return the log
+ */
public abstract Log getLog();
- /** Get the name of the tool, such as "javac", to be used in info like -help. */
+ /**
+ * Get the name of the tool, such as "javac", to be used in info like -help.
+ * @return the name of the tool
+ */
public abstract String getOwnName();
- /** Report an error. */
- abstract void error(String key, Object... args);
-
- /** Report an error. */
- abstract void error(JCDiagnostic.Error error);
+ /**
+ * Returns a new InvalidValueException, with a localized detail message.
+ * @param key the resource key for the message
+ * @param args the arguments, if any, for the resource string
+ * @return the InvalidValueException
+ */
+ Option.InvalidValueException newInvalidValueException(String key, Object... args) {
+ return new Option.InvalidValueException(getLog().localize(PrefixKind.JAVAC, key, args));
+ }
/** Record a file to be compiled. */
abstract void addFile(Path p);
@@ -112,16 +138,6 @@
}
@Override
- void error(String key, Object... args) {
- throw new IllegalArgumentException(log.localize(PrefixKind.JAVAC, key, args));
- }
-
- @Override
- void error(JCDiagnostic.Error error) {
- throw new IllegalArgumentException(log.localize(error));
- }
-
- @Override
public void addFile(Path p) {
throw new IllegalArgumentException(p.toString());
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java Wed Nov 16 11:53:24 2016 -0800
@@ -45,6 +45,7 @@
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.file.BaseFileManager;
+import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
import com.sun.tools.javac.platform.PlatformDescription;
@@ -309,12 +310,16 @@
if (o == ToolOption.LOCALE && i > 0)
usageError("main.locale_first");
- if (o.hasArg) {
- oneArg(argv, i++);
- o.process(this, argv[i]);
- } else {
- setOption(arg);
- o.process(this);
+ try {
+ if (o.hasArg) {
+ oneArg(argv, i++);
+ o.process(this, argv[i]);
+ } else {
+ setOption(arg);
+ o.process(this);
+ }
+ } catch (Option.InvalidValueException e) {
+ usageError("main.option.invalid.value", e.getMessage());
}
} else if (arg.equals("-XDaccessInternalAPI")) {
// pass this hidden option down to the doclet, if it wants it
@@ -367,6 +372,11 @@
((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
}
+ Arguments arguments = Arguments.instance(context);
+ arguments.init(messager.programName);
+ arguments.allowEmpty();
+ arguments.validate();
+
String platformString = compOpts.get("--release");
if (platformString != null) {
@@ -560,7 +570,7 @@
@Override
OptionHelper getOptionHelper() {
- return new GrumpyHelper(null) {
+ return new GrumpyHelper(messager) {
@Override
public String get(com.sun.tools.javac.main.Option option) {
return compOpts.get(option);
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java Wed Nov 16 11:53:24 2016 -0800
@@ -31,6 +31,7 @@
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.Option.InvalidValueException;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Options;
@@ -141,14 +142,14 @@
ADD_MODULES("--add-modules", true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_MODULES.process(helper.getOptionHelper(), opt, arg);
}
},
LIMIT_MODULES("--limit-modules", true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.LIMIT_MODULES.process(helper.getOptionHelper(), opt, arg);
}
},
@@ -191,28 +192,28 @@
ADD_READS("--add-reads", true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_READS.process(helper.getOptionHelper(), opt, arg);
}
},
ADD_EXPORTS("--add-exports", true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_EXPORTS.process(helper.getOptionHelper(), opt, arg);
}
},
XMODULE("-Xmodule:", false) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.PATCH_MODULE.process(helper.getOptionHelper(), opt, arg);
}
},
@@ -356,7 +357,7 @@
this.hasArg = hasArg;
}
- void process(Helper helper, String arg) { }
+ void process(Helper helper, String arg) throws Option.InvalidValueException { }
void process(Helper helper) { }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Wed Nov 16 11:53:24 2016 -0800
@@ -126,6 +126,7 @@
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
main.unsupported.release.version=release version {0} not supported
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
+main.option.invalid.value={0}
tag.illegal_char_in_arr_dim=Tag {0}: Syntax Error in array dimension, method parameters: {1}
tag.illegal_see_tag=Tag {0}: Syntax Error in method parameters: {1}
tag.missing_comma_space=Tag {0}: Missing comma or space in method parameters: {1}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Nov 16 11:53:24 2016 -0800
@@ -51,6 +51,7 @@
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.main.Arguments;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
@@ -59,6 +60,7 @@
import com.sun.tools.javac.util.ClientCodeException;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.WriterKind;
import com.sun.tools.javac.util.Options;
import jdk.javadoc.doclet.Doclet;
@@ -325,9 +327,14 @@
if (argv.length > 0 && "-Xold".equals(argv[0])) {
warn("main.legacy_api");
String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
- return com.sun.tools.javadoc.Main.execute(nargv) == 0
- ? OK
- : ERROR;
+ int rc = com.sun.tools.javadoc.Main.execute(
+ messager.programName,
+ messager.getWriter(WriterKind.ERROR),
+ messager.getWriter(WriterKind.WARNING),
+ messager.getWriter(WriterKind.NOTICE),
+ "com.sun.tools.doclets.standard.Standard",
+ nargv);
+ return (rc == 0) ? OK : ERROR;
}
return begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
}
@@ -400,9 +407,14 @@
}
warn("main.legacy_api");
String[] array = options.toArray(new String[options.size()]);
- return com.sun.tools.javadoc.Main.execute(array) == 0
- ? OK
- : ERROR;
+ int rc = com.sun.tools.javadoc.Main.execute(
+ messager.programName,
+ messager.getWriter(WriterKind.ERROR),
+ messager.getWriter(WriterKind.WARNING),
+ messager.getWriter(WriterKind.NOTICE),
+ "com.sun.tools.doclets.standard.Standard",
+ array);
+ return (rc == 0) ? OK : ERROR;
}
Result result = OK;
@@ -410,6 +422,11 @@
result = parseAndExecute(options, fileObjects)
? OK
: ERROR;
+ } catch (com.sun.tools.javac.main.Option.InvalidValueException e) {
+ messager.printError(e.getMessage());
+ Throwable t = e.getCause();
+ dumpStack(t == null ? e : t);
+ return ERROR;
} catch (OptionException toe) {
if (toe.message != null)
messager.printError(toe.message);
@@ -482,8 +499,8 @@
* Main program - internal
*/
@SuppressWarnings("unchecked")
- private boolean parseAndExecute(List<String> argList,
- Iterable<? extends JavaFileObject> fileObjects) throws ToolException, OptionException {
+ private boolean parseAndExecute(List<String> argList, Iterable<? extends JavaFileObject> fileObjects)
+ throws ToolException, OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
long tm = System.currentTimeMillis();
List<String> javaNames = new ArrayList<>();
@@ -491,11 +508,19 @@
compOpts = Options.instance(context);
// Make sure no obsolete source/target messages are reported
- com.sun.tools.javac.main.Option.XLINT.process(getOptionHelper(), "-Xlint:-options");
+ try {
+ com.sun.tools.javac.main.Option.XLINT_CUSTOM.process(getOptionHelper(), "-Xlint:-options");
+ } catch (com.sun.tools.javac.main.Option.InvalidValueException ignore) {
+ }
doclet.init(locale, messager);
parseArgs(argList, javaNames);
+ Arguments arguments = Arguments.instance(context);
+ arguments.init(ProgramName);
+ arguments.allowEmpty();
+ arguments.validate();
+
if (fileManager instanceof BaseFileManager) {
((BaseFileManager) fileManager).handleOptions(fileManagerOpts);
}
@@ -805,7 +830,7 @@
}
private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
- OptionException {
+ OptionException, com.sun.tools.javac.main.Option.InvalidValueException {
for (int i = 0 ; i < args.size() ; i++) {
String arg = args.get(i);
ToolOption o = ToolOption.get(arg);
@@ -929,7 +954,7 @@
@Override
OptionHelper getOptionHelper() {
- return new GrumpyHelper(null) {
+ return new GrumpyHelper(messager) {
@Override
public String get(com.sun.tools.javac.main.Option option) {
return compOpts.get(option);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Wed Nov 16 10:45:23 2016 -0800
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Wed Nov 16 11:53:24 2016 -0800
@@ -35,6 +35,7 @@
import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.Option.InvalidValueException;
import com.sun.tools.javac.main.Option.OptionKind;
import com.sun.tools.javac.main.OptionHelper;
import com.sun.tools.javac.util.Options;
@@ -56,70 +57,70 @@
BOOTCLASSPATH("-bootclasspath", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.BOOT_CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
CLASS_PATH("--class-path -classpath -cp", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
EXTDIRS("-extdirs", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.EXTDIRS.process(helper.getOptionHelper(), primaryName, arg);
}
},
SOURCE_PATH("--source-path -sourcepath", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.MODULE_SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.UPGRADE_MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
SYSTEM("--system", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.SYSTEM.process(helper.getOptionHelper(), primaryName, arg);
}
},
MODULE_PATH("--module-path -p", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_MODULES("--add-modules", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg);
}
},
LIMIT_MODULES("--limit-modules", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg);
}
},
@@ -133,63 +134,63 @@
ENCODING("-encoding", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ENCODING.process(helper.getOptionHelper(), primaryName, arg);
}
},
RELEASE("--release", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg);
}
},
SOURCE("-source", STANDARD, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMAXERRS("-Xmaxerrs", EXTENDED, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMAXWARNS("-Xmaxwarns", EXTENDED, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_READS("--add-reads", EXTENDED, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg);
}
},
ADD_EXPORTS("--add-exports", EXTENDED, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg);
}
},
XMODULE("-Xmodule:", EXTENDED, false) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.XMODULE.process(helper.getOptionHelper(), arg);
}
},
PATCH_MODULE("--patch-module", EXTENDED, true) {
@Override
- public void process(Helper helper, String arg) {
+ public void process(Helper helper, String arg) throws InvalidValueException {
Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg);
}
},
@@ -388,7 +389,7 @@
this.hasSuffix = lastChar == ':' || lastChar == '=';
}
- void process(Helper helper, String arg) throws OptionException { }
+ void process(Helper helper, String arg) throws OptionException, Option.InvalidValueException { }
void process(Helper helper) throws OptionException { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/BadOptionsTest.java Wed Nov 16 11:53:24 2016 -0800
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169676
+ * @summary boolean result of Option.process is often ignored
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
+ * @run main BadOptionsTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * This is primarily a test of the error reporting mechanisms
+ * for bad options provided by javac and utilized by javadoc.
+ * It is not an exhaustive test of all bad option forms detected
+ * by javac/javadoc.
+ */
+public class BadOptionsTest extends TestRunner {
+
+ public static void main(String... args) throws Exception {
+ BadOptionsTest t = new BadOptionsTest();
+ t.runTests();
+ }
+
+ private final ToolBox tb = new ToolBox();
+ private final Path src = Paths.get("src");
+
+ BadOptionsTest() throws IOException {
+ super(System.err);
+ init();
+ }
+
+ void init() throws IOException {
+ tb.writeJavaFiles(src,
+ "public class C { }");
+
+ }
+
+ @Test
+ public void testAddModulesEmptyArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("--add-modules=")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - no value for --add-modules option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddModulesBadName() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-quiet",
+ "--add-modules", "123")
+ .files(src.resolve("C.java"))
+ .run()
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "warning: bad name in value for --add-modules option: '123'");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsEmptyArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("--add-exports=")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - no value for --add-exports option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsBadArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("--add-exports=m/p")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - bad value for --add-exports option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsBadName() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("--add-exports", "m!/p1=m2")
+ .files(src.resolve("C.java"))
+ .run()
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "warning: bad name in value for --add-exports option: 'm!'");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ private void checkFound(String log, String... expect) {
+ for (String e : expect) {
+ if (!log.contains(e)) {
+ error("Expected string not found: '" + e + "'");
+ }
+ }
+ }
+
+ private void checkNotFound(Task.Result result, String... unexpected) {
+ for (Task.OutputKind k : Task.OutputKind.values()) {
+ String r = result.getOutput(k);
+ for (String u : unexpected) {
+ if (r.contains(u)) {
+ error("Unexpected string found: '" + u + "'");
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javadoc/BadOptionsTest.java Wed Nov 16 11:53:24 2016 -0800
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8169676
+ * @summary boolean result of Option.process is often ignored
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * @modules jdk.compiler/com.sun.tools.javac.main
+ * @modules jdk.javadoc/jdk.javadoc.internal.api
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox
+ * @run main BadOptionsTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.lang.model.SourceVersion;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+/*
+ * This is primarily a test of the error reporting mechanisms
+ * for bad options provided by javac and utilized by javadoc.
+ * It is not an exhaustive test of all bad option forms detected
+ * by javac/javadoc.
+ */
+public class BadOptionsTest extends TestRunner {
+
+ public static void main(String... args) throws Exception {
+ BadOptionsTest t = new BadOptionsTest();
+ t.runTests();
+ }
+
+ private final ToolBox tb = new ToolBox();
+ private final Path src = Paths.get("src");
+
+ BadOptionsTest() throws IOException {
+ super(System.err);
+ init();
+ }
+
+ void init() throws IOException {
+ tb.writeJavaFiles(src,
+ "public class C { }");
+
+ }
+
+ @Test
+ public void testAddModulesEmptyArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-Xold",
+ "--add-modules", "")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - no value for --add-modules option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddModulesBadName() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-Xold", "-quiet",
+ "--add-modules", "123")
+ .files(src.resolve("C.java"))
+ .run()
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "warning: bad name in value for --add-modules option: '123'");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsEmptyArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-Xold",
+ "--add-exports", "")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - no value for --add-exports option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsBadArg() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-Xold",
+ "--add-exports", "m/p")
+ .files(src.resolve("C.java"))
+ .run(Task.Expect.FAIL)
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "javadoc: error - bad value for --add-exports option");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ @Test
+ public void testAddExportsBadName() {
+ Task.Result result = new JavadocTask(tb, Task.Mode.CMDLINE)
+ .options("-Xold",
+ "--add-exports", "m!/p1=m2")
+ .files(src.resolve("C.java"))
+ .run()
+ .writeAll();
+ checkFound(result.getOutput(Task.OutputKind.DIRECT),
+ "warning: bad name in value for --add-exports option: 'm!'");
+ checkNotFound(result, "Exception", "at jdk.javadoc/");
+ }
+
+ private void checkFound(String log, String... expect) {
+ for (String e : expect) {
+ if (!log.contains(e)) {
+ error("Expected string not found: '" + e + "'");
+ }
+ }
+ }
+
+ private void checkNotFound(Task.Result result, String... unexpected) {
+ for (Task.OutputKind k : Task.OutputKind.values()) {
+ String r = result.getOutput(k);
+ for (String u : unexpected) {
+ if (r.contains(u)) {
+ error("Unexpected string found: '" + u + "'");
+ }
+ }
+ }
+ }
+}