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