ToolOption.java revision 3792:d516975e8110
1/* 2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.javadoc.internal.tool; 27 28import java.util.ArrayList; 29import java.util.Arrays; 30import java.util.EnumMap; 31import java.util.LinkedHashMap; 32import java.util.List; 33import java.util.Map; 34 35import javax.lang.model.element.ElementKind; 36 37import com.sun.tools.javac.main.Option; 38import com.sun.tools.javac.main.Option.OptionKind; 39import com.sun.tools.javac.main.OptionHelper; 40import com.sun.tools.javac.util.Options; 41 42import static com.sun.tools.javac.main.Option.OptionKind.*; 43import static jdk.javadoc.internal.tool.Main.Result.*; 44 45/** 46 * javadoc tool options. 47 * 48 * <p><b>This is NOT part of any supported API. 49 * If you write code that depends on this, you do so at your own risk. 50 * This code and its internal interfaces are subject to change or 51 * deletion without notice.</b> 52 */ 53public enum ToolOption { 54 55 // ----- options for underlying compiler ----- 56 57 BOOTCLASSPATH("-bootclasspath", STANDARD, true) { 58 @Override 59 public void process(Helper helper, String arg) { 60 Option.BOOT_CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg); 61 } 62 }, 63 64 CLASS_PATH("--class-path -classpath -cp", STANDARD, true) { 65 @Override 66 public void process(Helper helper, String arg) { 67 Option.CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg); 68 } 69 }, 70 71 EXTDIRS("-extdirs", STANDARD, true) { 72 @Override 73 public void process(Helper helper, String arg) { 74 Option.EXTDIRS.process(helper.getOptionHelper(), primaryName, arg); 75 } 76 }, 77 78 SOURCE_PATH("--source-path -sourcepath", STANDARD, true) { 79 @Override 80 public void process(Helper helper, String arg) { 81 Option.SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg); 82 } 83 }, 84 85 MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) { 86 @Override 87 public void process(Helper helper, String arg) { 88 Option.MODULE_SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg); 89 } 90 }, 91 92 UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) { 93 @Override 94 public void process(Helper helper, String arg) { 95 Option.UPGRADE_MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg); 96 } 97 }, 98 99 SYSTEM("--system", STANDARD, true) { 100 @Override 101 public void process(Helper helper, String arg) { 102 Option.SYSTEM.process(helper.getOptionHelper(), primaryName, arg); 103 } 104 }, 105 106 MODULE_PATH("--module-path -p", STANDARD, true) { 107 @Override 108 public void process(Helper helper, String arg) { 109 Option.MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg); 110 } 111 }, 112 113 ADD_MODULES("--add-modules", STANDARD, true) { 114 @Override 115 public void process(Helper helper, String arg) { 116 Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg); 117 } 118 }, 119 120 LIMIT_MODULES("--limit-modules", STANDARD, true) { 121 @Override 122 public void process(Helper helper, String arg) { 123 Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg); 124 } 125 }, 126 127 MODULE("--module", STANDARD, true) { 128 @Override 129 public void process(Helper helper, String arg) { 130 helper.addToList(this, ",", arg); 131 } 132 }, 133 134 ENCODING("-encoding", STANDARD, true) { 135 @Override 136 public void process(Helper helper, String arg) { 137 Option.ENCODING.process(helper.getOptionHelper(), primaryName, arg); 138 } 139 }, 140 141 RELEASE("--release", STANDARD, true) { 142 @Override 143 public void process(Helper helper, String arg) { 144 Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg); 145 } 146 }, 147 148 SOURCE("-source", STANDARD, true) { 149 @Override 150 public void process(Helper helper, String arg) { 151 Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg); 152 } 153 }, 154 155 XMAXERRS("-Xmaxerrs", EXTENDED, true) { 156 @Override 157 public void process(Helper helper, String arg) { 158 Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg); 159 } 160 }, 161 162 XMAXWARNS("-Xmaxwarns", EXTENDED, true) { 163 @Override 164 public void process(Helper helper, String arg) { 165 Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg); 166 } 167 }, 168 169 ADD_READS("--add-reads", EXTENDED, true) { 170 @Override 171 public void process(Helper helper, String arg) { 172 Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg); 173 } 174 }, 175 176 ADD_EXPORTS("--add-exports", EXTENDED, true) { 177 @Override 178 public void process(Helper helper, String arg) { 179 Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg); 180 } 181 }, 182 183 XMODULE("-Xmodule:", EXTENDED, false) { 184 @Override 185 public void process(Helper helper, String arg) { 186 Option.XMODULE.process(helper.getOptionHelper(), arg); 187 } 188 }, 189 190 PATCH_MODULE("--patch-module", EXTENDED, true) { 191 @Override 192 public void process(Helper helper, String arg) { 193 Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg); 194 } 195 }, 196 197 // ----- doclet options ----- 198 199 DOCLET("-doclet", STANDARD, true), // handled in setDocletInvoker 200 201 DOCLETPATH("-docletpath", STANDARD, true), // handled in setDocletInvoker 202 203 // ----- selection options ----- 204 205 SUBPACKAGES("-subpackages", STANDARD, true) { 206 @Override 207 public void process(Helper helper, String arg) { 208 helper.addToList(this, ":", arg); 209 } 210 }, 211 212 EXCLUDE("-exclude", STANDARD, true) { 213 @Override 214 public void process(Helper helper, String arg) { 215 helper.addToList(this, ":", arg); 216 } 217 }, 218 219 // ----- filtering options ----- 220 221 PACKAGE("-package", STANDARD) { 222 @Override 223 public void process(Helper helper) throws OptionException { 224 helper.setSimpleFilter("package"); 225 } 226 }, 227 228 PRIVATE("-private", STANDARD) { 229 @Override 230 public void process(Helper helper) throws OptionException { 231 helper.setSimpleFilter("private"); 232 } 233 }, 234 235 PROTECTED("-protected", STANDARD) { 236 @Override 237 public void process(Helper helper) throws OptionException { 238 helper.setSimpleFilter("protected"); 239 } 240 }, 241 242 PUBLIC("-public", STANDARD) { 243 @Override 244 public void process(Helper helper) throws OptionException { 245 helper.setSimpleFilter("public"); 246 } 247 }, 248 249 SHOW_MEMBERS("--show-members", STANDARD, true) { 250 @Override 251 public void process(Helper helper, String arg) throws OptionException { 252 helper.setFilter(this, arg); 253 } 254 }, 255 256 SHOW_TYPES("--show-types", STANDARD, true) { 257 @Override 258 public void process(Helper helper, String arg) throws OptionException { 259 helper.setFilter(this, arg); 260 } 261 }, 262 263 SHOW_PACKAGES("--show-packages", STANDARD, true) { 264 @Override 265 public void process(Helper helper, String arg) throws OptionException { 266 helper.setShowPackageAccess(SHOW_PACKAGES, arg); 267 } 268 }, 269 270 SHOW_MODULE_CONTENTS("--show-module-contents", STANDARD, true) { 271 @Override 272 public void process(Helper helper, String arg) throws OptionException { 273 helper.setShowModuleContents(SHOW_MODULE_CONTENTS, arg); 274 } 275 }, 276 277 EXPAND_REQUIRES("--expand-requires", STANDARD, true) { 278 @Override 279 public void process(Helper helper, String arg) throws OptionException { 280 helper.setExpandRequires(EXPAND_REQUIRES, arg); 281 } 282 }, 283 284 // ----- output control options ----- 285 286 QUIET("-quiet", STANDARD) { 287 @Override 288 public void process(Helper helper) { 289 helper.jdtoolOpts.put(QUIET, true); 290 } 291 }, 292 293 VERBOSE("-verbose", STANDARD) { 294 @Override 295 public void process(Helper helper) { 296 helper.compOpts.put("-verbose", ""); 297 } 298 }, 299 300 XWERROR("-Xwerror", HIDDEN) { 301 @Override 302 public void process(Helper helper) { 303 helper.rejectWarnings = true; 304 305 } 306 }, 307 308 // ----- other options ----- 309 310 BREAKITERATOR("-breakiterator", STANDARD) { 311 @Override 312 public void process(Helper helper) { 313 helper.breakiterator = true; 314 } 315 }, 316 317 LOCALE("-locale", STANDARD, true) { 318 @Override 319 public void process(Helper helper, String arg) { 320 helper.docLocale = arg; 321 } 322 }, 323 324 XCLASSES("-Xclasses", HIDDEN) { 325 @Override 326 public void process(Helper helper) { 327 helper.jdtoolOpts.put(XCLASSES, true); 328 } 329 }, 330 331 DUMPONERROR("--dump-on-error", HIDDEN) { 332 @Override 333 public void process(Helper helper) { 334 helper.dumpOnError = true; 335 } 336 }, 337 338 // ----- help options ----- 339 340 HELP("--help -help", STANDARD) { 341 @Override 342 public void process(Helper helper) throws OptionException { 343 throw new OptionException(OK, helper::usage); 344 } 345 }, 346 347 X("-X", STANDARD) { 348 @Override 349 public void process(Helper helper) throws OptionException { 350 throw new OptionException(OK, helper::Xusage); 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", STANDARD, true) { 357 @Override 358 public void process(Helper helper) { 359 throw new AssertionError("the -J flag should be caught by the launcher."); 360 } 361 }, 362 363 // This option exists only for the purpose of documenting itself. 364 // It's actually implemented ahead of the normal option decoding loop. 365 Xold("-Xold", EXTENDED) { 366 @Override 367 public void process(Helper helper) { 368 throw new AssertionError("the -Xold flag should be handled earlier."); 369 } 370 }; 371 372 public final String primaryName; 373 public final List<String> names; 374 public final OptionKind kind; 375 public final boolean hasArg; 376 public final boolean hasSuffix; // ex: foo:bar or -foo=bar 377 378 ToolOption(String opt, OptionKind kind) { 379 this(opt, kind, false); 380 } 381 382 ToolOption(String names, OptionKind kind, boolean hasArg) { 383 this.names = Arrays.asList(names.split("\\s+")); 384 this.primaryName = this.names.get(0); 385 this.kind = kind; 386 this.hasArg = hasArg; 387 char lastChar = names.charAt(names.length() - 1); 388 this.hasSuffix = lastChar == ':' || lastChar == '='; 389 } 390 391 void process(Helper helper, String arg) throws OptionException { } 392 393 void process(Helper helper) throws OptionException { } 394 395 List<String> getNames() { 396 return names; 397 } 398 399 String getParameters(Messager messager) { 400 return (hasArg || primaryName.endsWith(":")) 401 ? messager.getText(getKey(primaryName, ".arg")) 402 : null; 403 } 404 405 String getDescription(Messager messager) { 406 return messager.getText(getKey(primaryName, ".desc")); 407 } 408 409 private String getKey(String optionName, String suffix) { 410 return "main.opt." 411 + optionName 412 .replaceAll("^-*", "") // remove leading '-' 413 .replaceAll("[^A-Za-z0-9]+$", "") // remove trailing non-alphanumeric 414 .replaceAll("[^A-Za-z0-9]", ".") // replace internal non-alphanumeric 415 + suffix; 416 } 417 418 419 static ToolOption get(String name) { 420 String oname = name; 421 if (name.contains(":")) { 422 oname = name.substring(0, name.indexOf(':') + 1); 423 } else if (name.contains("=")) { 424 oname = name.substring(0, name.indexOf('=')); 425 } 426 for (ToolOption o : values()) { 427 for (String n : o.names) { 428 if (oname.equals(n)) { 429 return o; 430 } 431 } 432 } 433 return null; 434 } 435 436 static abstract class Helper { 437 438 // File manager options 439 final Map<Option, String> fileManagerOpts = new LinkedHashMap<>(); 440 441 /** javac options, set by various options. */ 442 Options compOpts; // = Options.instance(context) 443 444 /** Javadoc tool options */ 445 final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class); 446 447 /** dump stack traces for debugging etc.*/ 448 boolean dumpOnError = false; 449 450 /** Set by -breakiterator. */ 451 boolean breakiterator = false; 452 453 /** Set by -Xwerror. */ 454 boolean rejectWarnings = false; 455 456 /** Set by -prompt. */ 457 boolean promptOnError; 458 459 /** Set by -locale. */ 460 String docLocale = ""; 461 462 Helper() { 463 populateDefaultAccessMap(); 464 } 465 466 abstract void usage(); 467 abstract void Xusage(); 468 469 abstract String getLocalizedMessage(String msg, Object... args); 470 471 abstract OptionHelper getOptionHelper(); 472 473 @SuppressWarnings("unchecked") 474 void addToList(ToolOption opt, String delimiter, String str) { 475 List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>()); 476 list.addAll(Arrays.asList(str.split(delimiter))); 477 jdtoolOpts.put(opt, list); 478 } 479 480 void setExpandRequires(ToolOption opt, String arg) throws OptionException { 481 switch (arg) { 482 case "transitive": 483 jdtoolOpts.put(opt, AccessKind.PUBLIC); 484 break; 485 case "all": 486 jdtoolOpts.put(opt, AccessKind.PRIVATE); 487 break; 488 default: 489 String text = getLocalizedMessage("main.illegal_option_value", arg); 490 throw new IllegalOptionValue(this::usage, text); 491 } 492 } 493 494 void setShowModuleContents(ToolOption opt, String arg) throws OptionException { 495 switch (arg) { 496 case "api": 497 jdtoolOpts.put(opt, AccessKind.PUBLIC); 498 break; 499 case "all": 500 jdtoolOpts.put(opt, AccessKind.PRIVATE); 501 break; 502 default: 503 String text = getLocalizedMessage("main.illegal_option_value", arg); 504 throw new IllegalOptionValue(this::usage, text); 505 } 506 } 507 508 void setShowPackageAccess(ToolOption opt, String arg) throws OptionException { 509 switch (arg) { 510 case "exported": 511 jdtoolOpts.put(opt, AccessKind.PUBLIC); 512 break; 513 case "all": 514 jdtoolOpts.put(opt, AccessKind.PRIVATE); 515 break; 516 default: 517 String text = getLocalizedMessage("main.illegal_option_value", arg); 518 throw new IllegalOptionValue(this::usage, text); 519 } 520 } 521 522 523 void setFilter(ToolOption opt, String arg) throws OptionException { 524 jdtoolOpts.put(opt, getAccessValue(arg)); 525 } 526 527 void setSimpleFilter(String arg) throws OptionException { 528 handleSimpleOption(arg); 529 } 530 531 void setFileManagerOpt(Option opt, String arg) { 532 fileManagerOpts.put(opt, arg); 533 } 534 535 void handleSimpleOption(String arg) throws OptionException { 536 populateSimpleAccessMap(getAccessValue(arg)); 537 } 538 539 /* 540 * This method handles both the simple options -package, 541 * -private, so on, in addition to the new ones such as 542 * --show-types:public and so on. 543 */ 544 private AccessKind getAccessValue(String arg) throws OptionException { 545 int colon = arg.indexOf(':'); 546 String value = (colon > 0) 547 ? arg.substring(colon + 1) 548 : arg; 549 switch (value) { 550 case "public": 551 return AccessKind.PUBLIC; 552 case "protected": 553 return AccessKind.PROTECTED; 554 case "package": 555 return AccessKind.PACKAGE; 556 case "private": 557 return AccessKind.PRIVATE; 558 default: 559 String text = getLocalizedMessage("main.illegal_option_value", value); 560 throw new IllegalOptionValue(this::usage, text); 561 } 562 } 563 564 /* 565 * Sets the entire kind map to PROTECTED this is the default. 566 */ 567 private void populateDefaultAccessMap() { 568 populateSimpleAccessMap(AccessKind.PROTECTED); 569 } 570 571 /* 572 * This sets access to all the allowed kinds in the 573 * access map. 574 */ 575 void populateSimpleAccessMap(AccessKind accessValue) { 576 for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) { 577 switch (kind) { 578 case METHOD: 579 jdtoolOpts.put(SHOW_MEMBERS, accessValue); 580 break; 581 case CLASS: 582 jdtoolOpts.put(SHOW_TYPES, accessValue); 583 break; 584 case PACKAGE: 585 jdtoolOpts.put(SHOW_PACKAGES, accessValue); 586 break; 587 case MODULE: 588 jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue); 589 break; 590 default: 591 throw new AssertionError("unknown element kind:" + kind); 592 } 593 } 594 } 595 } 596} 597