Path: blob/master/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java
41161 views
/*1* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package jdk.javadoc.internal.tool;2627import java.util.ArrayList;28import java.util.Arrays;29import java.util.LinkedHashMap;30import java.util.List;31import java.util.Map;32import javax.lang.model.element.ElementKind;3334import com.sun.tools.javac.main.Option;35import com.sun.tools.javac.main.Option.InvalidValueException;36import com.sun.tools.javac.main.OptionHelper;37import com.sun.tools.javac.util.Context;38import com.sun.tools.javac.util.Options;3940import static jdk.javadoc.internal.tool.Main.Result.OK;41import static jdk.javadoc.internal.tool.ToolOptions.ToolOption.Kind.*;4243/**44* Storage and support for javadoc tool options, as distinct from45* the options supported by any doclet that may be in use.46* The tool options includes those options which are delegated47* to javac and/or the file manager, such as options to set48* the source level, and path options to locate the files to be49* documented.50*51* <p>Some of the methods used to access the values of options52* have names that begin with a verb, such as {@link #expandRequires}53* or {@link #ignoreSourceErrors}. Unless otherwise stated,54* these methods should all be taken as just accessing the value55* of the associated option.56*57* <p><b>This is NOT part of any supported API.58* If you write code that depends on this, you do so at your own risk.59* This code and its internal interfaces are subject to change or60* deletion without notice.</b>61*/62public class ToolOptions {63// The following are the names of options handled in the first pass of option decoding,64// in Start.preprocess.65static final String DOCLET = "-doclet";66static final String DOCLET_PATH = "-docletpath";67static final String DUMP_ON_ERROR = "--dump-on-error";68static final String AT = "@";69static final String J = "-J";70static final String LOCALE = "-locale";7172/**73* Argument for command-line option {@code -breakiterator}.74*/75private boolean breakIterator = false;7677/**78* Argument for command-line option {@code --dump-on-error}.79* Dump stack traces for debugging etc.80* Similar to javac {@code -doe}.81*/82private boolean dumpOnError = false;8384/**85* Argument for command-line option {@code -exclude}.86*/87private List<String> excludes = new ArrayList<>();8889/**90* Argument for command-line option {@code --expand-requires}.91*/92private AccessKind expandRequires;9394/**95* Argument for command-line option {@code --ignore-source-errors}.96*/97private boolean ignoreSourceErrors;9899/**100* Argument for command-line option {@code --module}.101*/102private List<String> modules = new ArrayList<>();103104/**105* Argument for command-line option {@code -Werror}.106* Set by -Werror.107*/108private boolean rejectWarnings = false;109110/**111* Argument for command-line option {@code --show-members}.112*/113private AccessKind showMembersAccess;114115/**116* Argument for command-line option {@code --show-types}.117*/118private AccessKind showTypesAccess;119120/**121* Argument for command-line option {@code --show-packages}.122*/123private AccessKind showPackagesAccess;124125/**126* Argument for command-line option {@code --show-module-contents}.127*/128private AccessKind showModuleContents;129130/**131* Argument for command-line option {@code -quiet}.132*/133private boolean quiet;134135/**136* Argument for command-line option {@code -subpackages}.137*/138private List<String> subpackages = new ArrayList<>();139140/**141* Argument for command-line option {@code -verbose}.142*/143private boolean verbose;144145/**146* Argument for command-line option {@code -xclasses}.147* If true, names on the command line that would normally be148* treated as package names are treated as class names instead.149*/150private boolean xclasses = false;151152/**153* Options to be given to the file manager, such as path options154* indicating where to find files to be documented.155*/156private final Map<Option, String> fileManagerOpts;157158/**159* Options to be given to the underlying compiler front-end,160* such as options to indicate the source level to be used.161*/162private final Options compOpts;163164/**165* The "helper" to be used when processing compiler options.166*/167private final OptionHelper compilerOptionHelper;168169/**170* The messager to be used to report diagnostics..171*/172private final Messager messager;173174/**175* The helper for help and version options176*/177private final ShowHelper showHelper;178179/**180* Creates an object to handle tool options.181*182* @param context the context used to find other tool-related components183* @param messager the messager to be used to report diagnostics184*/185ToolOptions(Context context, Messager messager, ShowHelper showHelper) {186this.messager = messager;187this.showHelper = showHelper;188compOpts = Options.instance(context);189fileManagerOpts = new LinkedHashMap<>();190compilerOptionHelper = getOptionHelper();191setAccessDefault();192}193194/**195* Creates a minimal object, just sufficient to check the names of the196* supported options.197*/198private ToolOptions() {199compOpts = null;200compilerOptionHelper = null;201fileManagerOpts = null;202messager = null;203showHelper = null;204}205206/**207* Returns the set of options supported by the tool, excluding any options208* that are managed by the doclet that may be in use.209*210* @return the set of options211*/212public List<ToolOption> getSupportedOptions() {213return supportedOptions;214}215216/**217* Determines if the given option is supported and if so, the218* number of arguments the option takes.219*220* @param option an option221* @return the number of arguments the given option takes or -1 if222* the option is not supported223* @see javax.tools.DocumentationTool#isSupportedOption(String)224*/225public static int isSupportedOption(String option) {226ToolOptions t = new ToolOptions();227for (ToolOption o : t.supportedOptions) {228for (String name : o.names) {229if (name.equals(option))230return o.hasArg ? 1 : 0;231}232}233return -1;234}235236/**237* Returns the option to be used to process an argument such as may be found on238* the command line.239*240* @param arg the argument241* @return the option242*/243ToolOption getOption(String arg) {244String name = arg;245if (arg.startsWith("--") && arg.contains("=")) {246name = arg.substring(0, arg.indexOf('='));247}248for (ToolOption o : supportedOptions) {249for (String n : o.names) {250if (name.equals(n)) {251return o;252}253}254}255return null;256}257258private List<ToolOption> supportedOptions = List.of(259// ----- options for underlying compiler -----260261new ToolOption("-bootclasspath", STANDARD, true) {262@Override263public void process(String arg) throws InvalidValueException {264processCompilerOption(Option.BOOT_CLASS_PATH, primaryName, arg);265}266},267268new ToolOption("--class-path -classpath -cp", STANDARD, true) {269@Override270public void process(String arg) throws InvalidValueException {271processCompilerOption(Option.CLASS_PATH, primaryName, arg);272}273},274275new ToolOption("-extdirs", STANDARD, true) {276@Override277public void process(String arg) throws InvalidValueException {278processCompilerOption(Option.EXTDIRS, primaryName, arg);279}280},281282new ToolOption("--source-path -sourcepath", STANDARD, true) {283@Override284public void process(String arg) throws InvalidValueException {285processCompilerOption(Option.SOURCE_PATH, primaryName, arg);286}287},288289new ToolOption("--module-source-path", STANDARD, true) {290@Override291public void process(String arg) throws InvalidValueException {292processCompilerOption(Option.MODULE_SOURCE_PATH, primaryName, arg);293}294},295296new ToolOption("--upgrade-module-path", STANDARD, true) {297@Override298public void process(String arg) throws InvalidValueException {299processCompilerOption(Option.UPGRADE_MODULE_PATH, primaryName, arg);300}301},302303new ToolOption("--system", STANDARD, true) {304@Override305public void process(String arg) throws InvalidValueException {306processCompilerOption(Option.SYSTEM, primaryName, arg);307}308},309310new ToolOption("--module-path -p", STANDARD, true) {311@Override312public void process(String arg) throws InvalidValueException {313processCompilerOption(Option.MODULE_PATH, primaryName, arg);314}315},316317new ToolOption("--add-modules", STANDARD, true) {318@Override319public void process(String arg) throws InvalidValueException {320processCompilerOption(Option.ADD_MODULES, primaryName, arg);321}322},323324new ToolOption("--limit-modules", STANDARD, true) {325@Override326public void process(String arg) throws InvalidValueException {327processCompilerOption(Option.LIMIT_MODULES, primaryName, arg);328}329},330331new ToolOption("--module", STANDARD, true) {332@Override333public void process(String arg) {334modules.addAll(List.of(arg.split(",")));335}336},337338new ToolOption("-encoding", STANDARD, true) {339@Override340public void process(String arg) throws InvalidValueException {341processCompilerOption(Option.ENCODING, primaryName, arg);342}343},344345new ToolOption("--release", STANDARD, true) {346@Override347public void process(String arg) throws InvalidValueException {348processCompilerOption(Option.RELEASE, primaryName, arg);349}350},351352new ToolOption("--source -source", STANDARD, true) {353@Override354public void process(String arg) throws InvalidValueException {355processCompilerOption(Option.SOURCE, primaryName, arg);356processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg);357}358},359360new ToolOption("-Xmaxerrs", EXTENDED, true) {361@Override362public void process(String arg) throws InvalidValueException {363processCompilerOption(Option.XMAXERRS, primaryName, arg);364}365},366367new ToolOption("-Xmaxwarns", EXTENDED, true) {368@Override369public void process(String arg) throws InvalidValueException {370processCompilerOption(Option.XMAXWARNS, primaryName, arg);371}372},373374new ToolOption("--add-reads", EXTENDED, true) {375@Override376public void process(String arg) throws InvalidValueException {377processCompilerOption(Option.ADD_READS, primaryName, arg);378}379},380381new ToolOption("--add-exports", EXTENDED, true) {382@Override383public void process(String arg) throws InvalidValueException {384processCompilerOption(Option.ADD_EXPORTS, primaryName, arg);385}386},387388new ToolOption("--patch-module", EXTENDED, true) {389@Override390public void process(String arg) throws InvalidValueException {391processCompilerOption(Option.PATCH_MODULE, primaryName, arg);392}393},394395new ToolOption("--add-opens", HIDDEN, true) {396@Override397public void process(String arg) throws InvalidValueException {398processCompilerOption(Option.ADD_OPENS, primaryName, arg);399}400},401402new ToolOption("--enable-preview", STANDARD) {403@Override404public void process() throws InvalidValueException {405processCompilerOption(Option.PREVIEW, primaryName);406}407},408409// ----- doclet options -----410411// This option exists so that it is documented in the command-line help.412// It is implemented in {@link Start#preprocess}.413new ToolOption(DOCLET, STANDARD, true),414415// This option exists so that it is documented in the command-line help.416// It is implemented in {@link Start#preprocess}.417new ToolOption(DOCLET_PATH, STANDARD, true),418419// ----- selection options -----420421new ToolOption("-subpackages", STANDARD, true) {422@Override423public void process(String arg) {424subpackages.addAll(List.of(arg.split(":")));425}426},427428new ToolOption("-exclude", STANDARD, true) {429@Override430public void process(String arg) {431excludes.addAll(List.of(arg.split(":")));432}433},434435// ----- filtering options -----436437new ToolOption("-package", STANDARD) {438@Override439public void process() throws OptionException {440setSimpleFilter("package");441}442},443444new ToolOption("-private", STANDARD) {445@Override446public void process() throws OptionException {447setSimpleFilter("private");448}449},450451new ToolOption("-protected", STANDARD) {452@Override453public void process() throws OptionException {454setSimpleFilter("protected");455}456},457458new ToolOption("-public", STANDARD) {459@Override460public void process() throws OptionException {461setSimpleFilter("public");462}463},464465new ToolOption("--show-members", STANDARD, true) {466@Override467public void process(String arg) throws OptionException {468setShowMembersAccess(arg);469}470},471472new ToolOption("--show-types", STANDARD, true) {473@Override474public void process(String arg) throws OptionException {475setShowTypesAccess(arg);476}477},478479new ToolOption("--show-packages", STANDARD, true) {480@Override481public void process(String arg) throws OptionException {482setShowPackageAccess(arg);483}484},485486new ToolOption("--show-module-contents", STANDARD, true) {487@Override488public void process(String arg) throws OptionException {489setShowModuleContents(arg);490}491},492493new ToolOption("--expand-requires", STANDARD, true) {494@Override495public void process(String arg) throws OptionException {496setExpandRequires(arg);497}498},499500// ----- output control options -----501502new ToolOption("-quiet", STANDARD) {503@Override504public void process() {505quiet = true;506}507},508509new ToolOption("-verbose", STANDARD) {510@Override511public void process() {512setVerbose();513}514},515516// superseded by -Werror, retained for a while for compatibility,517// although note that it is an undocumented hidden option, and can518// be removed without warning519new ToolOption("-Xwerror", HIDDEN) {520@Override521public void process() {522rejectWarnings = true;523}524},525526new ToolOption("-Werror", STANDARD) {527@Override528public void process() {529rejectWarnings = true;530}531},532533// ----- other options -----534535new ToolOption("-breakiterator", STANDARD) {536@Override537public void process() {538breakIterator = true;539}540},541542// This option exists so that it is documented in the command-line help.543// It is implemented in {@link Start#preprocess}.544new ToolOption(LOCALE, STANDARD, true),545546new ToolOption("-Xclasses", HIDDEN) {547@Override548public void process() {549xclasses = true;550}551},552553// This option exists so that it is documented in the command-line help.554// It is implemented in {@link Start#preprocess}.555new ToolOption(DUMP_ON_ERROR, HIDDEN),556557new ToolOption("--ignore-source-errors", HIDDEN) {558@Override559public void process() {560ignoreSourceErrors = true;561}562},563564// ----- help options -----565566new ToolOption("--help -help -? -h", STANDARD) {567@Override568public void process() throws OptionException {569throw new OptionException(OK, showHelper::usage);570}571},572573new ToolOption("--help-extra -X", STANDARD) {574@Override575public void process() throws OptionException {576throw new OptionException(OK, showHelper::Xusage);577}578},579580// This option exists so that it is documented in the command-line help.581// It is actually implemented by the launcher, and can only be used when582// invoking javadoc from the launcher.583new ToolOption(J, STANDARD, true) {584@Override585public void process() {586throw new AssertionError("the -J flag should be caught by the launcher.");587}588},589590// This option exists so that it is documented in the command-line help.591// It is actually implemented by expanding argv early on during execution,592// and can only be used when using the command-line and related interfaces593// (i.e. not the javax.tools API).594new ToolOption(AT, STANDARD, true) {595@Override596public void process() {597throw new AssertionError("the @ option is handled separately");598}599},600601new ToolOption("--version", STANDARD) {602@Override603public void process() throws OptionException {604throw new OptionException(OK, showHelper::version);605}606},607608new ToolOption("--full-version", HIDDEN) {609@Override610public void process() throws OptionException {611throw new OptionException(OK, showHelper::fullVersion);612}613});614615/**616* Base class for all supported tool options.617*/618static class ToolOption {619enum Kind { STANDARD, EXTENDED, HIDDEN }620621final String primaryName;622final List<String> names;623final Kind kind;624final boolean hasArg;625final boolean hasSuffix; // ex: foo:bar or -foo=bar626627ToolOption(String opt, Kind kind) {628this(opt, kind, false);629}630631ToolOption(String names, Kind kind, boolean hasArg) {632this.names = Arrays.asList(names.split("\\s+"));633this.primaryName = this.names.get(0);634this.kind = kind;635this.hasArg = hasArg;636char lastChar = names.charAt(names.length() - 1);637this.hasSuffix = lastChar == ':' || lastChar == '=';638}639640void process(String arg) throws OptionException, Option.InvalidValueException { }641642void process() throws OptionException, Option.InvalidValueException { }643644List<String> getNames() {645return names;646}647648String getParameters(Messager messager) {649return (hasArg || primaryName.endsWith(":"))650? messager.getText(getKey(primaryName, ".arg"))651: null;652}653654String getDescription(Messager messager) {655return messager.getText(getKey(primaryName, ".desc"));656}657658private String getKey(String optionName, String suffix) {659return "main.opt."660+ optionName661.replaceAll("^-*", "") // remove leading '-'662.replaceAll("^@", "at") // handle '@'663.replaceAll("[^A-Za-z0-9]+$", "") // remove trailing non-alphanumeric664.replaceAll("[^A-Za-z0-9]", ".") // replace internal non-alphanumeric665+ suffix;666}667}668669interface ShowHelper {670/**671* Show command-line help for the standard options, as requested by672* the {@code --help} option and its aliases.673*/674void usage();675676/**677* Show command-line help for the extended options, as requested by678* the {@code --help-extended} option and its aliases.679*/680void Xusage();681682/**683* Show the basic version information, as requested by the {@code --version} option.684*/685void version();686687/**688* Show the full version information, as requested by the {@code --full-version} option.689*/690void fullVersion();691}692693//<editor-fold desc="accessor methods">694/**695* Argument for command-line option {@code -breakiterator}.696*/697boolean breakIterator() {698return breakIterator;699}700701/**702* Argument for command-line option {@code --dump-on-error}.703* Dump stack traces for debugging etc.704* Similar to javac {@code -doe}.705*/706boolean dumpOnError() {707return dumpOnError;708}709710void setDumpOnError(boolean v) {711dumpOnError = v;712}713714/**715* Argument for command-line option {@code -exclude}.716*/717List<String> excludes() {718return excludes;719}720721/**722* Argument for command-line option {@code --expand-requires}.723*/724AccessKind expandRequires() {725return expandRequires;726}727728/**729* Argument for command-line option {@code --ignore-source-errors}.730*/731boolean ignoreSourceErrors() {732return ignoreSourceErrors;733}734735/**736* Argument for command-line option {@code --module}.737*/738List<String> modules() {739return modules;740}741742/**743* Argument for command-line option {@code -Werror}.744* Set by -Werror.745*/746boolean rejectWarnings() {747return rejectWarnings;748}749750/**751* Argument for command-line option {@code --show-members}.752*/753AccessKind showMembersAccess() {754return showMembersAccess;755}756757/**758* Argument for command-line option {@code --show-types}.759*/760AccessKind showTypesAccess() {761return showTypesAccess;762}763764/**765* Argument for command-line option {@code --show-packages}.766*/767AccessKind showPackagesAccess() {768return showPackagesAccess;769}770771/**772* Argument for command-line option {@code --show-module-contents}.773*/774AccessKind showModuleContents() {775return showModuleContents;776}777778/**779* Argument for command-line option {@code -quiet}.780*/781boolean quiet() {782return quiet;783}784785/**786* Argument for command-line option {@code -subpackages}.787*/788List<String> subpackages() {789return subpackages;790}791792/**793* Argument for command-line option {@code -verbose}.794*/795boolean verbose() {796return verbose;797}798799/**800* Argument for command-line option {@code -xclasses}.801* If true, names on the command line that would normally be802* treated as package names are treated as class names instead.803*/804boolean xclasses() {805return xclasses;806}807808/**809* Returns the set of options to be used for the instance of the810* underlying compiler front-end.811*812* @return the options813*/814Options compilerOptions() {815return compOpts;816}817818/**819* Returns the set of options to be used for the file manager.820*821* @return the options822*/823Map<Option, String> fileManagerOptions() {824return fileManagerOpts;825}826//</editor-fold>827828/**829* Returns an {@code IllegalOptionValue} exception.830*831* @param arg the argument to include in the detail message832* @return the exception833*/834private IllegalOptionValue illegalOptionValue(String arg) {835return new IllegalOptionValue(showHelper::usage, messager.getText("main.illegal_option_value", arg));836}837838/**839* Process a compiler option.840*841* @param option the option object to process the command-line option842* @param opt the command-line option843* @throws Option.InvalidValueException if the command-line option is invalid844*/845void processCompilerOption(Option option, String opt) throws Option.InvalidValueException {846option.process(compilerOptionHelper, opt);847}848849/**850* Process a compiler option.851*852* @param option the option object to process the command-line option853* @param opt the command-line option854* @param arg the argument for the command-line option855* @throws Option.InvalidValueException if the command-line option is invalid856*/857private void processCompilerOption(Option option, String opt, String arg) throws Option.InvalidValueException {858option.process(compilerOptionHelper, opt, arg);859}860861/**862* Returns a "helper" to be used when processing compiler options.863* @return the helper864*/865private OptionHelper getOptionHelper() {866return new OptionHelper.GrumpyHelper(messager) {867@Override868public String get(com.sun.tools.javac.main.Option option) {869return compOpts.get(option);870}871872@Override873public void put(String name, String value) {874compOpts.put(name, value);875}876877@Override878public void remove(String name) {879compOpts.remove(name);880}881882@Override883public boolean handleFileManagerOption(com.sun.tools.javac.main.Option option, String value) {884fileManagerOpts.put(option, value);885return true;886}887};888}889890private void setExpandRequires(String arg) throws OptionException {891switch (arg) {892case "transitive":893expandRequires = AccessKind.PUBLIC;894break;895case "all":896expandRequires = AccessKind.PRIVATE;897break;898default:899throw illegalOptionValue(arg);900}901}902903private void setShowModuleContents(String arg) throws OptionException {904switch (arg) {905case "api":906showModuleContents = AccessKind.PUBLIC;907break;908case "all":909showModuleContents = AccessKind.PRIVATE;910break;911default:912throw illegalOptionValue(arg);913}914}915916private void setShowPackageAccess(String arg) throws OptionException {917switch (arg) {918case "exported":919showPackagesAccess = AccessKind.PUBLIC;920break;921case "all":922showPackagesAccess = AccessKind.PRIVATE;923break;924default:925throw illegalOptionValue(arg);926}927}928929private void setShowTypesAccess(String arg) throws OptionException {930showTypesAccess = getAccessValue(arg);931}932933private void setShowMembersAccess(String arg) throws OptionException {934showMembersAccess = getAccessValue(arg);935}936937private void setSimpleFilter(String arg) throws OptionException {938setSimpleAccessOption(arg);939}940941private void setVerbose() {942compOpts.put("-verbose", "");943verbose = true;944}945946private void setSimpleAccessOption(String arg) throws OptionException {947setAccess(getAccessValue(arg));948}949950/*951* This method handles both the simple options -package,952* -private, so on, in addition to the new ones such as953* --show-types:public and so on.954*/955private AccessKind getAccessValue(String arg) throws OptionException {956int colon = arg.indexOf(':');957String value = (colon > 0)958? arg.substring(colon + 1)959: arg;960switch (value) {961case "public":962return AccessKind.PUBLIC;963case "protected":964return AccessKind.PROTECTED;965case "package":966return AccessKind.PACKAGE;967case "private":968return AccessKind.PRIVATE;969default:970throw illegalOptionValue(value);971}972}973974/*975* Sets all access members to PROTECTED; this is the default.976*/977private void setAccessDefault() {978setAccess(AccessKind.PROTECTED);979}980981/*982* This sets access to all the allowed kinds in the983* access members.984*/985private void setAccess(AccessKind accessValue) {986for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {987switch (kind) {988case METHOD:989showMembersAccess = accessValue;990break;991case CLASS:992showTypesAccess = accessValue;993break;994case PACKAGE:995showPackagesAccess = accessValue;996break;997case MODULE:998showModuleContents = accessValue;999break;1000default:1001throw new AssertionError("unknown element kind:" + kind);1002}1003}1004}1005}100610071008