--- old/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java 2020-01-23 18:12:11.253338500 -0800 +++ /dev/null 2019-11-20 10:47:51.674104495 -0800 @@ -1,618 +0,0 @@ -/* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.javadoc.internal.tool; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import javax.lang.model.element.ElementKind; - -import com.sun.tools.javac.main.Option; -import com.sun.tools.javac.main.Option.InvalidValueException; -import com.sun.tools.javac.main.Option.OptionKind; -import com.sun.tools.javac.main.OptionHelper; -import com.sun.tools.javac.util.Options; - -import static com.sun.tools.javac.main.Option.OptionKind.*; -import static jdk.javadoc.internal.tool.Main.Result.*; - -/** - * javadoc tool options. - * - *

This is NOT part of any supported API. - * If you write code that depends on this, you do so at your own risk. - * This code and its internal interfaces are subject to change or - * deletion without notice. - */ -public enum ToolOption { - - // ----- options for underlying compiler ----- - - BOOTCLASSPATH("-bootclasspath", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.BOOT_CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - CLASS_PATH("--class-path -classpath -cp", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.CLASS_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - EXTDIRS("-extdirs", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.EXTDIRS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - SOURCE_PATH("--source-path -sourcepath", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - MODULE_SOURCE_PATH("--module-source-path", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.MODULE_SOURCE_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - UPGRADE_MODULE_PATH("--upgrade-module-path", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.UPGRADE_MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - SYSTEM("--system", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.SYSTEM.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - MODULE_PATH("--module-path -p", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.MODULE_PATH.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - ADD_MODULES("--add-modules", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.ADD_MODULES.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - LIMIT_MODULES("--limit-modules", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.LIMIT_MODULES.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - MODULE("--module", STANDARD, true) { - @Override - public void process(Helper helper, String arg) { - helper.addToList(this, ",", arg); - } - }, - - ENCODING("-encoding", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.ENCODING.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - RELEASE("--release", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.RELEASE.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - SOURCE("--source -source", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.SOURCE.process(helper.getOptionHelper(), primaryName, arg); - Option.TARGET.process(helper.getOptionHelper(), Option.TARGET.primaryName, arg); - } - }, - - XMAXERRS("-Xmaxerrs", EXTENDED, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.XMAXERRS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - XMAXWARNS("-Xmaxwarns", EXTENDED, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.XMAXWARNS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - ADD_READS("--add-reads", EXTENDED, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.ADD_READS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - ADD_EXPORTS("--add-exports", EXTENDED, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.ADD_EXPORTS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - PATCH_MODULE("--patch-module", EXTENDED, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.PATCH_MODULE.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - ADD_OPENS("--add-opens", HIDDEN, true) { - @Override - public void process(Helper helper, String arg) throws InvalidValueException { - Option.ADD_OPENS.process(helper.getOptionHelper(), primaryName, arg); - } - }, - - ENABLE_PREVIEW("--enable-preview", STANDARD) { - @Override - public void process(Helper helper) throws InvalidValueException { - Option.PREVIEW.process(helper.getOptionHelper(), primaryName); - } - }, - - // ----- doclet options ----- - - DOCLET("-doclet", STANDARD, true), // handled in setDocletInvoker - - DOCLETPATH("-docletpath", STANDARD, true), // handled in setDocletInvoker - - // ----- selection options ----- - - SUBPACKAGES("-subpackages", STANDARD, true) { - @Override - public void process(Helper helper, String arg) { - helper.addToList(this, ":", arg); - } - }, - - EXCLUDE("-exclude", STANDARD, true) { - @Override - public void process(Helper helper, String arg) { - helper.addToList(this, ":", arg); - } - }, - - // ----- filtering options ----- - - PACKAGE("-package", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - helper.setSimpleFilter("package"); - } - }, - - PRIVATE("-private", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - helper.setSimpleFilter("private"); - } - }, - - PROTECTED("-protected", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - helper.setSimpleFilter("protected"); - } - }, - - PUBLIC("-public", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - helper.setSimpleFilter("public"); - } - }, - - SHOW_MEMBERS("--show-members", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws OptionException { - helper.setFilter(this, arg); - } - }, - - SHOW_TYPES("--show-types", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws OptionException { - helper.setFilter(this, arg); - } - }, - - SHOW_PACKAGES("--show-packages", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws OptionException { - helper.setShowPackageAccess(SHOW_PACKAGES, arg); - } - }, - - SHOW_MODULE_CONTENTS("--show-module-contents", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws OptionException { - helper.setShowModuleContents(SHOW_MODULE_CONTENTS, arg); - } - }, - - EXPAND_REQUIRES("--expand-requires", STANDARD, true) { - @Override - public void process(Helper helper, String arg) throws OptionException { - helper.setExpandRequires(EXPAND_REQUIRES, arg); - } - }, - - // ----- output control options ----- - - QUIET("-quiet", STANDARD) { - @Override - public void process(Helper helper) { - helper.jdtoolOpts.put(QUIET, true); - } - }, - - VERBOSE("-verbose", STANDARD) { - @Override - public void process(Helper helper) { - helper.compOpts.put("-verbose", ""); - } - }, - - XWERROR("-Xwerror", HIDDEN) { - @Override - public void process(Helper helper) { - helper.rejectWarnings = true; - - } - }, - - // ----- other options ----- - - BREAKITERATOR("-breakiterator", STANDARD) { - @Override - public void process(Helper helper) { - helper.breakiterator = true; - } - }, - - LOCALE("-locale", STANDARD, true) { - @Override - public void process(Helper helper, String arg) { - helper.docLocale = arg; - } - }, - - XCLASSES("-Xclasses", HIDDEN) { - @Override - public void process(Helper helper) { - helper.jdtoolOpts.put(XCLASSES, true); - } - }, - - DUMPONERROR("--dump-on-error", HIDDEN) { - @Override - public void process(Helper helper) { - helper.dumpOnError = true; - } - }, - - IGNORE_SOURCE_ERRORS("--ignore-source-errors", HIDDEN) { - @Override - public void process(Helper helper) { - helper.jdtoolOpts.put(IGNORE_SOURCE_ERRORS, true); - } - }, - - // ----- help options ----- - - HELP("--help -help -? -h", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - throw new OptionException(OK, helper::usage); - } - }, - - HELP_EXTRA("--help-extra -X", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - throw new OptionException(OK, helper::Xusage); - } - }, - - // This option exists only for the purpose of documenting itself. - // It's actually implemented by the launcher. - J("-J", STANDARD, true) { - @Override - public void process(Helper helper) { - throw new AssertionError("the -J flag should be caught by the launcher."); - } - }, - - VERSION("--version", STANDARD) { - @Override - public void process(Helper helper) throws OptionException { - throw new OptionException(OK, helper::version); - } - }, - - FULLVERSION("--full-version", HIDDEN) { - @Override - public void process(Helper helper) throws OptionException { - throw new OptionException(OK, helper::fullVersion); - } - }; - - public final String primaryName; - public final List names; - public final OptionKind kind; - public final boolean hasArg; - public final boolean hasSuffix; // ex: foo:bar or -foo=bar - - ToolOption(String opt, OptionKind kind) { - this(opt, kind, false); - } - - ToolOption(String names, OptionKind kind, boolean hasArg) { - this.names = Arrays.asList(names.split("\\s+")); - this.primaryName = this.names.get(0); - this.kind = kind; - this.hasArg = hasArg; - char lastChar = names.charAt(names.length() - 1); - this.hasSuffix = lastChar == ':' || lastChar == '='; - } - - void process(Helper helper, String arg) throws OptionException, Option.InvalidValueException { } - - void process(Helper helper) throws OptionException, Option.InvalidValueException { } - - List getNames() { - return names; - } - - String getParameters(Messager messager) { - return (hasArg || primaryName.endsWith(":")) - ? messager.getText(getKey(primaryName, ".arg")) - : null; - } - - String getDescription(Messager messager) { - return messager.getText(getKey(primaryName, ".desc")); - } - - private String getKey(String optionName, String suffix) { - return "main.opt." - + optionName - .replaceAll("^-*", "") // remove leading '-' - .replaceAll("[^A-Za-z0-9]+$", "") // remove trailing non-alphanumeric - .replaceAll("[^A-Za-z0-9]", ".") // replace internal non-alphanumeric - + suffix; - } - - - static ToolOption get(String name) { - String oname = name; - if (name.startsWith("--") && name.contains("=")) { - oname = name.substring(0, name.indexOf('=')); - } - for (ToolOption o : values()) { - for (String n : o.names) { - if (oname.equals(n)) { - return o; - } - } - } - return null; - } - - abstract static class Helper { - - // File manager options - final Map fileManagerOpts = new LinkedHashMap<>(); - - /** javac options, set by various options. */ - Options compOpts; // = Options.instance(context) - - /** Javadoc tool options */ - final Map jdtoolOpts = new EnumMap<>(ToolOption.class); - - /** dump stack traces for debugging etc.*/ - boolean dumpOnError = false; - - /** Set by -breakiterator. */ - boolean breakiterator = false; - - /** Set by -Xwerror. */ - boolean rejectWarnings = false; - - /** Set by -prompt. */ - boolean promptOnError; - - /** Set by -locale. */ - String docLocale = ""; - - Helper() { - populateDefaultAccessMap(); - } - - abstract void usage(); - abstract void Xusage(); - - abstract void version(); - abstract void fullVersion(); - - abstract String getLocalizedMessage(String msg, Object... args); - - abstract OptionHelper getOptionHelper(); - - @SuppressWarnings("unchecked") - void addToList(ToolOption opt, String delimiter, String str) { - List list = (List) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>()); - list.addAll(Arrays.asList(str.split(delimiter))); - jdtoolOpts.put(opt, list); - } - - void setExpandRequires(ToolOption opt, String arg) throws OptionException { - switch (arg) { - case "transitive": - jdtoolOpts.put(opt, AccessKind.PUBLIC); - break; - case "all": - jdtoolOpts.put(opt, AccessKind.PRIVATE); - break; - default: - String text = getLocalizedMessage("main.illegal_option_value", arg); - throw new IllegalOptionValue(this::usage, text); - } - } - - void setShowModuleContents(ToolOption opt, String arg) throws OptionException { - switch (arg) { - case "api": - jdtoolOpts.put(opt, AccessKind.PUBLIC); - break; - case "all": - jdtoolOpts.put(opt, AccessKind.PRIVATE); - break; - default: - String text = getLocalizedMessage("main.illegal_option_value", arg); - throw new IllegalOptionValue(this::usage, text); - } - } - - void setShowPackageAccess(ToolOption opt, String arg) throws OptionException { - switch (arg) { - case "exported": - jdtoolOpts.put(opt, AccessKind.PUBLIC); - break; - case "all": - jdtoolOpts.put(opt, AccessKind.PRIVATE); - break; - default: - String text = getLocalizedMessage("main.illegal_option_value", arg); - throw new IllegalOptionValue(this::usage, text); - } - } - - - void setFilter(ToolOption opt, String arg) throws OptionException { - jdtoolOpts.put(opt, getAccessValue(arg)); - } - - void setSimpleFilter(String arg) throws OptionException { - handleSimpleOption(arg); - } - - void setFileManagerOpt(Option opt, String arg) { - fileManagerOpts.put(opt, arg); - } - - void handleSimpleOption(String arg) throws OptionException { - populateSimpleAccessMap(getAccessValue(arg)); - } - - /* - * This method handles both the simple options -package, - * -private, so on, in addition to the new ones such as - * --show-types:public and so on. - */ - private AccessKind getAccessValue(String arg) throws OptionException { - int colon = arg.indexOf(':'); - String value = (colon > 0) - ? arg.substring(colon + 1) - : arg; - switch (value) { - case "public": - return AccessKind.PUBLIC; - case "protected": - return AccessKind.PROTECTED; - case "package": - return AccessKind.PACKAGE; - case "private": - return AccessKind.PRIVATE; - default: - String text = getLocalizedMessage("main.illegal_option_value", value); - throw new IllegalOptionValue(this::usage, text); - } - } - - /* - * Sets the entire kind map to PROTECTED this is the default. - */ - private void populateDefaultAccessMap() { - populateSimpleAccessMap(AccessKind.PROTECTED); - } - - /* - * This sets access to all the allowed kinds in the - * access map. - */ - void populateSimpleAccessMap(AccessKind accessValue) { - for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) { - switch (kind) { - case METHOD: - jdtoolOpts.put(SHOW_MEMBERS, accessValue); - break; - case CLASS: - jdtoolOpts.put(SHOW_TYPES, accessValue); - break; - case PACKAGE: - jdtoolOpts.put(SHOW_PACKAGES, accessValue); - break; - case MODULE: - jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue); - break; - default: - throw new AssertionError("unknown element kind:" + kind); - } - } - } - } -} --- /dev/null 2019-11-20 10:47:51.674104495 -0800 +++ new/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java 2020-01-23 18:12:10.813319339 -0800 @@ -0,0 +1,992 @@ +/* + * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.javadoc.internal.tool; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import javax.lang.model.element.ElementKind; + +import com.sun.tools.javac.main.Option; +import com.sun.tools.javac.main.Option.InvalidValueException; +import com.sun.tools.javac.main.Option.OptionKind; +import com.sun.tools.javac.main.OptionHelper; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Options; + +import static com.sun.tools.javac.main.Option.OptionKind.EXTENDED; +import static com.sun.tools.javac.main.Option.OptionKind.HIDDEN; +import static com.sun.tools.javac.main.Option.OptionKind.STANDARD; +import static jdk.javadoc.internal.tool.Main.Result.OK; + +/** + * Storage and support for javadoc tool options, as distinct from + * the options supported by any doclet that may be in use. + * The tool options includes those options which are delegated + * to javac and/or the file manager, such as options to set + * the source level, and path options to locate the files to be + * documented. + * + *

This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice. + */ +public class ToolOptions { + // The following are the names of options handled in the first pass of option decoding, + // in Start.preprocess. + static final String DOCLET = "-doclet"; + static final String DOCLET_PATH = "-docletpath"; + static final String DUMP_ON_ERROR = "--dump-on-error"; + static final String J = "-J"; + static final String LOCALE = "-locale"; + + /** + * Argument for command-line option {@code -breakiterator}. + */ + private boolean breakIterator = false; + + /** + * Argument for command-line option {@code -locale}. + */ + private String docLocale = ""; + + /** + * Argument for command-line option {@code --dump-on-error}. + * Dump stack traces for debugging etc. + * Similar to javac {@code -doe}. + */ + private boolean dumpOnError = false; + + /** + * Argument for command-line option {@code -exclude}. + */ + private List excludes = new ArrayList<>(); + + /** + * Argument for command-line option {@code --expand-requires}. + */ + private AccessKind expandRequires; + + /** + * Argument for command-line option {@code --ignore-source-errors}. + */ + private boolean ignoreSourceErrors; + + /** + * Argument for command-line option {@code --module}. + */ + private List modules = new ArrayList<>(); + + /** + * Argument for command-line option {@code -Xwerror}. + * Set by -Xwerror. + */ + private boolean rejectWarnings = false; + + /** + * Argument for command-line option {@code --show-members}. + */ + private AccessKind showMembersAccess; + + /** + * Argument for command-line option {@code --show-types}. + */ + private AccessKind showTypesAccess; + + /** + * Argument for command-line option {@code --show-packages}. + */ + private AccessKind showPackagesAccess; + + /** + * Argument for command-line option {@code --show-module-contents}. + */ + private AccessKind showModuleContents; + + /** + * Argument for command-line option {@code -quiet}. + */ + private boolean quiet; + + /** + * Argument for command-line option {@code -subpackages}. + */ + private List subpackages = new ArrayList<>(); + + /** + * Argument for command-line option {@code -verbose}. + */ + private boolean verbose; + + /** + * Argument for command-line option {@code -xclasses}. + * If true, names on the command line that would normally be + * treated as package names are treated as class names instead. + */ + private boolean xclasses = false; + + /** + * Options to be given to the file manager, such as path options + * indicating where to find files to be documented. + */ + private final Map fileManagerOpts; + + /** + * Options to be given to the underlying compiler front-end, + * such as options to indicate the source level to be used. + */ + private final Options compOpts; + + /** + * The "helper" to be used when processing compiler options. + */ + private final OptionHelper compilerOptionHelper; + + /** + * The messager to be used to report diagnostics.. + */ + private final Messager messager; + + /** + * The helper for help and version options + */ + private final ShowHelper showHelper; + + /** + * Creates an object to handle tool options. + * + * @param context the context used to find other tool-related components + * @param messager the messager to be used to report diagnostics + */ + ToolOptions(Context context, Messager messager, ShowHelper showHelper) { + this.messager = messager; + this.showHelper = showHelper; + compOpts = Options.instance(context); + fileManagerOpts = new LinkedHashMap<>(); + compilerOptionHelper = getOptionHelper(); + setAccessDefault(); + } + + /** + * Creates a minimal object, just sufficient to check the names of the + * supported options. + */ + private ToolOptions() { + compOpts = null; + compilerOptionHelper = null; + fileManagerOpts = null; + messager = null; + showHelper = null; + } + + /** + * Returns the set of options supported by the tool, excluding any options + * that are managed by the doclet that may be in use. + * + * @return the set of options + */ + public List getSupportedOptions() { + return supportedOptions; + } + + /** + * Determines if the given option is supported and if so, the + * number of arguments the option takes. + * + * @param option an option + * @return the number of arguments the given option takes or -1 if + * the option is not supported + * @see javax.tools.DocumentationTool#isSupportedOption(String) + */ + public static int isSupportedOption(String option) { + ToolOptions t = new ToolOptions(); + for (ToolOption o : t.supportedOptions) { + for (String name : o.names) { + if (name.equals(option)) + return o.hasArg ? 1 : 0; + } + } + return -1; + } + + /** + * Returns the option to be used to process an argument such as may be found on + * the command line. + * + * @param arg the argument + * @return the option + */ + ToolOption getOption(String arg) { + String name = arg; + if (arg.startsWith("--") && arg.contains("=")) { + name = arg.substring(0, arg.indexOf('=')); + } + for (ToolOption o : supportedOptions) { + for (String n : o.names) { + if (name.equals(n)) { + return o; + } + } + } + return null; + } + + private List supportedOptions = List.of( + // ----- options for underlying compiler ----- + + new ToolOption("-bootclasspath", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.BOOT_CLASS_PATH, primaryName, arg); + } + }, + + new ToolOption("--class-path -classpath -cp", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.CLASS_PATH, primaryName, arg); + } + }, + + new ToolOption("-extdirs", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.EXTDIRS, primaryName, arg); + } + }, + + new ToolOption("--source-path -sourcepath", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.SOURCE_PATH, primaryName, arg); + } + }, + + new ToolOption("--module-source-path", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.MODULE_SOURCE_PATH, primaryName, arg); + } + }, + + new ToolOption("--upgrade-module-path", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.UPGRADE_MODULE_PATH, primaryName, arg); + } + }, + + new ToolOption("--system", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.SYSTEM, primaryName, arg); + } + }, + + new ToolOption("--module-path -p", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.MODULE_PATH, primaryName, arg); + } + }, + + new ToolOption("--add-modules", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.ADD_MODULES, primaryName, arg); + } + }, + + new ToolOption("--limit-modules", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.LIMIT_MODULES, primaryName, arg); + } + }, + + new ToolOption("--module", STANDARD, true) { + @Override + public void process(String arg) { + modules.addAll(List.of(arg.split(","))); + } + }, + + new ToolOption("-encoding", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.ENCODING, primaryName, arg); + } + }, + + new ToolOption("--release", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.RELEASE, primaryName, arg); + } + }, + + new ToolOption("--source -source", STANDARD, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.SOURCE, primaryName, arg); + processCompilerOption(Option.TARGET, Option.TARGET.primaryName, arg); + } + }, + + new ToolOption("-Xmaxerrs", EXTENDED, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.XMAXERRS, primaryName, arg); + } + }, + + new ToolOption("-Xmaxwarns", EXTENDED, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.XMAXWARNS, primaryName, arg); + } + }, + + new ToolOption("--add-reads", EXTENDED, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.ADD_READS, primaryName, arg); + } + }, + + new ToolOption("--add-exports", EXTENDED, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.ADD_EXPORTS, primaryName, arg); + } + }, + + new ToolOption("--patch-module", EXTENDED, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.PATCH_MODULE, primaryName, arg); + } + }, + + new ToolOption("--add-opens", HIDDEN, true) { + @Override + public void process(String arg) throws InvalidValueException { + processCompilerOption(Option.ADD_OPENS, primaryName, arg); + } + }, + + new ToolOption("--enable-preview", STANDARD) { + @Override + public void process() throws InvalidValueException { + processCompilerOption(Option.PREVIEW, primaryName); + } + }, + + // ----- doclet options ----- + + new ToolOption(DOCLET, STANDARD, true), // handled in setDocletInvoker + + new ToolOption(DOCLET_PATH, STANDARD, true), // handled in setDocletInvoker + + // ----- selection options ----- + + new ToolOption("-subpackages", STANDARD, true) { + @Override + public void process(String arg) { + subpackages.addAll(List.of(arg.split(":"))); + } + }, + + new ToolOption("-exclude", STANDARD, true) { + @Override + public void process(String arg) { + excludes.addAll(List.of(arg.split(":"))); + } + }, + + // ----- filtering options ----- + + new ToolOption("-package", STANDARD) { + @Override + public void process() throws OptionException { + setSimpleFilter("package"); + } + }, + + new ToolOption("-private", STANDARD) { + @Override + public void process() throws OptionException { + setSimpleFilter("private"); + } + }, + + new ToolOption("-protected", STANDARD) { + @Override + public void process() throws OptionException { + setSimpleFilter("protected"); + } + }, + + new ToolOption("-public", STANDARD) { + @Override + public void process() throws OptionException { + setSimpleFilter("public"); + } + }, + + new ToolOption("--show-members", STANDARD, true) { + @Override + public void process(String arg) throws OptionException { + setShowMembersAccess(arg); + } + }, + + new ToolOption("--show-types", STANDARD, true) { + @Override + public void process(String arg) throws OptionException { + setShowTypesAccess(arg); + } + }, + + new ToolOption("--show-packages", STANDARD, true) { + @Override + public void process(String arg) throws OptionException { + setShowPackageAccess(arg); + } + }, + + new ToolOption("--show-module-contents", STANDARD, true) { + @Override + public void process(String arg) throws OptionException { + setShowModuleContents(arg); + } + }, + + new ToolOption("--expand-requires", STANDARD, true) { + @Override + public void process(String arg) throws OptionException { + setExpandRequires(arg); + } + }, + + // ----- output control options ----- + + new ToolOption("-quiet", STANDARD) { + @Override + public void process() { + quiet = true; + } + }, + + new ToolOption("-verbose", STANDARD) { + @Override + public void process() { + setVerbose(); + } + }, + + new ToolOption("-Xwerror", HIDDEN) { + @Override + public void process() { + rejectWarnings = true; + } + }, + + // ----- other options ----- + + new ToolOption("-breakiterator", STANDARD) { + @Override + public void process() { + breakIterator = true; + } + }, + + new ToolOption(LOCALE, STANDARD, true) { + @Override + public void process(String arg) { + docLocale = arg; + } + }, + + new ToolOption("-Xclasses", HIDDEN) { + @Override + public void process() { + xclasses = true; + } + }, + + new ToolOption(DUMP_ON_ERROR, HIDDEN) { + @Override + public void process() { + dumpOnError = true; + } + }, + + new ToolOption("--ignore-source-errors", HIDDEN) { + @Override + public void process() { + ignoreSourceErrors = true; + } + }, + + // ----- help options ----- + + new ToolOption("--help -help -? -h", STANDARD) { + @Override + public void process() throws OptionException { + throw new OptionException(OK, showHelper::usage); + } + }, + + new ToolOption("--help-extra -X", STANDARD) { + @Override + public void process() throws OptionException { + throw new OptionException(OK, showHelper::Xusage); + } + }, + + // This option exists only for the purpose of documenting itself. + // It's actually implemented by the launcher. + new ToolOption(J, STANDARD, true) { + @Override + public void process() { + throw new AssertionError("the -J flag should be caught by the launcher."); + } + }, + + new ToolOption("--version", STANDARD) { + @Override + public void process() throws OptionException { + throw new OptionException(OK, showHelper::version); + } + }, + + new ToolOption("--full-version", HIDDEN) { + @Override + public void process() throws OptionException { + throw new OptionException(OK, showHelper::fullVersion); + } + }); + + /** + * Base class for all supported tool options. + */ + static class ToolOption { + + final String primaryName; + final List names; + final OptionKind kind; + final boolean hasArg; + final boolean hasSuffix; // ex: foo:bar or -foo=bar + + ToolOption(String opt, OptionKind kind) { + this(opt, kind, false); + } + + ToolOption(String names, OptionKind kind, boolean hasArg) { + this.names = Arrays.asList(names.split("\\s+")); + this.primaryName = this.names.get(0); + this.kind = kind; + this.hasArg = hasArg; + char lastChar = names.charAt(names.length() - 1); + this.hasSuffix = lastChar == ':' || lastChar == '='; + } + + void process(String arg) throws OptionException, Option.InvalidValueException { } + + void process() throws OptionException, Option.InvalidValueException { } + + List getNames() { + return names; + } + + String getParameters(Messager messager) { + return (hasArg || primaryName.endsWith(":")) + ? messager.getText(getKey(primaryName, ".arg")) + : null; + } + + String getDescription(Messager messager) { + return messager.getText(getKey(primaryName, ".desc")); + } + + private String getKey(String optionName, String suffix) { + return "main.opt." + + optionName + .replaceAll("^-*", "") // remove leading '-' + .replaceAll("[^A-Za-z0-9]+$", "") // remove trailing non-alphanumeric + .replaceAll("[^A-Za-z0-9]", ".") // replace internal non-alphanumeric + + suffix; + } + } + + interface ShowHelper { + /** + * Show command-line help for the standard options, as requested by + * the {@code --help} option and its aliases. + */ + void usage(); + + /** + * Show command-line help for the extended options, as requested by + * the {@code --help-extended} option and its aliases. + */ + void Xusage(); + + /** + * Show the basic version information, as requested by the {@code --version} option. + */ + void version(); + + /** + * Show the full version information, as requested by the {@code --full-version} option. + */ + void fullVersion(); + } + + // + /** + * Argument for command-line option {@code -breakiterator}. + */ + boolean breakIterator() { + return breakIterator; + } + + /** + * Argument for command-line option {@code -locale}. + */ + String locale() { + return docLocale; + } + + /** + * Argument for command-line option {@code --dump-on-error}. + * Dump stack traces for debugging etc. + * Similar to javac {@code -doe}. + */ + boolean dumpOnError() { + return dumpOnError; + } + + void setDumpOnError(boolean v) { + dumpOnError = true; + } + + /** + * Argument for command-line option {@code -exclude}. + */ + List excludes() { + return excludes; + } + + /** + * Argument for command-line option {@code --expand-requires}. + */ + AccessKind expandRequires() { + return expandRequires; + } + + /** + * Argument for command-line option {@code --ignore-source-errors}. + */ + boolean ignoreSourceErrors() { + return ignoreSourceErrors; + } + + /** + * Argument for command-line option {@code --module}. + */ + List modules() { + return modules; + } + + /** + * Argument for command-line option {@code -Xwerror}. + * Set by -Xwerror. + */ + boolean rejectWarnings() { + return rejectWarnings; + } + + /** + * Argument for command-line option {@code --show-members}. + */ + AccessKind showMembersAccess() { + return showMembersAccess; + } + + /** + * Argument for command-line option {@code --show-types}. + */ + AccessKind showTypesAccess() { + return showTypesAccess; + } + + /** + * Argument for command-line option {@code --show-packages}. + */ + AccessKind showPackagesAccess() { + return showPackagesAccess; + } + + /** + * Argument for command-line option {@code --show-module-contents}. + */ + AccessKind showModuleContents() { + return showModuleContents; + } + + /** + * Argument for command-line option {@code -quiet}. + */ + boolean quiet() { + return quiet; + } + + /** + * Argument for command-line option {@code -subpackages}. + */ + List subpackages() { + return subpackages; + } + + /** + * Argument for command-line option {@code -verbose}. + */ + boolean verbose() { + return verbose; + } + + /** + * Argument for command-line option {@code -xclasses}. + * If true, names on the command line that would normally be + * treated as package names are treated as class names instead. + */ + boolean xclasses() { + return xclasses; + } + + /** + * Returns the set of options to be used for the instance of the + * underlying compiler front-end. + * + * @return the options + */ + Options compilerOptions() { + return compOpts; + } + + /** + * Returns the set of options to be used for the file manager. + * + * @return the options + */ + Map fileManagerOptions() { + return fileManagerOpts; + } + // + + /** + * Returns an {@code IllegalOptionValue} exception. + * + * @param arg the arghument to include in the detail message + * @return the exception + */ + private IllegalOptionValue illegalOptionValue(String arg) { + return new IllegalOptionValue(showHelper::usage, messager.getText("main.illegal_option_value", arg)); + } + + /** + * Process a compiler option. + * + * @param option the option object to process the command-line option + * @param opt the command-line option + * @throws Option.InvalidValueException if the command-line option is invalid + */ + void processCompilerOption(Option option, String opt) throws Option.InvalidValueException { + option.process(compilerOptionHelper, opt); + } + + /** + * Process a compiler option. + * + * @param option the option object to process the command-line option + * @param opt the command-line option + * @param arg the argument for the command-line option + * @throws Option.InvalidValueException if the command-line option is invalid + */ + private void processCompilerOption(Option option, String opt, String arg) throws Option.InvalidValueException { + option.process(compilerOptionHelper, opt, arg); + } + + /** + * Returns a "helper" to be used when processing compiler options. + * @return the helper + */ + private OptionHelper getOptionHelper() { + return new OptionHelper.GrumpyHelper(messager) { + @Override + public String get(com.sun.tools.javac.main.Option option) { + return compOpts.get(option); + } + + @Override + public void put(String name, String value) { + compOpts.put(name, value); + } + + @Override + public void remove(String name) { + compOpts.remove(name); + } + + @Override + public boolean handleFileManagerOption(com.sun.tools.javac.main.Option option, String value) { + fileManagerOpts.put(option, value); + return true; + } + }; + } + + private void setExpandRequires(String arg) throws OptionException { + switch (arg) { + case "transitive": + expandRequires = AccessKind.PUBLIC; + break; + case "all": + expandRequires = AccessKind.PRIVATE; + break; + default: + throw illegalOptionValue(arg); + } + } + + private void setShowModuleContents(String arg) throws OptionException { + switch (arg) { + case "api": + showModuleContents = AccessKind.PUBLIC; + break; + case "all": + showModuleContents = AccessKind.PRIVATE; + break; + default: + throw illegalOptionValue(arg); + } + } + + private void setShowPackageAccess(String arg) throws OptionException { + switch (arg) { + case "exported": + showPackagesAccess = AccessKind.PUBLIC; + break; + case "all": + showPackagesAccess = AccessKind.PRIVATE; + break; + default: + throw illegalOptionValue(arg); + } + } + + private void setShowTypesAccess(String arg) throws OptionException { + showTypesAccess = getAccessValue(arg); + } + + private void setShowMembersAccess(String arg) throws OptionException { + showMembersAccess = getAccessValue(arg); + } + + private void setSimpleFilter(String arg) throws OptionException { + setSimpleAccessOption(arg); + } + + private void setVerbose() { + compOpts.put("-verbose", ""); + verbose = true; + } + + private void setSimpleAccessOption(String arg) throws OptionException { + setAccess(getAccessValue(arg)); + } + + /* + * This method handles both the simple options -package, + * -private, so on, in addition to the new ones such as + * --show-types:public and so on. + */ + private AccessKind getAccessValue(String arg) throws OptionException { + int colon = arg.indexOf(':'); + String value = (colon > 0) + ? arg.substring(colon + 1) + : arg; + switch (value) { + case "public": + return AccessKind.PUBLIC; + case "protected": + return AccessKind.PROTECTED; + case "package": + return AccessKind.PACKAGE; + case "private": + return AccessKind.PRIVATE; + default: + throw illegalOptionValue(value); + } + } + + /* + * Sets all access members to PROTECTED; this is the default. + */ + private void setAccessDefault() { + setAccess(AccessKind.PROTECTED); + } + + /* + * This sets access to all the allowed kinds in the + * access members. + */ + private void setAccess(AccessKind accessValue) { + for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) { + switch (kind) { + case METHOD: + showMembersAccess = accessValue; + break; + case CLASS: + showTypesAccess = accessValue; + break; + case PACKAGE: + showPackagesAccess = accessValue; + break; + case MODULE: + showModuleContents = accessValue; + break; + default: + throw new AssertionError("unknown element kind:" + kind); + } + } + } +}