6307187: clean up code for -Xlint:options

Introduce common code for handling one-of and any-of options

Reviewed-by: mcimadamore
This commit is contained in:
Jonathan Gibbons 2008-03-11 13:14:55 -07:00
parent a7ed75b36a
commit 4cd40a47ff
5 changed files with 218 additions and 137 deletions

View File

@ -194,7 +194,7 @@ public class Lint
return map.get(option);
}
private final String option;
public final String option;
};
/**

View File

@ -28,6 +28,8 @@ package com.sun.tools.javac.main;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
/**
* TODO: describe com.sun.tools.javac.main.JavacOption
@ -41,19 +43,29 @@ public interface JavacOption {
OptionKind getKind();
/** Does this option take a (separate) operand? */
/** Does this option take a (separate) operand?
* @return true if this option takes a separate operand
*/
boolean hasArg();
/** Does argument string match option pattern?
* @param arg The command line argument string.
* @param arg the command line argument string
* @return true if {@code arg} matches this option
*/
boolean matches(String arg);
/** Process the option (with arg). Return true if error detected.
/** Process an option with an argument.
* @param options the accumulated set of analyzed options
* @param option the option to be processed
* @param arg the arg for the option to be processed
* @return true if an error was detected
*/
boolean process(Options options, String option, String arg);
/** Process the option (without arg). Return true if error detected.
/** Process the option with no argument.
* @param options the accumulated set of analyzed options
* @param option the option to be processed
* @return true if an error was detected
*/
boolean process(Options options, String option);
@ -65,6 +77,11 @@ public interface JavacOption {
HIDDEN,
}
enum ChoiceKind {
ONEOF,
ANYOF
}
/** This class represents an option recognized by the main program
*/
static class Option implements JavacOption {
@ -85,6 +102,14 @@ public interface JavacOption {
*/
boolean hasSuffix;
/** The kind of choices for this option, if any.
*/
ChoiceKind choiceKind;
/** The choices for this option, if any.
*/
Collection<String> choices;
Option(OptionName name, String argsNameKey, String descrKey) {
this.name = name;
this.argsNameKey = argsNameKey;
@ -92,51 +117,116 @@ public interface JavacOption {
char lastChar = name.optionName.charAt(name.optionName.length()-1);
hasSuffix = lastChar == ':' || lastChar == '=';
}
Option(OptionName name, String descrKey) {
this(name, null, descrKey);
}
Option(OptionName name, String descrKey, ChoiceKind choiceKind, String... choices) {
this(name, descrKey, choiceKind, Arrays.asList(choices));
}
Option(OptionName name, String descrKey, ChoiceKind choiceKind, Collection<String> choices) {
this(name, null, descrKey);
if (choiceKind == null || choices == null)
throw new NullPointerException();
this.choiceKind = choiceKind;
this.choices = choices;
}
@Override
public String toString() {
return name.optionName;
}
/** Does this option take a (separate) operand?
*/
public boolean hasArg() {
return argsNameKey != null && !hasSuffix;
}
/** Does argument string match option pattern?
* @param arg The command line argument string.
*/
public boolean matches(String arg) {
return hasSuffix ? arg.startsWith(name.optionName) : arg.equals(name.optionName);
public boolean matches(String option) {
if (!hasSuffix)
return option.equals(name.optionName);
if (!option.startsWith(name.optionName))
return false;
if (choices != null) {
String arg = option.substring(name.optionName.length());
if (choiceKind == ChoiceKind.ONEOF)
return choices.contains(arg);
else {
for (String a: arg.split(",+")) {
if (!choices.contains(a))
return false;
}
}
}
return true;
}
/** Print a line of documentation describing this option, if standard.
* @param out the stream to which to write the documentation
*/
void help(PrintWriter out) {
String s = " " + helpSynopsis();
out.print(s);
for (int j = s.length(); j < 29; j++) out.print(" ");
for (int j = Math.min(s.length(), 28); j < 29; j++) out.print(" ");
Log.printLines(out, Main.getLocalizedString(descrKey));
}
String helpSynopsis() {
return name +
(argsNameKey == null ? "" :
((hasSuffix ? "" : " ") +
Main.getLocalizedString(argsNameKey)));
StringBuilder sb = new StringBuilder();
sb.append(name);
if (argsNameKey == null) {
if (choices != null) {
String sep = "{";
for (String c: choices) {
sb.append(sep);
sb.append(c);
sep = ",";
}
sb.append("}");
}
} else {
if (!hasSuffix)
sb.append(" ");
sb.append(Main.getLocalizedString(argsNameKey));
}
return sb.toString();
}
/** Print a line of documentation describing this option, if non-standard.
* @param out the stream to which to write the documentation
*/
void xhelp(PrintWriter out) {}
/** Process the option (with arg). Return true if error detected.
*/
public boolean process(Options options, String option, String arg) {
if (options != null)
if (options != null) {
if (choices != null) {
if (choiceKind == ChoiceKind.ONEOF) {
// some clients like to see just one of option+choice set
for (String c: choices)
options.remove(option + c);
String opt = option + arg;
options.put(opt, opt);
// some clients like to see option (without trailing ":")
// set to arg
String nm = option.substring(0, option.length() - 1);
options.put(nm, arg);
} else {
// set option+word for each word in arg
for (String a: arg.split(",+")) {
String opt = option + a;
options.put(opt, opt);
}
}
}
options.put(option, arg);
}
return false;
}
@ -163,8 +253,17 @@ public interface JavacOption {
XOption(OptionName name, String descrKey) {
this(name, null, descrKey);
}
XOption(OptionName name, String descrKey, ChoiceKind kind, String... choices) {
super(name, descrKey, kind, choices);
}
XOption(OptionName name, String descrKey, ChoiceKind kind, Collection<String> choices) {
super(name, descrKey, kind, choices);
}
@Override
void help(PrintWriter out) {}
@Override
void xhelp(PrintWriter out) { super.help(out); }
@Override
public OptionKind getKind() { return OptionKind.EXTENDED; }
};
@ -177,8 +276,11 @@ public interface JavacOption {
HiddenOption(OptionName name, String argsNameKey) {
super(name, argsNameKey, null);
}
@Override
void help(PrintWriter out) {}
@Override
void xhelp(PrintWriter out) {}
@Override
public OptionKind getKind() { return OptionKind.HIDDEN; }
};

View File

@ -37,13 +37,9 @@ package com.sun.tools.javac.main;
public enum OptionName {
G("-g"),
G_NONE("-g:none"),
G_CUSTOM("-g:{lines,vars,source}"),
G_CUSTOM("-g:"),
XLINT("-Xlint"),
XLINT_CUSTOM("-Xlint:{"
+ "all,"
+ "cast,deprecation,divzero,empty,unchecked,fallthrough,path,serial,finally,overrides,"
+ "-cast,-deprecation,-divzero,-empty,-unchecked,-fallthrough,-path,-serial,-finally,-overrides,"
+ "none}"),
XLINT_CUSTOM("-Xlint:"),
NOWARN("-nowarn"),
VERBOSE("-verbose"),
DEPRECATION("-deprecation"),
@ -58,12 +54,12 @@ public enum OptionName {
DJAVA_EXT_DIRS("-Djava.ext.dirs="),
ENDORSEDDIRS("-endorseddirs"),
DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs="),
PROC_CUSTOM("-proc:{none,only}"),
PROC("-proc:"),
PROCESSOR("-processor"),
PROCESSORPATH("-processorpath"),
D("-d"),
S("-s"),
IMPLICIT("-implicit:{none,class}"),
IMPLICIT("-implicit:"),
ENCODING("-encoding"),
SOURCE("-source"),
TARGET("-target"),
@ -86,7 +82,7 @@ public enum OptionName {
XPRINT("-Xprint"),
XPRINTROUNDS("-XprintRounds"),
XPRINTPROCESSORINFO("-XprintProcessorInfo"),
XPREFER("-Xprefer:{source,newer}"),
XPREFER("-Xprefer:"),
O("-O"),
XJCOV("-Xjcov"),
XD("-XD"),

View File

@ -25,21 +25,23 @@
package com.sun.tools.javac.main;
import com.sun.tools.javac.code.Lint;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.main.JavacOption.HiddenOption;
import com.sun.tools.javac.main.JavacOption.Option;
import com.sun.tools.javac.main.JavacOption.XOption;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringTokenizer;
import javax.lang.model.SourceVersion;
@ -134,7 +136,7 @@ public class RecognizedOptions {
DJAVA_EXT_DIRS,
ENDORSEDDIRS,
DJAVA_ENDORSED_DIRS,
PROC_CUSTOM,
PROC,
PROCESSOR,
PROCESSORPATH,
D,
@ -195,7 +197,7 @@ public class RecognizedOptions {
NOWARN,
VERBOSE,
DEPRECATION,
PROC_CUSTOM,
PROC,
PROCESSOR,
IMPLICIT,
SOURCE,
@ -245,79 +247,58 @@ public class RecognizedOptions {
}
/**
* @param out the writer to use for diagnostic output
* Get all the recognized options.
* @param helper an {@code OptionHelper} to help when processing options
* @return an array of options
*/
public static Option[] getAll(final OptionHelper helper) {
return new Option[]{
return new Option[] {
new Option(G, "opt.g"),
new Option(G_NONE, "opt.g.none") {
@Override
public boolean process(Options options, String option) {
options.put("-g:", "none");
return false;
}
},
new Option(G_CUSTOM, "opt.g.lines.vars.source") {
public boolean matches(String s) {
return s.startsWith("-g:");
}
public boolean process(Options options, String option) {
String suboptions = option.substring(3);
options.put("-g:", suboptions);
// enter all the -g suboptions as "-g:suboption"
for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
String tok = t.nextToken();
String opt = "-g:" + tok;
options.put(opt, opt);
}
return false;
}
},
new Option(G_CUSTOM, "opt.g.lines.vars.source",
Option.ChoiceKind.ANYOF, "lines", "vars", "source"),
new XOption(XLINT, "opt.Xlint"),
new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist") {
public boolean matches(String s) {
return s.startsWith("-Xlint:");
}
public boolean process(Options options, String option) {
String suboptions = option.substring(7);
options.put("-Xlint:", suboptions);
// enter all the -Xlint suboptions as "-Xlint:suboption"
for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
String tok = t.nextToken();
String opt = "-Xlint:" + tok;
options.put(opt, opt);
}
return false;
}
},
new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist",
Option.ChoiceKind.ANYOF, getXLintChoices()),
// -nowarn is retained for command-line backward compatibility
new Option(NOWARN, "opt.nowarn") {
public boolean process(Options options, String option) {
options.put("-Xlint:none", option);
return false;
}
},
@Override
public boolean process(Options options, String option) {
options.put("-Xlint:none", option);
return false;
}
},
new Option(VERBOSE, "opt.verbose"),
// -deprecation is retained for command-line backward compatibility
new Option(DEPRECATION, "opt.deprecation") {
public boolean process(Options options, String option) {
options.put("-Xlint:deprecation", option);
return false;
}
},
@Override
public boolean process(Options options, String option) {
options.put("-Xlint:deprecation", option);
return false;
}
},
new Option(CLASSPATH, "opt.arg.path", "opt.classpath"),
new Option(CP, "opt.arg.path", "opt.classpath") {
@Override
public boolean process(Options options, String option, String arg) {
return super.process(options, "-classpath", arg);
}
},
new Option(SOURCEPATH, "opt.arg.path", "opt.sourcepath"),
new Option(BOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
@Override
public boolean process(Options options, String option, String arg) {
options.remove("-Xbootclasspath/p:");
options.remove("-Xbootclasspath/a:");
@ -327,6 +308,7 @@ public class RecognizedOptions {
new XOption(XBOOTCLASSPATH_PREPEND,"opt.arg.path", "opt.Xbootclasspath.p"),
new XOption(XBOOTCLASSPATH_APPEND, "opt.arg.path", "opt.Xbootclasspath.a"),
new XOption(XBOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
@Override
public boolean process(Options options, String option, String arg) {
options.remove("-Xbootclasspath/p:");
options.remove("-Xbootclasspath/a:");
@ -335,48 +317,29 @@ public class RecognizedOptions {
},
new Option(EXTDIRS, "opt.arg.dirs", "opt.extdirs"),
new XOption(DJAVA_EXT_DIRS, "opt.arg.dirs", "opt.extdirs") {
@Override
public boolean process(Options options, String option, String arg) {
return super.process(options, "-extdirs", arg);
}
},
new Option(ENDORSEDDIRS, "opt.arg.dirs", "opt.endorseddirs"),
new XOption(DJAVA_ENDORSED_DIRS, "opt.arg.dirs", "opt.endorseddirs") {
@Override
public boolean process(Options options, String option, String arg) {
return super.process(options, "-endorseddirs", arg);
}
},
new Option(PROC_CUSTOM, "opt.proc.none.only") {
public boolean matches(String s) {
return s.equals("-proc:none") || s.equals("-proc:only");
}
public boolean process(Options options, String option) {
if (option.equals("-proc:none")) {
options.remove("-proc:only");
} else {
options.remove("-proc:none");
}
options.put(option, option);
return false;
}
},
new Option(PROC, "opt.proc.none.only",
Option.ChoiceKind.ONEOF, "none", "only"),
new Option(PROCESSOR, "opt.arg.class.list", "opt.processor"),
new Option(PROCESSORPATH, "opt.arg.path", "opt.processorpath"),
new Option(D, "opt.arg.directory", "opt.d"),
new Option(S, "opt.arg.directory", "opt.sourceDest"),
new Option(IMPLICIT, "opt.implicit") {
public boolean matches(String s) {
return s.equals("-implicit:none") || s.equals("-implicit:class");
}
public boolean process(Options options, String option, String operand) {
int sep = option.indexOf(":");
options.put(option.substring(0, sep), option.substring(sep+1));
options.put(option,option);
return false;
}
},
new Option(IMPLICIT, "opt.implicit",
Option.ChoiceKind.ONEOF, "none", "class"),
new Option(ENCODING, "opt.arg.encoding", "opt.encoding"),
new Option(SOURCE, "opt.arg.release", "opt.source") {
@Override
public boolean process(Options options, String option, String operand) {
Source source = Source.lookup(operand);
if (source == null) {
@ -387,6 +350,7 @@ public class RecognizedOptions {
}
},
new Option(TARGET, "opt.arg.release", "opt.target") {
@Override
public boolean process(Options options, String option, String operand) {
Target target = Target.lookup(operand);
if (target == null) {
@ -397,54 +361,62 @@ public class RecognizedOptions {
}
},
new Option(VERSION, "opt.version") {
@Override
public boolean process(Options options, String option) {
helper.printVersion();
return super.process(options, option);
}
},
new HiddenOption(FULLVERSION) {
@Override
public boolean process(Options options, String option) {
helper.printFullVersion();
return super.process(options, option);
}
},
new Option(HELP, "opt.help") {
@Override
public boolean process(Options options, String option) {
helper.printHelp();
return super.process(options, option);
}
},
new Option(A, "opt.arg.key.equals.value","opt.A") {
String helpSynopsis() {
hasSuffix = true;
return super.helpSynopsis();
}
@Override
String helpSynopsis() {
hasSuffix = true;
return super.helpSynopsis();
}
public boolean matches(String arg) {
return arg.startsWith("-A");
}
@Override
public boolean matches(String arg) {
return arg.startsWith("-A");
}
public boolean hasArg() {
return false;
@Override
public boolean hasArg() {
return false;
}
// Mapping for processor options created in
// JavacProcessingEnvironment
@Override
public boolean process(Options options, String option) {
int argLength = option.length();
if (argLength == 2) {
helper.error("err.empty.A.argument");
return true;
}
// Mapping for processor options created in
// JavacProcessingEnvironment
public boolean process(Options options, String option) {
int argLength = option.length();
if (argLength == 2) {
helper.error("err.empty.A.argument");
return true;
}
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;
}
return process(options, option, option);
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;
}
return process(options, option, option);
}
},
new Option(X, "opt.X") {
@Override
public boolean process(Options options, String option) {
helper.printXhelp();
return super.process(options, option);
@ -454,10 +426,12 @@ public class RecognizedOptions {
// This option exists only for the purpose of documenting itself.
// It's actually implemented by the launcher.
new Option(J, "opt.arg.flag", "opt.J") {
@Override
String helpSynopsis() {
hasSuffix = true;
return super.helpSynopsis();
}
@Override
public boolean process(Options options, String option) {
throw new AssertionError
("the -J flag should be caught by the launcher.");
@ -469,6 +443,7 @@ public class RecognizedOptions {
// new Option("-moreinfo", "opt.moreinfo") {
new HiddenOption(MOREINFO) {
@Override
public boolean process(Options options, String option) {
Type.moreInfo = true;
return super.process(options, option);
@ -512,6 +487,7 @@ public class RecognizedOptions {
// display warnings for generic unchecked operations
new HiddenOption(WARNUNCHECKED) {
@Override
public boolean process(Options options, String option) {
options.put("-Xlint:unchecked", option);
return false;
@ -521,6 +497,7 @@ public class RecognizedOptions {
new XOption(XMAXERRS, "opt.arg.number", "opt.maxerrs"),
new XOption(XMAXWARNS, "opt.arg.number", "opt.maxwarns"),
new XOption(XSTDOUT, "opt.arg.file", "opt.Xstdout") {
@Override
public boolean process(Options options, String option, String arg) {
try {
helper.setOut(new PrintWriter(new FileWriter(arg), true));
@ -538,17 +515,8 @@ public class RecognizedOptions {
new XOption(XPRINTPROCESSORINFO, "opt.printProcessorInfo"),
new XOption(XPREFER, "opt.prefer") {
public boolean matches(String s) {
return s.equals("-Xprefer:source") || s.equals("-Xprefer:newer");
}
public boolean process(Options options, String option, String operand) {
int sep = option.indexOf(":");
options.put(option.substring(0, sep), option.substring(sep+1));
options.put(option,option);
return false;
}
},
new XOption(XPREFER, "opt.prefer",
Option.ChoiceKind.ONEOF, "source", "newer"),
/* -O is a no-op, accepted for backward compatibility. */
new HiddenOption(O),
@ -562,10 +530,12 @@ public class RecognizedOptions {
*/
new HiddenOption(XD) {
String s;
@Override
public boolean matches(String s) {
this.s = s;
return s.startsWith(name.optionName);
}
@Override
public boolean process(Options options, String option) {
s = s.substring(name.optionName.length());
int eq = s.indexOf('=');
@ -586,11 +556,13 @@ public class RecognizedOptions {
*/
new HiddenOption(SOURCEFILE) {
String s;
@Override
public boolean matches(String s) {
this.s = s;
return s.endsWith(".java") // Java source file
|| SourceVersion.isName(s); // Legal type name
}
@Override
public boolean process(Options options, String option) {
if (s.endsWith(".java") ) {
File f = new File(s);
@ -612,4 +584,15 @@ public class RecognizedOptions {
};
}
private static Collection<String> getXLintChoices() {
Collection<String> choices = new LinkedHashSet<String>();
choices.add("all");
for (Lint.LintCategory c : Lint.LintCategory.values())
choices.add(c.option);
for (Lint.LintCategory c : Lint.LintCategory.values())
choices.add("-" + c.option);
choices.add("none");
return choices;
}
}

View File

@ -186,7 +186,7 @@ public class T6341866 {
}
static void error(String msg) {
System.err.println(msg);
System.err.println("ERROR: " + msg);
}
static File services(Class<?> service) {