src/share/classes/com/sun/tools/javac/main/Option.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 2413
fe033d997ddf
parent 0
959103a6100f
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javac.main;
aoqi@0 27
aoqi@0 28 import java.io.File;
aoqi@0 29 import java.io.FileWriter;
aoqi@0 30 import java.io.PrintWriter;
aoqi@0 31 import java.util.Collections;
aoqi@0 32 import java.util.EnumSet;
aoqi@0 33 import java.util.LinkedHashMap;
aoqi@0 34 import java.util.Map;
aoqi@0 35 import java.util.Set;
aoqi@0 36
aoqi@0 37 import javax.lang.model.SourceVersion;
aoqi@0 38
aoqi@0 39 import com.sun.tools.doclint.DocLint;
aoqi@0 40 import com.sun.tools.javac.code.Lint;
aoqi@0 41 import com.sun.tools.javac.code.Source;
aoqi@0 42 import com.sun.tools.javac.code.Type;
aoqi@0 43 import com.sun.tools.javac.jvm.Profile;
aoqi@0 44 import com.sun.tools.javac.jvm.Target;
aoqi@0 45 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
aoqi@0 46 import com.sun.tools.javac.util.Log;
aoqi@0 47 import com.sun.tools.javac.util.Log.PrefixKind;
aoqi@0 48 import com.sun.tools.javac.util.Log.WriterKind;
aoqi@0 49 import com.sun.tools.javac.util.Options;
aoqi@0 50 import com.sun.tools.javac.util.StringUtils;
aoqi@0 51 import static com.sun.tools.javac.main.Option.ChoiceKind.*;
aoqi@0 52 import static com.sun.tools.javac.main.Option.OptionGroup.*;
aoqi@0 53 import static com.sun.tools.javac.main.Option.OptionKind.*;
aoqi@0 54
aoqi@0 55 /**
aoqi@0 56 * Options for javac. The specific Option to handle a command-line option
aoqi@0 57 * is identified by searching the members of this enum in order, looking
aoqi@0 58 * the first {@link #matches match}. The action for an Option is performed
aoqi@0 59 * by calling {@link #process process}, and by providing a suitable
aoqi@0 60 * {@link OptionHelper} to provide access the compiler state.
aoqi@0 61 *
aoqi@0 62 * <p><b>This is NOT part of any supported API.
aoqi@0 63 * If you write code that depends on this, you do so at your own
aoqi@0 64 * risk. This code and its internal interfaces are subject to change
aoqi@0 65 * or deletion without notice.</b></p>
aoqi@0 66 */
aoqi@0 67 public enum Option {
aoqi@0 68 G("-g", "opt.g", STANDARD, BASIC),
aoqi@0 69
aoqi@0 70 G_NONE("-g:none", "opt.g.none", STANDARD, BASIC) {
aoqi@0 71 @Override
aoqi@0 72 public boolean process(OptionHelper helper, String option) {
aoqi@0 73 helper.put("-g:", "none");
aoqi@0 74 return false;
aoqi@0 75 }
aoqi@0 76 },
aoqi@0 77
aoqi@0 78 G_CUSTOM("-g:", "opt.g.lines.vars.source",
aoqi@0 79 STANDARD, BASIC, ANYOF, "lines", "vars", "source"),
aoqi@0 80
aoqi@0 81 XLINT("-Xlint", "opt.Xlint", EXTENDED, BASIC),
aoqi@0 82
aoqi@0 83 XLINT_CUSTOM("-Xlint:", "opt.Xlint.suboptlist",
aoqi@0 84 EXTENDED, BASIC, ANYOF, getXLintChoices()),
aoqi@0 85
aoqi@0 86 XDOCLINT("-Xdoclint", "opt.Xdoclint", EXTENDED, BASIC),
aoqi@0 87
aoqi@0 88 XDOCLINT_CUSTOM("-Xdoclint:", "opt.Xdoclint.subopts", "opt.Xdoclint.custom", EXTENDED, BASIC) {
aoqi@0 89 @Override
aoqi@0 90 public boolean matches(String option) {
aoqi@0 91 return DocLint.isValidOption(
aoqi@0 92 option.replace(XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX));
aoqi@0 93 }
aoqi@0 94
aoqi@0 95 @Override
aoqi@0 96 public boolean process(OptionHelper helper, String option) {
aoqi@0 97 String prev = helper.get(XDOCLINT_CUSTOM);
aoqi@0 98 String next = (prev == null) ? option : (prev + " " + option);
aoqi@0 99 helper.put(XDOCLINT_CUSTOM.text, next);
aoqi@0 100 return false;
aoqi@0 101 }
aoqi@0 102 },
aoqi@0 103
aoqi@0 104 // -nowarn is retained for command-line backward compatibility
aoqi@0 105 NOWARN("-nowarn", "opt.nowarn", STANDARD, BASIC) {
aoqi@0 106 @Override
aoqi@0 107 public boolean process(OptionHelper helper, String option) {
aoqi@0 108 helper.put("-Xlint:none", option);
aoqi@0 109 return false;
aoqi@0 110 }
aoqi@0 111 },
aoqi@0 112
aoqi@0 113 VERBOSE("-verbose", "opt.verbose", STANDARD, BASIC),
aoqi@0 114
aoqi@0 115 // -deprecation is retained for command-line backward compatibility
aoqi@0 116 DEPRECATION("-deprecation", "opt.deprecation", STANDARD, BASIC) {
aoqi@0 117 @Override
aoqi@0 118 public boolean process(OptionHelper helper, String option) {
aoqi@0 119 helper.put("-Xlint:deprecation", option);
aoqi@0 120 return false;
aoqi@0 121 }
aoqi@0 122 },
aoqi@0 123
aoqi@0 124 CLASSPATH("-classpath", "opt.arg.path", "opt.classpath", STANDARD, FILEMANAGER),
aoqi@0 125
aoqi@0 126 CP("-cp", "opt.arg.path", "opt.classpath", STANDARD, FILEMANAGER) {
aoqi@0 127 @Override
aoqi@0 128 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 129 return super.process(helper, "-classpath", arg);
aoqi@0 130 }
aoqi@0 131 },
aoqi@0 132
aoqi@0 133 SOURCEPATH("-sourcepath", "opt.arg.path", "opt.sourcepath", STANDARD, FILEMANAGER),
aoqi@0 134
aoqi@0 135 BOOTCLASSPATH("-bootclasspath", "opt.arg.path", "opt.bootclasspath", STANDARD, FILEMANAGER) {
aoqi@0 136 @Override
aoqi@0 137 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 138 helper.remove("-Xbootclasspath/p:");
aoqi@0 139 helper.remove("-Xbootclasspath/a:");
aoqi@0 140 return super.process(helper, option, arg);
aoqi@0 141 }
aoqi@0 142 },
aoqi@0 143
aoqi@0 144 XBOOTCLASSPATH_PREPEND("-Xbootclasspath/p:", "opt.arg.path", "opt.Xbootclasspath.p", EXTENDED, FILEMANAGER),
aoqi@0 145
aoqi@0 146 XBOOTCLASSPATH_APPEND("-Xbootclasspath/a:", "opt.arg.path", "opt.Xbootclasspath.a", EXTENDED, FILEMANAGER),
aoqi@0 147
aoqi@0 148 XBOOTCLASSPATH("-Xbootclasspath:", "opt.arg.path", "opt.bootclasspath", EXTENDED, FILEMANAGER) {
aoqi@0 149 @Override
aoqi@0 150 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 151 helper.remove("-Xbootclasspath/p:");
aoqi@0 152 helper.remove("-Xbootclasspath/a:");
aoqi@0 153 return super.process(helper, "-bootclasspath", arg);
aoqi@0 154 }
aoqi@0 155 },
aoqi@0 156
aoqi@0 157 EXTDIRS("-extdirs", "opt.arg.dirs", "opt.extdirs", STANDARD, FILEMANAGER),
aoqi@0 158
aoqi@0 159 DJAVA_EXT_DIRS("-Djava.ext.dirs=", "opt.arg.dirs", "opt.extdirs", EXTENDED, FILEMANAGER) {
aoqi@0 160 @Override
aoqi@0 161 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 162 return super.process(helper, "-extdirs", arg);
aoqi@0 163 }
aoqi@0 164 },
aoqi@0 165
aoqi@0 166 ENDORSEDDIRS("-endorseddirs", "opt.arg.dirs", "opt.endorseddirs", STANDARD, FILEMANAGER),
aoqi@0 167
aoqi@0 168 DJAVA_ENDORSED_DIRS("-Djava.endorsed.dirs=", "opt.arg.dirs", "opt.endorseddirs", EXTENDED, FILEMANAGER) {
aoqi@0 169 @Override
aoqi@0 170 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 171 return super.process(helper, "-endorseddirs", arg);
aoqi@0 172 }
aoqi@0 173 },
aoqi@0 174
aoqi@0 175 PROC("-proc:", "opt.proc.none.only", STANDARD, BASIC, ONEOF, "none", "only"),
aoqi@0 176
aoqi@0 177 PROCESSOR("-processor", "opt.arg.class.list", "opt.processor", STANDARD, BASIC),
aoqi@0 178
aoqi@0 179 PROCESSORPATH("-processorpath", "opt.arg.path", "opt.processorpath", STANDARD, FILEMANAGER),
aoqi@0 180
aoqi@0 181 PARAMETERS("-parameters","opt.parameters", STANDARD, BASIC),
aoqi@0 182
aoqi@0 183 D("-d", "opt.arg.directory", "opt.d", STANDARD, FILEMANAGER),
aoqi@0 184
aoqi@0 185 S("-s", "opt.arg.directory", "opt.sourceDest", STANDARD, FILEMANAGER),
aoqi@0 186
aoqi@0 187 H("-h", "opt.arg.directory", "opt.headerDest", STANDARD, FILEMANAGER),
aoqi@0 188
aoqi@0 189 IMPLICIT("-implicit:", "opt.implicit", STANDARD, BASIC, ONEOF, "none", "class"),
aoqi@0 190
aoqi@0 191 ENCODING("-encoding", "opt.arg.encoding", "opt.encoding", STANDARD, FILEMANAGER) {
aoqi@0 192 @Override
aoqi@0 193 public boolean process(OptionHelper helper, String option, String operand) {
aoqi@0 194 return super.process(helper, option, operand);
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 },
aoqi@0 198
aoqi@0 199 SOURCE("-source", "opt.arg.release", "opt.source", STANDARD, BASIC) {
aoqi@0 200 @Override
aoqi@0 201 public boolean process(OptionHelper helper, String option, String operand) {
aoqi@0 202 Source source = Source.lookup(operand);
aoqi@0 203 if (source == null) {
aoqi@0 204 helper.error("err.invalid.source", operand);
aoqi@0 205 return true;
aoqi@0 206 }
aoqi@0 207 return super.process(helper, option, operand);
aoqi@0 208 }
aoqi@0 209 },
aoqi@0 210
aoqi@0 211 TARGET("-target", "opt.arg.release", "opt.target", STANDARD, BASIC) {
aoqi@0 212 @Override
aoqi@0 213 public boolean process(OptionHelper helper, String option, String operand) {
aoqi@0 214 Target target = Target.lookup(operand);
aoqi@0 215 if (target == null) {
aoqi@0 216 helper.error("err.invalid.target", operand);
aoqi@0 217 return true;
aoqi@0 218 }
aoqi@0 219 return super.process(helper, option, operand);
aoqi@0 220 }
aoqi@0 221 },
aoqi@0 222
aoqi@0 223 PROFILE("-profile", "opt.arg.profile", "opt.profile", STANDARD, BASIC) {
aoqi@0 224 @Override
aoqi@0 225 public boolean process(OptionHelper helper, String option, String operand) {
aoqi@0 226 Profile profile = Profile.lookup(operand);
aoqi@0 227 if (profile == null) {
aoqi@0 228 helper.error("err.invalid.profile", operand);
aoqi@0 229 return true;
aoqi@0 230 }
aoqi@0 231 return super.process(helper, option, operand);
aoqi@0 232 }
aoqi@0 233 },
aoqi@0 234
aoqi@0 235 VERSION("-version", "opt.version", STANDARD, INFO) {
aoqi@0 236 @Override
aoqi@0 237 public boolean process(OptionHelper helper, String option) {
aoqi@0 238 Log log = helper.getLog();
aoqi@0 239 String ownName = helper.getOwnName();
aoqi@0 240 log.printLines(PrefixKind.JAVAC, "version", ownName, JavaCompiler.version());
aoqi@0 241 return super.process(helper, option);
aoqi@0 242 }
aoqi@0 243 },
aoqi@0 244
aoqi@0 245 FULLVERSION("-fullversion", null, HIDDEN, INFO) {
aoqi@0 246 @Override
aoqi@0 247 public boolean process(OptionHelper helper, String option) {
aoqi@0 248 Log log = helper.getLog();
aoqi@0 249 String ownName = helper.getOwnName();
aoqi@0 250 log.printLines(PrefixKind.JAVAC, "fullVersion", ownName, JavaCompiler.fullVersion());
aoqi@0 251 return super.process(helper, option);
aoqi@0 252 }
aoqi@0 253 },
aoqi@0 254
aoqi@0 255 DIAGS("-XDdiags=", null, HIDDEN, INFO) {
aoqi@0 256 @Override
aoqi@0 257 public boolean process(OptionHelper helper, String option) {
aoqi@0 258 option = option.substring(option.indexOf('=') + 1);
aoqi@0 259 String diagsOption = option.contains("%") ?
aoqi@0 260 "-XDdiagsFormat=" :
aoqi@0 261 "-XDdiags=";
aoqi@0 262 diagsOption += option;
aoqi@0 263 if (XD.matches(diagsOption))
aoqi@0 264 return XD.process(helper, diagsOption);
aoqi@0 265 else
aoqi@0 266 return false;
aoqi@0 267 }
aoqi@0 268 },
aoqi@0 269
aoqi@0 270 HELP("-help", "opt.help", STANDARD, INFO) {
aoqi@0 271 @Override
aoqi@0 272 public boolean process(OptionHelper helper, String option) {
aoqi@0 273 Log log = helper.getLog();
aoqi@0 274 String ownName = helper.getOwnName();
aoqi@0 275 log.printLines(PrefixKind.JAVAC, "msg.usage.header", ownName);
aoqi@0 276 for (Option o: getJavaCompilerOptions()) {
aoqi@0 277 o.help(log, OptionKind.STANDARD);
aoqi@0 278 }
aoqi@0 279 log.printNewline();
aoqi@0 280 return super.process(helper, option);
aoqi@0 281 }
aoqi@0 282 },
aoqi@0 283
aoqi@0 284 A("-A", "opt.arg.key.equals.value", "opt.A", STANDARD, BASIC, true) {
aoqi@0 285 @Override
aoqi@0 286 public boolean matches(String arg) {
aoqi@0 287 return arg.startsWith("-A");
aoqi@0 288 }
aoqi@0 289
aoqi@0 290 @Override
aoqi@0 291 public boolean hasArg() {
aoqi@0 292 return false;
aoqi@0 293 }
aoqi@0 294 // Mapping for processor options created in
aoqi@0 295 // JavacProcessingEnvironment
aoqi@0 296 @Override
aoqi@0 297 public boolean process(OptionHelper helper, String option) {
aoqi@0 298 int argLength = option.length();
aoqi@0 299 if (argLength == 2) {
aoqi@0 300 helper.error("err.empty.A.argument");
aoqi@0 301 return true;
aoqi@0 302 }
aoqi@0 303 int sepIndex = option.indexOf('=');
aoqi@0 304 String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
aoqi@0 305 if (!JavacProcessingEnvironment.isValidOptionName(key)) {
aoqi@0 306 helper.error("err.invalid.A.key", option);
aoqi@0 307 return true;
aoqi@0 308 }
aoqi@0 309 return process(helper, option, option);
aoqi@0 310 }
aoqi@0 311 },
aoqi@0 312
aoqi@0 313 X("-X", "opt.X", STANDARD, INFO) {
aoqi@0 314 @Override
aoqi@0 315 public boolean process(OptionHelper helper, String option) {
aoqi@0 316 Log log = helper.getLog();
aoqi@0 317 for (Option o: getJavaCompilerOptions()) {
aoqi@0 318 o.help(log, OptionKind.EXTENDED);
aoqi@0 319 }
aoqi@0 320 log.printNewline();
aoqi@0 321 log.printLines(PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
aoqi@0 322 return super.process(helper, option);
aoqi@0 323 }
aoqi@0 324 },
aoqi@0 325
aoqi@0 326 // This option exists only for the purpose of documenting itself.
aoqi@0 327 // It's actually implemented by the launcher.
aoqi@0 328 J("-J", "opt.arg.flag", "opt.J", STANDARD, INFO, true) {
aoqi@0 329 @Override
aoqi@0 330 public boolean process(OptionHelper helper, String option) {
aoqi@0 331 throw new AssertionError
aoqi@0 332 ("the -J flag should be caught by the launcher.");
aoqi@0 333 }
aoqi@0 334 },
aoqi@0 335
aoqi@0 336 MOREINFO("-moreinfo", null, HIDDEN, BASIC) {
aoqi@0 337 @Override
aoqi@0 338 public boolean process(OptionHelper helper, String option) {
aoqi@0 339 Type.moreInfo = true;
aoqi@0 340 return super.process(helper, option);
aoqi@0 341 }
aoqi@0 342 },
aoqi@0 343
aoqi@0 344 // treat warnings as errors
aoqi@0 345 WERROR("-Werror", "opt.Werror", STANDARD, BASIC),
aoqi@0 346
aoqi@0 347 // prompt after each error
aoqi@0 348 // new Option("-prompt", "opt.prompt"),
aoqi@0 349 PROMPT("-prompt", null, HIDDEN, BASIC),
aoqi@0 350
aoqi@0 351 // dump stack on error
aoqi@0 352 DOE("-doe", null, HIDDEN, BASIC),
aoqi@0 353
aoqi@0 354 // output source after type erasure
aoqi@0 355 PRINTSOURCE("-printsource", null, HIDDEN, BASIC),
aoqi@0 356
aoqi@0 357 // display warnings for generic unchecked operations
aoqi@0 358 WARNUNCHECKED("-warnunchecked", null, HIDDEN, BASIC) {
aoqi@0 359 @Override
aoqi@0 360 public boolean process(OptionHelper helper, String option) {
aoqi@0 361 helper.put("-Xlint:unchecked", option);
aoqi@0 362 return false;
aoqi@0 363 }
aoqi@0 364 },
aoqi@0 365
aoqi@0 366 XMAXERRS("-Xmaxerrs", "opt.arg.number", "opt.maxerrs", EXTENDED, BASIC),
aoqi@0 367
aoqi@0 368 XMAXWARNS("-Xmaxwarns", "opt.arg.number", "opt.maxwarns", EXTENDED, BASIC),
aoqi@0 369
aoqi@0 370 XSTDOUT("-Xstdout", "opt.arg.file", "opt.Xstdout", EXTENDED, INFO) {
aoqi@0 371 @Override
aoqi@0 372 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 373 try {
aoqi@0 374 Log log = helper.getLog();
aoqi@0 375 // TODO: this file should be closed at the end of compilation
aoqi@0 376 log.setWriters(new PrintWriter(new FileWriter(arg), true));
aoqi@0 377 } catch (java.io.IOException e) {
aoqi@0 378 helper.error("err.error.writing.file", arg, e);
aoqi@0 379 return true;
aoqi@0 380 }
aoqi@0 381 return super.process(helper, option, arg);
aoqi@0 382 }
aoqi@0 383 },
aoqi@0 384
aoqi@0 385 XPRINT("-Xprint", "opt.print", EXTENDED, BASIC),
aoqi@0 386
aoqi@0 387 XPRINTROUNDS("-XprintRounds", "opt.printRounds", EXTENDED, BASIC),
aoqi@0 388
aoqi@0 389 XPRINTPROCESSORINFO("-XprintProcessorInfo", "opt.printProcessorInfo", EXTENDED, BASIC),
aoqi@0 390
aoqi@0 391 XPREFER("-Xprefer:", "opt.prefer", EXTENDED, BASIC, ONEOF, "source", "newer"),
aoqi@0 392
aoqi@0 393 // see enum PkgInfo
aoqi@0 394 XPKGINFO("-Xpkginfo:", "opt.pkginfo", EXTENDED, BASIC, ONEOF, "always", "legacy", "nonempty"),
aoqi@0 395
aoqi@0 396 /* -O is a no-op, accepted for backward compatibility. */
aoqi@0 397 O("-O", null, HIDDEN, BASIC),
aoqi@0 398
aoqi@0 399 /* -Xjcov produces tables to support the code coverage tool jcov. */
aoqi@0 400 XJCOV("-Xjcov", null, HIDDEN, BASIC),
aoqi@0 401
aoqi@0 402 PLUGIN("-Xplugin:", "opt.arg.plugin", "opt.plugin", EXTENDED, BASIC) {
aoqi@0 403 @Override
aoqi@0 404 public boolean process(OptionHelper helper, String option) {
aoqi@0 405 String p = option.substring(option.indexOf(':') + 1);
aoqi@0 406 String prev = helper.get(PLUGIN);
aoqi@0 407 helper.put(PLUGIN.text, (prev == null) ? p : prev + '\0' + p.trim());
aoqi@0 408 return false;
aoqi@0 409 }
aoqi@0 410 },
aoqi@0 411
aoqi@0 412 XDIAGS("-Xdiags:", "opt.diags", EXTENDED, BASIC, ONEOF, "compact", "verbose"),
aoqi@0 413
aoqi@0 414 /* This is a back door to the compiler's option table.
aoqi@0 415 * -XDx=y sets the option x to the value y.
aoqi@0 416 * -XDx sets the option x to the value x.
aoqi@0 417 */
aoqi@0 418 XD("-XD", null, HIDDEN, BASIC) {
aoqi@0 419 @Override
aoqi@0 420 public boolean matches(String s) {
aoqi@0 421 return s.startsWith(text);
aoqi@0 422 }
aoqi@0 423 @Override
aoqi@0 424 public boolean process(OptionHelper helper, String option) {
aoqi@0 425 option = option.substring(text.length());
aoqi@0 426 int eq = option.indexOf('=');
aoqi@0 427 String key = (eq < 0) ? option : option.substring(0, eq);
aoqi@0 428 String value = (eq < 0) ? option : option.substring(eq+1);
aoqi@0 429 helper.put(key, value);
aoqi@0 430 return false;
aoqi@0 431 }
aoqi@0 432 },
aoqi@0 433
aoqi@0 434 // This option exists only for the purpose of documenting itself.
aoqi@0 435 // It's actually implemented by the CommandLine class.
aoqi@0 436 AT("@", "opt.arg.file", "opt.AT", STANDARD, INFO, true) {
aoqi@0 437 @Override
aoqi@0 438 public boolean process(OptionHelper helper, String option) {
aoqi@0 439 throw new AssertionError("the @ flag should be caught by CommandLine.");
aoqi@0 440 }
aoqi@0 441 },
aoqi@0 442
aoqi@0 443 /*
aoqi@0 444 * TODO: With apt, the matches method accepts anything if
aoqi@0 445 * -XclassAsDecls is used; code elsewhere does the lookup to
aoqi@0 446 * see if the class name is both legal and found.
aoqi@0 447 *
aoqi@0 448 * In apt, the process method adds the candidate class file
aoqi@0 449 * name to a separate list.
aoqi@0 450 */
aoqi@0 451 SOURCEFILE("sourcefile", null, HIDDEN, INFO) {
aoqi@0 452 @Override
aoqi@0 453 public boolean matches(String s) {
aoqi@0 454 return s.endsWith(".java") // Java source file
aoqi@0 455 || SourceVersion.isName(s); // Legal type name
aoqi@0 456 }
aoqi@0 457 @Override
aoqi@0 458 public boolean process(OptionHelper helper, String option) {
aoqi@0 459 if (option.endsWith(".java") ) {
aoqi@0 460 File f = new File(option);
aoqi@0 461 if (!f.exists()) {
aoqi@0 462 helper.error("err.file.not.found", f);
aoqi@0 463 return true;
aoqi@0 464 }
aoqi@0 465 if (!f.isFile()) {
aoqi@0 466 helper.error("err.file.not.file", f);
aoqi@0 467 return true;
aoqi@0 468 }
aoqi@0 469 helper.addFile(f);
aoqi@0 470 } else {
aoqi@0 471 helper.addClassName(option);
aoqi@0 472 }
aoqi@0 473 return false;
aoqi@0 474 }
aoqi@0 475 };
aoqi@0 476
aoqi@0 477 /** The kind of an Option. This is used by the -help and -X options. */
aoqi@0 478 public enum OptionKind {
aoqi@0 479 /** A standard option, documented by -help. */
aoqi@0 480 STANDARD,
aoqi@0 481 /** An extended option, documented by -X. */
aoqi@0 482 EXTENDED,
aoqi@0 483 /** A hidden option, not documented. */
aoqi@0 484 HIDDEN,
aoqi@0 485 }
aoqi@0 486
aoqi@0 487 /** The group for an Option. This determines the situations in which the
aoqi@0 488 * option is applicable. */
aoqi@0 489 enum OptionGroup {
aoqi@0 490 /** A basic option, available for use on the command line or via the
aoqi@0 491 * Compiler API. */
aoqi@0 492 BASIC,
aoqi@0 493 /** An option for javac's standard JavaFileManager. Other file managers
aoqi@0 494 * may or may not support these options. */
aoqi@0 495 FILEMANAGER,
aoqi@0 496 /** A command-line option that requests information, such as -help. */
aoqi@0 497 INFO,
aoqi@0 498 /** A command-line "option" representing a file or class name. */
aoqi@0 499 OPERAND
aoqi@0 500 }
aoqi@0 501
aoqi@0 502 /** The kind of choice for "choice" options. */
aoqi@0 503 enum ChoiceKind {
aoqi@0 504 /** The expected value is exactly one of the set of choices. */
aoqi@0 505 ONEOF,
aoqi@0 506 /** The expected value is one of more of the set of choices. */
aoqi@0 507 ANYOF
aoqi@0 508 }
aoqi@0 509
aoqi@0 510 public final String text;
aoqi@0 511
aoqi@0 512 final OptionKind kind;
aoqi@0 513
aoqi@0 514 final OptionGroup group;
aoqi@0 515
aoqi@0 516 /** Documentation key for arguments.
aoqi@0 517 */
aoqi@0 518 final String argsNameKey;
aoqi@0 519
aoqi@0 520 /** Documentation key for description.
aoqi@0 521 */
aoqi@0 522 final String descrKey;
aoqi@0 523
aoqi@0 524 /** Suffix option (-foo=bar or -foo:bar)
aoqi@0 525 */
aoqi@0 526 final boolean hasSuffix;
aoqi@0 527
aoqi@0 528 /** The kind of choices for this option, if any.
aoqi@0 529 */
aoqi@0 530 final ChoiceKind choiceKind;
aoqi@0 531
aoqi@0 532 /** The choices for this option, if any, and whether or not the choices
aoqi@0 533 * are hidden
aoqi@0 534 */
aoqi@0 535 final Map<String,Boolean> choices;
aoqi@0 536
aoqi@0 537
aoqi@0 538 Option(String text, String descrKey,
aoqi@0 539 OptionKind kind, OptionGroup group) {
aoqi@0 540 this(text, null, descrKey, kind, group, null, null, false);
aoqi@0 541 }
aoqi@0 542
aoqi@0 543 Option(String text, String argsNameKey, String descrKey,
aoqi@0 544 OptionKind kind, OptionGroup group) {
aoqi@0 545 this(text, argsNameKey, descrKey, kind, group, null, null, false);
aoqi@0 546 }
aoqi@0 547
aoqi@0 548 Option(String text, String argsNameKey, String descrKey,
aoqi@0 549 OptionKind kind, OptionGroup group, boolean doHasSuffix) {
aoqi@0 550 this(text, argsNameKey, descrKey, kind, group, null, null, doHasSuffix);
aoqi@0 551 }
aoqi@0 552
aoqi@0 553 Option(String text, String descrKey,
aoqi@0 554 OptionKind kind, OptionGroup group,
aoqi@0 555 ChoiceKind choiceKind, Map<String,Boolean> choices) {
aoqi@0 556 this(text, null, descrKey, kind, group, choiceKind, choices, false);
aoqi@0 557 }
aoqi@0 558
aoqi@0 559 Option(String text, String descrKey,
aoqi@0 560 OptionKind kind, OptionGroup group,
aoqi@0 561 ChoiceKind choiceKind, String... choices) {
aoqi@0 562 this(text, null, descrKey, kind, group, choiceKind,
aoqi@0 563 createChoices(choices), false);
aoqi@0 564 }
aoqi@0 565 // where
aoqi@0 566 private static Map<String,Boolean> createChoices(String... choices) {
aoqi@0 567 Map<String,Boolean> map = new LinkedHashMap<String,Boolean>();
aoqi@0 568 for (String c: choices)
aoqi@0 569 map.put(c, false);
aoqi@0 570 return map;
aoqi@0 571 }
aoqi@0 572
aoqi@0 573 private Option(String text, String argsNameKey, String descrKey,
aoqi@0 574 OptionKind kind, OptionGroup group,
aoqi@0 575 ChoiceKind choiceKind, Map<String,Boolean> choices,
aoqi@0 576 boolean doHasSuffix) {
aoqi@0 577 this.text = text;
aoqi@0 578 this.argsNameKey = argsNameKey;
aoqi@0 579 this.descrKey = descrKey;
aoqi@0 580 this.kind = kind;
aoqi@0 581 this.group = group;
aoqi@0 582 this.choiceKind = choiceKind;
aoqi@0 583 this.choices = choices;
aoqi@0 584 char lastChar = text.charAt(text.length()-1);
aoqi@0 585 this.hasSuffix = doHasSuffix || lastChar == ':' || lastChar == '=';
aoqi@0 586 }
aoqi@0 587
aoqi@0 588 public String getText() {
aoqi@0 589 return text;
aoqi@0 590 }
aoqi@0 591
aoqi@0 592 public OptionKind getKind() {
aoqi@0 593 return kind;
aoqi@0 594 }
aoqi@0 595
aoqi@0 596 public boolean hasArg() {
aoqi@0 597 return argsNameKey != null && !hasSuffix;
aoqi@0 598 }
aoqi@0 599
aoqi@0 600 public boolean matches(String option) {
aoqi@0 601 if (!hasSuffix)
aoqi@0 602 return option.equals(text);
aoqi@0 603
aoqi@0 604 if (!option.startsWith(text))
aoqi@0 605 return false;
aoqi@0 606
aoqi@0 607 if (choices != null) {
aoqi@0 608 String arg = option.substring(text.length());
aoqi@0 609 if (choiceKind == ChoiceKind.ONEOF)
aoqi@0 610 return choices.keySet().contains(arg);
aoqi@0 611 else {
aoqi@0 612 for (String a: arg.split(",+")) {
aoqi@0 613 if (!choices.keySet().contains(a))
aoqi@0 614 return false;
aoqi@0 615 }
aoqi@0 616 }
aoqi@0 617 }
aoqi@0 618
aoqi@0 619 return true;
aoqi@0 620 }
aoqi@0 621
aoqi@0 622 public boolean process(OptionHelper helper, String option, String arg) {
aoqi@0 623 if (choices != null) {
aoqi@0 624 if (choiceKind == ChoiceKind.ONEOF) {
aoqi@0 625 // some clients like to see just one of option+choice set
aoqi@0 626 for (String s: choices.keySet())
aoqi@0 627 helper.remove(option + s);
aoqi@0 628 String opt = option + arg;
aoqi@0 629 helper.put(opt, opt);
aoqi@0 630 // some clients like to see option (without trailing ":")
aoqi@0 631 // set to arg
aoqi@0 632 String nm = option.substring(0, option.length() - 1);
aoqi@0 633 helper.put(nm, arg);
aoqi@0 634 } else {
aoqi@0 635 // set option+word for each word in arg
aoqi@0 636 for (String a: arg.split(",+")) {
aoqi@0 637 String opt = option + a;
aoqi@0 638 helper.put(opt, opt);
aoqi@0 639 }
aoqi@0 640 }
aoqi@0 641 }
aoqi@0 642 helper.put(option, arg);
aoqi@0 643 return false;
aoqi@0 644 }
aoqi@0 645
aoqi@0 646 public boolean process(OptionHelper helper, String option) {
aoqi@0 647 if (hasSuffix)
aoqi@0 648 return process(helper, text, option.substring(text.length()));
aoqi@0 649 else
aoqi@0 650 return process(helper, option, option);
aoqi@0 651 }
aoqi@0 652
aoqi@0 653 void help(Log log, OptionKind kind) {
aoqi@0 654 if (this.kind != kind)
aoqi@0 655 return;
aoqi@0 656
aoqi@0 657 log.printRawLines(WriterKind.NOTICE,
aoqi@0 658 String.format(" %-26s %s",
aoqi@0 659 helpSynopsis(log),
aoqi@0 660 log.localize(PrefixKind.JAVAC, descrKey)));
aoqi@0 661
aoqi@0 662 }
aoqi@0 663
aoqi@0 664 private String helpSynopsis(Log log) {
aoqi@0 665 StringBuilder sb = new StringBuilder();
aoqi@0 666 sb.append(text);
aoqi@0 667 if (argsNameKey == null) {
aoqi@0 668 if (choices != null) {
aoqi@0 669 String sep = "{";
aoqi@0 670 for (Map.Entry<String,Boolean> e: choices.entrySet()) {
aoqi@0 671 if (!e.getValue()) {
aoqi@0 672 sb.append(sep);
aoqi@0 673 sb.append(e.getKey());
aoqi@0 674 sep = ",";
aoqi@0 675 }
aoqi@0 676 }
aoqi@0 677 sb.append("}");
aoqi@0 678 }
aoqi@0 679 } else {
aoqi@0 680 if (!hasSuffix)
aoqi@0 681 sb.append(" ");
aoqi@0 682 sb.append(log.localize(PrefixKind.JAVAC, argsNameKey));
aoqi@0 683
aoqi@0 684 }
aoqi@0 685
aoqi@0 686 return sb.toString();
aoqi@0 687 }
aoqi@0 688
aoqi@0 689 // For -XpkgInfo:value
aoqi@0 690 public enum PkgInfo {
aoqi@0 691 /**
aoqi@0 692 * Always generate package-info.class for every package-info.java file.
aoqi@0 693 * The file may be empty if there annotations with a RetentionPolicy
aoqi@0 694 * of CLASS or RUNTIME. This option may be useful in conjunction with
aoqi@0 695 * build systems (such as Ant) that expect javac to generate at least
aoqi@0 696 * one .class file for every .java file.
aoqi@0 697 */
aoqi@0 698 ALWAYS,
aoqi@0 699 /**
aoqi@0 700 * Generate a package-info.class file if package-info.java contains
aoqi@0 701 * annotations. The file may be empty if all the annotations have
aoqi@0 702 * a RetentionPolicy of SOURCE.
aoqi@0 703 * This value is just for backwards compatibility with earlier behavior.
aoqi@0 704 * Either of the other two values are to be preferred to using this one.
aoqi@0 705 */
aoqi@0 706 LEGACY,
aoqi@0 707 /**
aoqi@0 708 * Generate a package-info.class file if and only if there are annotations
aoqi@0 709 * in package-info.java to be written into it.
aoqi@0 710 */
aoqi@0 711 NONEMPTY;
aoqi@0 712
aoqi@0 713 public static PkgInfo get(Options options) {
aoqi@0 714 String v = options.get(XPKGINFO);
aoqi@0 715 return (v == null
aoqi@0 716 ? PkgInfo.LEGACY
aoqi@0 717 : PkgInfo.valueOf(StringUtils.toUpperCase(v)));
aoqi@0 718 }
aoqi@0 719 }
aoqi@0 720
aoqi@0 721 private static Map<String,Boolean> getXLintChoices() {
aoqi@0 722 Map<String,Boolean> choices = new LinkedHashMap<String,Boolean>();
aoqi@0 723 choices.put("all", false);
aoqi@0 724 for (Lint.LintCategory c : Lint.LintCategory.values())
aoqi@0 725 choices.put(c.option, c.hidden);
aoqi@0 726 for (Lint.LintCategory c : Lint.LintCategory.values())
aoqi@0 727 choices.put("-" + c.option, c.hidden);
aoqi@0 728 choices.put("none", false);
aoqi@0 729 return choices;
aoqi@0 730 }
aoqi@0 731
aoqi@0 732 static Set<Option> getJavaCompilerOptions() {
aoqi@0 733 return EnumSet.allOf(Option.class);
aoqi@0 734 }
aoqi@0 735
aoqi@0 736 public static Set<Option> getJavacFileManagerOptions() {
aoqi@0 737 return getOptions(EnumSet.of(FILEMANAGER));
aoqi@0 738 }
aoqi@0 739
aoqi@0 740 public static Set<Option> getJavacToolOptions() {
aoqi@0 741 return getOptions(EnumSet.of(BASIC));
aoqi@0 742 }
aoqi@0 743
aoqi@0 744 static Set<Option> getOptions(Set<OptionGroup> desired) {
aoqi@0 745 Set<Option> options = EnumSet.noneOf(Option.class);
aoqi@0 746 for (Option option : Option.values())
aoqi@0 747 if (desired.contains(option.group))
aoqi@0 748 options.add(option);
aoqi@0 749 return Collections.unmodifiableSet(options);
aoqi@0 750 }
aoqi@0 751
aoqi@0 752 }

mercurial