1.1 --- a/src/share/classes/com/sun/tools/javac/main/JavacOption.java Thu Mar 06 10:25:04 2008 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavacOption.java Tue Mar 11 13:14:55 2008 -0700 1.3 @@ -28,6 +28,8 @@ 1.4 import com.sun.tools.javac.util.Log; 1.5 import com.sun.tools.javac.util.Options; 1.6 import java.io.PrintWriter; 1.7 +import java.util.Arrays; 1.8 +import java.util.Collection; 1.9 1.10 /** 1.11 * TODO: describe com.sun.tools.javac.main.JavacOption 1.12 @@ -41,19 +43,29 @@ 1.13 1.14 OptionKind getKind(); 1.15 1.16 - /** Does this option take a (separate) operand? */ 1.17 + /** Does this option take a (separate) operand? 1.18 + * @return true if this option takes a separate operand 1.19 + */ 1.20 boolean hasArg(); 1.21 1.22 /** Does argument string match option pattern? 1.23 - * @param arg The command line argument string. 1.24 + * @param arg the command line argument string 1.25 + * @return true if {@code arg} matches this option 1.26 */ 1.27 boolean matches(String arg); 1.28 1.29 - /** Process the option (with arg). Return true if error detected. 1.30 + /** Process an option with an argument. 1.31 + * @param options the accumulated set of analyzed options 1.32 + * @param option the option to be processed 1.33 + * @param arg the arg for the option to be processed 1.34 + * @return true if an error was detected 1.35 */ 1.36 boolean process(Options options, String option, String arg); 1.37 1.38 - /** Process the option (without arg). Return true if error detected. 1.39 + /** Process the option with no argument. 1.40 + * @param options the accumulated set of analyzed options 1.41 + * @param option the option to be processed 1.42 + * @return true if an error was detected 1.43 */ 1.44 boolean process(Options options, String option); 1.45 1.46 @@ -65,6 +77,11 @@ 1.47 HIDDEN, 1.48 } 1.49 1.50 + enum ChoiceKind { 1.51 + ONEOF, 1.52 + ANYOF 1.53 + } 1.54 + 1.55 /** This class represents an option recognized by the main program 1.56 */ 1.57 static class Option implements JavacOption { 1.58 @@ -85,6 +102,14 @@ 1.59 */ 1.60 boolean hasSuffix; 1.61 1.62 + /** The kind of choices for this option, if any. 1.63 + */ 1.64 + ChoiceKind choiceKind; 1.65 + 1.66 + /** The choices for this option, if any. 1.67 + */ 1.68 + Collection<String> choices; 1.69 + 1.70 Option(OptionName name, String argsNameKey, String descrKey) { 1.71 this.name = name; 1.72 this.argsNameKey = argsNameKey; 1.73 @@ -92,51 +117,116 @@ 1.74 char lastChar = name.optionName.charAt(name.optionName.length()-1); 1.75 hasSuffix = lastChar == ':' || lastChar == '='; 1.76 } 1.77 + 1.78 Option(OptionName name, String descrKey) { 1.79 this(name, null, descrKey); 1.80 } 1.81 1.82 + Option(OptionName name, String descrKey, ChoiceKind choiceKind, String... choices) { 1.83 + this(name, descrKey, choiceKind, Arrays.asList(choices)); 1.84 + } 1.85 + 1.86 + Option(OptionName name, String descrKey, ChoiceKind choiceKind, Collection<String> choices) { 1.87 + this(name, null, descrKey); 1.88 + if (choiceKind == null || choices == null) 1.89 + throw new NullPointerException(); 1.90 + this.choiceKind = choiceKind; 1.91 + this.choices = choices; 1.92 + } 1.93 + 1.94 + @Override 1.95 public String toString() { 1.96 return name.optionName; 1.97 } 1.98 1.99 - /** Does this option take a (separate) operand? 1.100 - */ 1.101 public boolean hasArg() { 1.102 return argsNameKey != null && !hasSuffix; 1.103 } 1.104 1.105 - /** Does argument string match option pattern? 1.106 - * @param arg The command line argument string. 1.107 - */ 1.108 - public boolean matches(String arg) { 1.109 - return hasSuffix ? arg.startsWith(name.optionName) : arg.equals(name.optionName); 1.110 + public boolean matches(String option) { 1.111 + if (!hasSuffix) 1.112 + return option.equals(name.optionName); 1.113 + 1.114 + if (!option.startsWith(name.optionName)) 1.115 + return false; 1.116 + 1.117 + if (choices != null) { 1.118 + String arg = option.substring(name.optionName.length()); 1.119 + if (choiceKind == ChoiceKind.ONEOF) 1.120 + return choices.contains(arg); 1.121 + else { 1.122 + for (String a: arg.split(",+")) { 1.123 + if (!choices.contains(a)) 1.124 + return false; 1.125 + } 1.126 + } 1.127 + } 1.128 + 1.129 + return true; 1.130 } 1.131 1.132 /** Print a line of documentation describing this option, if standard. 1.133 + * @param out the stream to which to write the documentation 1.134 */ 1.135 void help(PrintWriter out) { 1.136 String s = " " + helpSynopsis(); 1.137 out.print(s); 1.138 - for (int j = s.length(); j < 29; j++) out.print(" "); 1.139 + for (int j = Math.min(s.length(), 28); j < 29; j++) out.print(" "); 1.140 Log.printLines(out, Main.getLocalizedString(descrKey)); 1.141 } 1.142 + 1.143 String helpSynopsis() { 1.144 - return name + 1.145 - (argsNameKey == null ? "" : 1.146 - ((hasSuffix ? "" : " ") + 1.147 - Main.getLocalizedString(argsNameKey))); 1.148 + StringBuilder sb = new StringBuilder(); 1.149 + sb.append(name); 1.150 + if (argsNameKey == null) { 1.151 + if (choices != null) { 1.152 + String sep = "{"; 1.153 + for (String c: choices) { 1.154 + sb.append(sep); 1.155 + sb.append(c); 1.156 + sep = ","; 1.157 + } 1.158 + sb.append("}"); 1.159 + } 1.160 + } else { 1.161 + if (!hasSuffix) 1.162 + sb.append(" "); 1.163 + sb.append(Main.getLocalizedString(argsNameKey)); 1.164 + } 1.165 + 1.166 + return sb.toString(); 1.167 } 1.168 1.169 /** Print a line of documentation describing this option, if non-standard. 1.170 + * @param out the stream to which to write the documentation 1.171 */ 1.172 void xhelp(PrintWriter out) {} 1.173 1.174 /** Process the option (with arg). Return true if error detected. 1.175 */ 1.176 public boolean process(Options options, String option, String arg) { 1.177 - if (options != null) 1.178 + if (options != null) { 1.179 + if (choices != null) { 1.180 + if (choiceKind == ChoiceKind.ONEOF) { 1.181 + // some clients like to see just one of option+choice set 1.182 + for (String c: choices) 1.183 + options.remove(option + c); 1.184 + String opt = option + arg; 1.185 + options.put(opt, opt); 1.186 + // some clients like to see option (without trailing ":") 1.187 + // set to arg 1.188 + String nm = option.substring(0, option.length() - 1); 1.189 + options.put(nm, arg); 1.190 + } else { 1.191 + // set option+word for each word in arg 1.192 + for (String a: arg.split(",+")) { 1.193 + String opt = option + a; 1.194 + options.put(opt, opt); 1.195 + } 1.196 + } 1.197 + } 1.198 options.put(option, arg); 1.199 + } 1.200 return false; 1.201 } 1.202 1.203 @@ -163,8 +253,17 @@ 1.204 XOption(OptionName name, String descrKey) { 1.205 this(name, null, descrKey); 1.206 } 1.207 + XOption(OptionName name, String descrKey, ChoiceKind kind, String... choices) { 1.208 + super(name, descrKey, kind, choices); 1.209 + } 1.210 + XOption(OptionName name, String descrKey, ChoiceKind kind, Collection<String> choices) { 1.211 + super(name, descrKey, kind, choices); 1.212 + } 1.213 + @Override 1.214 void help(PrintWriter out) {} 1.215 + @Override 1.216 void xhelp(PrintWriter out) { super.help(out); } 1.217 + @Override 1.218 public OptionKind getKind() { return OptionKind.EXTENDED; } 1.219 }; 1.220 1.221 @@ -177,8 +276,11 @@ 1.222 HiddenOption(OptionName name, String argsNameKey) { 1.223 super(name, argsNameKey, null); 1.224 } 1.225 + @Override 1.226 void help(PrintWriter out) {} 1.227 + @Override 1.228 void xhelp(PrintWriter out) {} 1.229 + @Override 1.230 public OptionKind getKind() { return OptionKind.HIDDEN; } 1.231 }; 1.232