1 /*
   2  * Copyright (c) 2012, 2019, 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 
  26 package jdk.javadoc.internal.tool;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Arrays;
  30 import java.util.LinkedHashMap;
  31 import java.util.List;
  32 import java.util.Map;
  33 import javax.lang.model.element.ElementKind;
  34 
  35 import com.sun.tools.javac.main.Option;
  36 import com.sun.tools.javac.main.Option.InvalidValueException;
  37 import com.sun.tools.javac.main.Option.OptionKind;
  38 import com.sun.tools.javac.main.OptionHelper;
  39 import com.sun.tools.javac.util.Context;
  40 import com.sun.tools.javac.util.Options;
  41 
  42 import static com.sun.tools.javac.main.Option.OptionKind.EXTENDED;
  43 import static com.sun.tools.javac.main.Option.OptionKind.HIDDEN;
  44 import static com.sun.tools.javac.main.Option.OptionKind.STANDARD;
  45 import static jdk.javadoc.internal.tool.Main.Result.OK;
  46 
  47 /**
  48  * Storage and support for javadoc tool options, as distinct from
  49  * the options supported by any doclet that may be in use.
  50  * The tool options includes those options which are delegated
  51  * to javac and/or the file manager, such as options to set
  52  * the source level, and path options to locate the files to be
  53  * documented.
  54  *
  55  *  <p><b>This is NOT part of any supported API.
  56  *  If you write code that depends on this, you do so at your own risk.
  57  *  This code and its internal interfaces are subject to change or
  58  *  deletion without notice.</b>
  59  */
  60 public class ToolOptions {
  61     // The following are the names of options handled in the first pass of option decoding,
  62     // in Start.preprocess.
  63     static final String DOCLET = "-doclet";
  64     static final String DOCLET_PATH = "-docletpath";
  65     static final String DUMP_ON_ERROR = "--dump-on-error";
  66     static final String J = "-J";
  67     static final String LOCALE = "-locale";
  68 
  69     /**
  70      * Argument for command-line option {@code -breakiterator}.
  71      */
  72     private boolean breakIterator = false;
  73 
  74     /**
  75      * Argument for command-line option {@code -locale}.
  76      */
  77     private String docLocale = "";
  78 
  79     /**
  80      * Argument for command-line option {@code --dump-on-error}.
  81      * Dump stack traces for debugging etc.
  82      * Similar to javac {@code -doe}.
  83      */
  84     private boolean dumpOnError = false;
  85 
  86     /**
  87      * Argument for command-line option {@code -exclude}.
  88      */
  89     private List<String> excludes = new ArrayList<>();
  90 
  91     /**
  92      * Argument for command-line option {@code --expand-requires}.
  93      */
  94     private AccessKind expandRequires;
  95 
  96     /**
  97      * Argument for command-line option {@code --ignore-source-errors}.
  98      */
  99     private boolean ignoreSourceErrors;
 100 
 101     /**
 102      * Argument for command-line option {@code --module}.
 103      */
 104     private List<String> modules = new ArrayList<>();
 105 
 106     /**
 107      * Argument for command-line option {@code -Xwerror}.
 108      * Set by -Xwerror.
 109      */
 110     private boolean rejectWarnings = false;
 111 
 112     /**
 113      * Argument for command-line option {@code --show-members}.
 114      */
 115     private AccessKind showMembersAccess;
 116 
 117     /**
 118      * Argument for command-line option {@code --show-types}.
 119      */
 120     private AccessKind showTypesAccess;
 121 
 122     /**
 123      * Argument for command-line option {@code --show-packages}.
 124      */
 125     private AccessKind showPackagesAccess;
 126 
 127     /**
 128      * Argument for command-line option {@code --show-module-contents}.
 129      */
 130     private AccessKind showModuleContents;
 131 
 132     /**
 133      * Argument for command-line option {@code -quiet}.
 134      */
 135     private boolean quiet;
 136 
 137     /**
 138      * Argument for command-line option {@code -subpackages}.
 139      */
 140     private List<String> subpackages = new ArrayList<>();
 141 
 142     /**
 143      * Argument for command-line option {@code -verbose}.
 144      */
 145     private boolean verbose;
 146 
 147     /**
 148      * Argument for command-line option {@code -xclasses}.
 149      * If true, names on the command line that would normally be
 150      * treated as package names are treated as class names instead.
 151      */
 152     private boolean xclasses = false;
 153 
 154     /**
 155      * Options to be given to the file manager, such as path options
 156      * indicating where to find files to be documented.
 157      */
 158     private final Map<Option, String> fileManagerOpts;
 159 
 160     /**
 161      * Options to be given to the underlying compiler front-end,
 162      * such as options to indicate the source level to be used.
 163      */
 164     private final Options compOpts;
 165 
 166     /**
 167      * The "helper" to be used when processing compiler options.
 168      */
 169     private final OptionHelper compilerOptionHelper;
 170 
 171     /**
 172      * The messager to be used to report diagnostics..
 173      */
 174     private final Messager messager;
 175 
 176     /**
 177      * The helper for help and version options
 178      */
 179     private final ShowHelper showHelper;
 180 
 181     /**
 182      * Creates an object to handle tool options.
 183      *
 184      * @param context the context used to find other tool-related components
 185      * @param messager the messager to be used to report diagnostics
 186      */
 187     ToolOptions(Context context, Messager messager, ShowHelper showHelper) {
 188         this.messager = messager;
 189         this.showHelper = showHelper;
 190         compOpts = Options.instance(context);
 191         fileManagerOpts = new LinkedHashMap<>();
 192         compilerOptionHelper = getOptionHelper();
 193         setAccessDefault();
 194     }
 195 
 196     /**
 197      * Creates a minimal object, just sufficient to check the names of the
 198      * supported options.
 199      */
 200     private ToolOptions() {
 201         compOpts = null;
 202         compilerOptionHelper = null;
 203         fileManagerOpts = null;
 204         messager = null;
 205         showHelper = null;
 206     }
 207 
 208     /**
 209      * Returns the set of options supported by the tool, excluding any options
 210      * that are managed by the doclet that may be in use.
 211      *
 212      * @return the set of options
 213      */
 214     public List<ToolOption> getSupportedOptions() {
 215         return supportedOptions;
 216     }
 217 
 218     /**
 219      * Determines if the given option is supported and if so, the
 220      * number of arguments the option takes.
 221      *
 222      * @param option an option
 223      * @return the number of arguments the given option takes or -1 if
 224      * the option is not supported
 225      * @see javax.tools.DocumentationTool#isSupportedOption(String)
 226      */
 227     public static int isSupportedOption(String option) {
 228         ToolOptions t = new ToolOptions();
 229         for (ToolOption o : t.supportedOptions) {
 230             for (String name : o.names) {
 231                 if (name.equals(option))
 232                     return o.hasArg ? 1 : 0;
 233             }
 234         }
 235         return -1;
 236     }
 237 
 238     /**
 239      * Returns the option to be used to process an argument such as may be found on
 240      * the command line.
 241      *
 242      * @param arg the argument
 243      * @return the option
 244      */
 245     ToolOption getOption(String arg) {
 246         String name = arg;
 247         if (arg.startsWith("--") && arg.contains("=")) {
 248             name = arg.substring(0, arg.indexOf('='));
 249         }
 250         for (ToolOption o : supportedOptions) {
 251             for (String n : o.names) {
 252                 if (name.equals(n)) {
 253                     return o;
 254                 }
 255             }
 256         }
 257         return null;
 258     }
 259 
 260     private List<ToolOption> supportedOptions = List.of(
 261             // ----- options for underlying compiler -----
 262 
 263             new ToolOption("-bootclasspath", STANDARD, true) {
 264                 @Override
 265                 public void process(String arg) throws InvalidValueException {
 266                     processCompilerOption(Option.BOOT_CLASS_PATH, primaryName, arg);
 267                 }
 268             },
 269 
 270             new ToolOption("--class-path -classpath -cp", STANDARD, true) {
 271                 @Override
 272                 public void process(String arg) throws InvalidValueException {
 273                     processCompilerOption(Option.CLASS_PATH, primaryName, arg);
 274                 }
 275             },
 276 
 277             new ToolOption("-extdirs", STANDARD, true) {
 278                 @Override
 279                 public void process(String arg) throws InvalidValueException {
 280                     processCompilerOption(Option.EXTDIRS, primaryName, arg);
 281                 }
 282             },
 283 
 284             new ToolOption("--source-path -sourcepath", STANDARD, true) {
 285                 @Override
 286                 public void process(String arg) throws InvalidValueException {
 287                     processCompilerOption(Option.SOURCE_PATH, primaryName, arg);
 288                 }
 289             },
 290 
 291             new ToolOption("--module-source-path", STANDARD, true) {
 292                 @Override
 293                 public void process(String arg) throws InvalidValueException {
 294                     processCompilerOption(Option.MODULE_SOURCE_PATH, primaryName, arg);
 295                 }
 296             },
 297 
 298             new ToolOption("--upgrade-module-path", STANDARD, true) {
 299                 @Override
 300                 public void process(String arg) throws InvalidValueException {
 301                     processCompilerOption(Option.UPGRADE_MODULE_PATH, primaryName, arg);
 302                 }
 303             },
 304 
 305             new ToolOption("--system", STANDARD, true) {
 306                 @Override
 307                 public void process(String arg) throws InvalidValueException {
 308                     processCompilerOption(Option.SYSTEM, primaryName, arg);
 309                 }
 310             },
 311 
 312             new ToolOption("--module-path -p", STANDARD, true) {
 313                 @Override
 314                 public void process(String arg) throws InvalidValueException {
 315                     processCompilerOption(Option.MODULE_PATH, primaryName, arg);
 316                 }
 317             },
 318 
 319             new ToolOption("--add-modules", STANDARD, true) {
 320                 @Override
 321                 public void process(String arg) throws InvalidValueException {
 322                     processCompilerOption(Option.ADD_MODULES, primaryName, arg);
 323                 }
 324             },
 325 
 326             new ToolOption("--limit-modules", STANDARD, true) {
 327                 @Override
 328                 public void process(String arg) throws InvalidValueException {
 329                     processCompilerOption(Option.LIMIT_MODULES, primaryName, arg);
 330                 }
 331             },
 332 
 333             new ToolOption("--module", STANDARD, true) {
 334                 @Override
 335                 public void process(String arg) {
 336                     modules.addAll(List.of(arg.split(",")));
 337                 }
 338             },
 339 
 340             new ToolOption("-encoding", STANDARD, true) {
 341                 @Override
 342                 public void process(String arg) throws InvalidValueException {
 343                     processCompilerOption(Option.ENCODING, primaryName, arg);
 344                 }
 345             },
 346 
 347             new ToolOption("--release", STANDARD, true) {
 348                 @Override
 349                 public void process(String arg) throws InvalidValueException {
 350                     processCompilerOption(Option.RELEASE, primaryName, arg);
 351                 }
 352             },
 353 
 354             new ToolOption("--source -source", STANDARD, true) {
 355                 @Override
 356                 public void process(String arg) throws InvalidValueException {
 357                     processCompilerOption(Option.SOURCE, primaryName, arg);
 358                     processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg);
 359                 }
 360             },
 361 
 362             new ToolOption("-Xmaxerrs", EXTENDED, true) {
 363                 @Override
 364                 public void process(String arg) throws InvalidValueException {
 365                     processCompilerOption(Option.XMAXERRS, primaryName, arg);
 366                 }
 367             },
 368 
 369             new ToolOption("-Xmaxwarns", EXTENDED, true) {
 370                 @Override
 371                 public void process(String arg) throws InvalidValueException {
 372                     processCompilerOption(Option.XMAXWARNS, primaryName, arg);
 373                 }
 374             },
 375 
 376             new ToolOption("--add-reads", EXTENDED, true) {
 377                 @Override
 378                 public void process(String arg) throws InvalidValueException {
 379                     processCompilerOption(Option.ADD_READS, primaryName, arg);
 380                 }
 381             },
 382 
 383             new ToolOption("--add-exports", EXTENDED, true) {
 384                 @Override
 385                 public void process(String arg) throws InvalidValueException {
 386                     processCompilerOption(Option.ADD_EXPORTS, primaryName, arg);
 387                 }
 388             },
 389 
 390             new ToolOption("--patch-module", EXTENDED, true) {
 391                 @Override
 392                 public void process(String arg) throws InvalidValueException {
 393                     processCompilerOption(Option.PATCH_MODULE, primaryName, arg);
 394                 }
 395             },
 396 
 397             new ToolOption("--add-opens", HIDDEN, true) {
 398                 @Override
 399                 public void process(String arg) throws InvalidValueException {
 400                     processCompilerOption(Option.ADD_OPENS, primaryName, arg);
 401                 }
 402             },
 403 
 404             new ToolOption("--enable-preview", STANDARD) {
 405                 @Override
 406                 public void process() throws InvalidValueException {
 407                     processCompilerOption(Option.PREVIEW, primaryName);
 408                 }
 409             },
 410 
 411             // ----- doclet options -----
 412 
 413             new ToolOption(DOCLET, STANDARD, true), // handled in setDocletInvoker
 414 
 415             new ToolOption(DOCLET_PATH, STANDARD, true), // handled in setDocletInvoker
 416 
 417             // ----- selection options -----
 418 
 419             new ToolOption("-subpackages", STANDARD, true) {
 420                 @Override
 421                 public void process(String arg) {
 422                     subpackages.addAll(List.of(arg.split(":")));
 423                 }
 424             },
 425 
 426             new ToolOption("-exclude", STANDARD, true) {
 427                 @Override
 428                 public void process(String arg) {
 429                     excludes.addAll(List.of(arg.split(":")));
 430                 }
 431             },
 432 
 433             // ----- filtering options -----
 434 
 435             new ToolOption("-package", STANDARD) {
 436                 @Override
 437                 public void process() throws OptionException {
 438                     setSimpleFilter("package");
 439                 }
 440             },
 441 
 442             new ToolOption("-private", STANDARD) {
 443                 @Override
 444                 public void process() throws OptionException {
 445                     setSimpleFilter("private");
 446                 }
 447             },
 448 
 449             new ToolOption("-protected", STANDARD) {
 450                 @Override
 451                 public void process() throws OptionException {
 452                     setSimpleFilter("protected");
 453                 }
 454             },
 455 
 456             new ToolOption("-public", STANDARD) {
 457                 @Override
 458                 public void process() throws OptionException {
 459                     setSimpleFilter("public");
 460                 }
 461             },
 462 
 463             new ToolOption("--show-members", STANDARD, true) {
 464                 @Override
 465                 public void process(String arg) throws OptionException {
 466                     setShowMembersAccess(arg);
 467                 }
 468             },
 469 
 470             new ToolOption("--show-types", STANDARD, true) {
 471                 @Override
 472                 public void process(String arg) throws OptionException {
 473                     setShowTypesAccess(arg);
 474                 }
 475             },
 476 
 477             new ToolOption("--show-packages", STANDARD, true) {
 478                 @Override
 479                 public void process(String arg) throws OptionException {
 480                     setShowPackageAccess(arg);
 481                 }
 482             },
 483 
 484             new ToolOption("--show-module-contents", STANDARD, true) {
 485                 @Override
 486                 public void process(String arg) throws OptionException {
 487                     setShowModuleContents(arg);
 488                 }
 489             },
 490 
 491             new ToolOption("--expand-requires", STANDARD, true) {
 492                 @Override
 493                 public void process(String arg) throws OptionException {
 494                     setExpandRequires(arg);
 495                 }
 496             },
 497 
 498             // ----- output control options -----
 499 
 500             new ToolOption("-quiet", STANDARD) {
 501                 @Override
 502                 public void process() {
 503                     quiet = true;
 504                 }
 505             },
 506 
 507             new ToolOption("-verbose", STANDARD) {
 508                 @Override
 509                 public void process() {
 510                     setVerbose();
 511                 }
 512             },
 513 
 514             new ToolOption("-Xwerror", HIDDEN) {
 515                 @Override
 516                 public void process() {
 517                     rejectWarnings = true;
 518                 }
 519             },
 520 
 521             // ----- other options -----
 522 
 523             new ToolOption("-breakiterator", STANDARD) {
 524                 @Override
 525                 public void process() {
 526                     breakIterator = true;
 527                 }
 528             },
 529 
 530             new ToolOption(LOCALE, STANDARD, true) {
 531                 @Override
 532                 public void process(String arg) {
 533                     docLocale = arg;
 534                 }
 535             },
 536 
 537             new ToolOption("-Xclasses", HIDDEN) {
 538                 @Override
 539                 public void process() {
 540                     xclasses = true;
 541                 }
 542             },
 543 
 544             new ToolOption(DUMP_ON_ERROR, HIDDEN) {
 545                 @Override
 546                 public void process() {
 547                     dumpOnError = true;
 548                 }
 549             },
 550 
 551             new ToolOption("--ignore-source-errors", HIDDEN) {
 552                 @Override
 553                 public void process() {
 554                     ignoreSourceErrors = true;
 555                 }
 556             },
 557 
 558             // ----- help options -----
 559 
 560             new ToolOption("--help -help -? -h", STANDARD) {
 561                 @Override
 562                 public void process() throws OptionException {
 563                     throw new OptionException(OK, showHelper::usage);
 564                 }
 565             },
 566 
 567             new ToolOption("--help-extra -X", STANDARD) {
 568                 @Override
 569                 public void process() throws OptionException {
 570                     throw new OptionException(OK, showHelper::Xusage);
 571                 }
 572             },
 573 
 574             // This option exists only for the purpose of documenting itself.
 575             // It's actually implemented by the launcher.
 576             new ToolOption(J, STANDARD, true) {
 577                 @Override
 578                 public void process() {
 579                     throw new AssertionError("the -J flag should be caught by the launcher.");
 580                 }
 581             },
 582 
 583             new ToolOption("--version", STANDARD) {
 584                 @Override
 585                 public void process() throws OptionException {
 586                     throw new OptionException(OK, showHelper::version);
 587                 }
 588             },
 589 
 590             new ToolOption("--full-version", HIDDEN) {
 591                 @Override
 592                 public void process() throws OptionException {
 593                     throw new OptionException(OK, showHelper::fullVersion);
 594                 }
 595             });
 596 
 597     /**
 598      * Base class for all supported tool options.
 599      */
 600     static class ToolOption {
 601 
 602         final String primaryName;
 603         final List<String> names;
 604         final OptionKind kind;
 605         final boolean hasArg;
 606         final boolean hasSuffix; // ex: foo:bar or -foo=bar
 607 
 608         ToolOption(String opt, OptionKind kind) {
 609             this(opt, kind, false);
 610         }
 611 
 612         ToolOption(String names, OptionKind kind, boolean hasArg) {
 613             this.names = Arrays.asList(names.split("\\s+"));
 614             this.primaryName = this.names.get(0);
 615             this.kind = kind;
 616             this.hasArg = hasArg;
 617             char lastChar = names.charAt(names.length() - 1);
 618             this.hasSuffix = lastChar == ':' || lastChar == '=';
 619         }
 620 
 621         void process(String arg) throws OptionException, Option.InvalidValueException { }
 622 
 623         void process() throws OptionException, Option.InvalidValueException { }
 624 
 625         List<String> getNames() {
 626             return names;
 627         }
 628 
 629         String getParameters(Messager messager) {
 630             return (hasArg || primaryName.endsWith(":"))
 631                     ? messager.getText(getKey(primaryName, ".arg"))
 632                     : null;
 633         }
 634 
 635         String getDescription(Messager messager) {
 636             return messager.getText(getKey(primaryName, ".desc"));
 637         }
 638 
 639         private String getKey(String optionName, String suffix) {
 640             return "main.opt."
 641                     + optionName
 642                         .replaceAll("^-*", "")              // remove leading '-'
 643                         .replaceAll("[^A-Za-z0-9]+$", "")   // remove trailing non-alphanumeric
 644                         .replaceAll("[^A-Za-z0-9]", ".")    // replace internal non-alphanumeric
 645                     + suffix;
 646         }
 647     }
 648 
 649     interface ShowHelper {
 650         /**
 651          * Show command-line help for the standard options, as requested by
 652          * the {@code --help} option and its aliases.
 653          */
 654         void usage();
 655 
 656         /**
 657          * Show command-line help for the extended options, as requested by
 658          * the {@code --help-extended} option and its aliases.
 659          */
 660         void Xusage();
 661 
 662         /**
 663          * Show the basic version information, as requested by the {@code --version} option.
 664          */
 665         void version();
 666 
 667         /**
 668          * Show the full version information, as requested by the {@code --full-version} option.
 669          */
 670         void fullVersion();
 671     }
 672 
 673     //<editor-fold desc="accessor methods">
 674     /**
 675      * Argument for command-line option {@code -breakiterator}.
 676      */
 677     boolean breakIterator() {
 678         return breakIterator;
 679     }
 680 
 681     /**
 682      * Argument for command-line option {@code -locale}.
 683      */
 684     String locale() {
 685         return docLocale;
 686     }
 687 
 688     /**
 689      * Argument for command-line option {@code --dump-on-error}.
 690      * Dump stack traces for debugging etc.
 691      * Similar to javac {@code -doe}.
 692      */
 693     boolean dumpOnError() {
 694         return dumpOnError;
 695     }
 696 
 697     void setDumpOnError(boolean v) {
 698         dumpOnError = true;
 699     }
 700 
 701     /**
 702      * Argument for command-line option {@code -exclude}.
 703      */
 704     List<String> excludes() {
 705         return excludes;
 706     }
 707 
 708     /**
 709      * Argument for command-line option {@code --expand-requires}.
 710      */
 711     AccessKind expandRequires() {
 712         return expandRequires;
 713     }
 714 
 715     /**
 716      * Argument for command-line option {@code --ignore-source-errors}.
 717      */
 718     boolean ignoreSourceErrors() {
 719         return ignoreSourceErrors;
 720     }
 721 
 722     /**
 723      * Argument for command-line option {@code --module}.
 724      */
 725     List<String> modules() {
 726         return modules;
 727     }
 728 
 729     /**
 730      * Argument for command-line option {@code -Xwerror}.
 731      * Set by -Xwerror.
 732      */
 733     boolean rejectWarnings() {
 734         return rejectWarnings;
 735     }
 736 
 737     /**
 738      * Argument for command-line option {@code --show-members}.
 739      */
 740     AccessKind showMembersAccess() {
 741         return showMembersAccess;
 742     }
 743 
 744     /**
 745      * Argument for command-line option {@code --show-types}.
 746      */
 747     AccessKind showTypesAccess() {
 748         return showTypesAccess;
 749     }
 750 
 751     /**
 752      * Argument for command-line option {@code --show-packages}.
 753      */
 754     AccessKind showPackagesAccess() {
 755         return showPackagesAccess;
 756     }
 757 
 758     /**
 759      * Argument for command-line option {@code --show-module-contents}.
 760      */
 761     AccessKind showModuleContents() {
 762         return showModuleContents;
 763     }
 764 
 765     /**
 766      * Argument for command-line option {@code -quiet}.
 767      */
 768     boolean quiet() {
 769         return quiet;
 770     }
 771 
 772     /**
 773      * Argument for command-line option {@code -subpackages}.
 774      */
 775     List<String> subpackages() {
 776         return subpackages;
 777     }
 778 
 779     /**
 780      * Argument for command-line option {@code -verbose}.
 781      */
 782     boolean verbose() {
 783         return verbose;
 784     }
 785 
 786     /**
 787      * Argument for command-line option {@code -xclasses}.
 788      * If true, names on the command line that would normally be
 789      * treated as package names are treated as class names instead.
 790      */
 791     boolean xclasses() {
 792         return xclasses;
 793     }
 794 
 795     /**
 796      * Returns the set of options to be used for the instance of the
 797      * underlying compiler front-end.
 798      *
 799      * @return the options
 800      */
 801     Options compilerOptions() {
 802         return compOpts;
 803     }
 804 
 805     /**
 806      * Returns the set of options to be used for the file manager.
 807      *
 808      * @return the options
 809      */
 810     Map<Option, String> fileManagerOptions() {
 811         return fileManagerOpts;
 812     }
 813     //</editor-fold>
 814 
 815     /**
 816      * Returns an {@code IllegalOptionValue} exception.
 817      *
 818      * @param arg the arghument to include in the detail message
 819      * @return the exception
 820      */
 821     private IllegalOptionValue illegalOptionValue(String arg) {
 822         return new IllegalOptionValue(showHelper::usage, messager.getText("main.illegal_option_value", arg));
 823     }
 824 
 825     /**
 826      * Process a compiler option.
 827      *
 828      * @param option the option object to process the command-line option
 829      * @param opt    the command-line option
 830      * @throws Option.InvalidValueException if the command-line option is invalid
 831      */
 832     void processCompilerOption(Option option, String opt) throws Option.InvalidValueException {
 833         option.process(compilerOptionHelper, opt);
 834     }
 835 
 836     /**
 837      * Process a compiler option.
 838      *
 839      * @param option the option object to process the command-line option
 840      * @param opt    the command-line option
 841      * @param arg    the argument for the command-line option
 842      * @throws Option.InvalidValueException if the command-line option is invalid
 843      */
 844     private void processCompilerOption(Option option, String opt, String arg) throws Option.InvalidValueException {
 845         option.process(compilerOptionHelper, opt, arg);
 846     }
 847 
 848     /**
 849      * Returns a "helper" to be used when processing compiler options.
 850      * @return the helper
 851      */
 852     private OptionHelper getOptionHelper() {
 853         return new OptionHelper.GrumpyHelper(messager) {
 854             @Override
 855             public String get(com.sun.tools.javac.main.Option option) {
 856                 return compOpts.get(option);
 857             }
 858 
 859             @Override
 860             public void put(String name, String value) {
 861                 compOpts.put(name, value);
 862             }
 863 
 864             @Override
 865             public void remove(String name) {
 866                 compOpts.remove(name);
 867             }
 868 
 869             @Override
 870             public boolean handleFileManagerOption(com.sun.tools.javac.main.Option option, String value) {
 871                 fileManagerOpts.put(option, value);
 872                 return true;
 873             }
 874         };
 875     }
 876 
 877     private void setExpandRequires(String arg) throws OptionException {
 878         switch (arg) {
 879             case "transitive":
 880                 expandRequires = AccessKind.PUBLIC;
 881                 break;
 882             case "all":
 883                 expandRequires = AccessKind.PRIVATE;
 884                 break;
 885             default:
 886                 throw illegalOptionValue(arg);
 887         }
 888     }
 889 
 890     private void setShowModuleContents(String arg) throws OptionException {
 891         switch (arg) {
 892             case "api":
 893                 showModuleContents = AccessKind.PUBLIC;
 894                 break;
 895             case "all":
 896                 showModuleContents = AccessKind.PRIVATE;
 897                 break;
 898             default:
 899                 throw illegalOptionValue(arg);
 900         }
 901     }
 902 
 903     private void setShowPackageAccess(String arg) throws OptionException {
 904         switch (arg) {
 905             case "exported":
 906                 showPackagesAccess = AccessKind.PUBLIC;
 907                 break;
 908             case "all":
 909                 showPackagesAccess = AccessKind.PRIVATE;
 910                 break;
 911             default:
 912                 throw illegalOptionValue(arg);
 913         }
 914     }
 915 
 916     private void setShowTypesAccess(String arg) throws OptionException {
 917         showTypesAccess = getAccessValue(arg);
 918     }
 919 
 920     private void setShowMembersAccess(String arg) throws OptionException {
 921         showMembersAccess = getAccessValue(arg);
 922     }
 923 
 924     private void setSimpleFilter(String arg) throws OptionException {
 925         setSimpleAccessOption(arg);
 926     }
 927 
 928     private void setVerbose() {
 929         compOpts.put("-verbose", "");
 930         verbose = true;
 931     }
 932 
 933     private void setSimpleAccessOption(String arg) throws OptionException {
 934         setAccess(getAccessValue(arg));
 935     }
 936 
 937     /*
 938      * This method handles both the simple options -package,
 939      * -private, so on, in addition to the new ones such as
 940      * --show-types:public and so on.
 941      */
 942     private AccessKind getAccessValue(String arg) throws OptionException {
 943         int colon = arg.indexOf(':');
 944         String value = (colon > 0)
 945                 ? arg.substring(colon + 1)
 946                 : arg;
 947         switch (value) {
 948             case "public":
 949                 return AccessKind.PUBLIC;
 950             case "protected":
 951                 return AccessKind.PROTECTED;
 952             case "package":
 953                 return AccessKind.PACKAGE;
 954             case "private":
 955                 return AccessKind.PRIVATE;
 956             default:
 957                 throw illegalOptionValue(value);
 958         }
 959     }
 960 
 961     /*
 962      * Sets all access members to PROTECTED; this is the default.
 963      */
 964     private void setAccessDefault() {
 965         setAccess(AccessKind.PROTECTED);
 966     }
 967 
 968     /*
 969      * This sets access to all the allowed kinds in the
 970      * access members.
 971      */
 972     private void setAccess(AccessKind accessValue) {
 973         for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
 974             switch (kind) {
 975                 case METHOD:
 976                     showMembersAccess = accessValue;
 977                     break;
 978                 case CLASS:
 979                     showTypesAccess = accessValue;
 980                     break;
 981                 case PACKAGE:
 982                     showPackagesAccess = accessValue;
 983                     break;
 984                 case MODULE:
 985                     showModuleContents = accessValue;
 986                     break;
 987                 default:
 988                     throw new AssertionError("unknown element kind:" + kind);
 989             }
 990         }
 991     }
 992 }