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