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