src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java

Mon, 07 Mar 2011 13:45:06 -0800

author
jjg
date
Mon, 07 Mar 2011 13:45:06 -0800
changeset 916
cb9493a80341
parent 798
4868a36f6fd8
child 962
0ff2bbd38f10
permissions
-rw-r--r--

6980021: javac should document @file command line option
Reviewed-by: mcimadamore

     1 /*
     2  * Copyright (c) 2006, 2010, 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  */
    26 package com.sun.tools.javac.main;
    28 import com.sun.tools.javac.code.Lint;
    29 import com.sun.tools.javac.code.Source;
    30 import com.sun.tools.javac.code.Type;
    31 import com.sun.tools.javac.jvm.Target;
    32 import com.sun.tools.javac.main.JavacOption.HiddenOption;
    33 import com.sun.tools.javac.main.JavacOption.Option;
    34 import com.sun.tools.javac.main.JavacOption.XOption;
    35 import com.sun.tools.javac.util.ListBuffer;
    36 import com.sun.tools.javac.util.Options;
    37 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
    38 import java.io.File;
    39 import java.io.FileWriter;
    40 import java.io.PrintWriter;
    41 import java.util.EnumSet;
    42 import java.util.LinkedHashMap;
    43 import java.util.Map;
    44 import java.util.Set;
    45 import javax.lang.model.SourceVersion;
    47 import static com.sun.tools.javac.main.OptionName.*;
    49 /**
    50  * TODO: describe com.sun.tools.javac.main.RecognizedOptions
    51  *
    52  * <p><b>This is NOT part of any supported API.
    53  * If you write code that depends on this, you do so at your own
    54  * risk.  This code and its internal interfaces are subject to change
    55  * or deletion without notice.</b></p>
    56  */
    57 public class RecognizedOptions {
    59     private RecognizedOptions() {}
    61     public interface OptionHelper {
    63         void setOut(PrintWriter out);
    65         void error(String key, Object... args);
    67         void printVersion();
    69         void printFullVersion();
    71         void printHelp();
    73         void printXhelp();
    75         void addFile(File f);
    77         void addClassName(String s);
    79     }
    81     public static class GrumpyHelper implements OptionHelper {
    83         public void setOut(PrintWriter out) {
    84             throw new IllegalArgumentException();
    85         }
    87         public void error(String key, Object... args) {
    88             throw new IllegalArgumentException(Main.getLocalizedString(key, args));
    89         }
    91         public void printVersion() {
    92             throw new IllegalArgumentException();
    93         }
    95         public void printFullVersion() {
    96             throw new IllegalArgumentException();
    97         }
    99         public void printHelp() {
   100             throw new IllegalArgumentException();
   101         }
   103         public void printXhelp() {
   104             throw new IllegalArgumentException();
   105         }
   107         public void addFile(File f) {
   108             throw new IllegalArgumentException(f.getPath());
   109         }
   111         public void addClassName(String s) {
   112             throw new IllegalArgumentException(s);
   113         }
   115     }
   117     static Set<OptionName> javacOptions = EnumSet.of(
   118         G,
   119         G_NONE,
   120         G_CUSTOM,
   121         XLINT,
   122         XLINT_CUSTOM,
   123         NOWARN,
   124         VERBOSE,
   125         DEPRECATION,
   126         CLASSPATH,
   127         CP,
   128         SOURCEPATH,
   129         BOOTCLASSPATH,
   130         XBOOTCLASSPATH_PREPEND,
   131         XBOOTCLASSPATH_APPEND,
   132         XBOOTCLASSPATH,
   133         EXTDIRS,
   134         DJAVA_EXT_DIRS,
   135         ENDORSEDDIRS,
   136         DJAVA_ENDORSED_DIRS,
   137         PROC,
   138         PROCESSOR,
   139         PROCESSORPATH,
   140         D,
   141         S,
   142         IMPLICIT,
   143         ENCODING,
   144         SOURCE,
   145         TARGET,
   146         VERSION,
   147         FULLVERSION,
   148         DIAGS,
   149         HELP,
   150         A,
   151         X,
   152         J,
   153         MOREINFO,
   154         WERROR,
   155         // COMPLEXINFERENCE,
   156         PROMPT,
   157         DOE,
   158         PRINTSOURCE,
   159         WARNUNCHECKED,
   160         XMAXERRS,
   161         XMAXWARNS,
   162         XSTDOUT,
   163         XPKGINFO,
   164         XPRINT,
   165         XPRINTROUNDS,
   166         XPRINTPROCESSORINFO,
   167         XPREFER,
   168         O,
   169         XJCOV,
   170         XD,
   171         AT,
   172         SOURCEFILE);
   174     static Set<OptionName> javacFileManagerOptions = EnumSet.of(
   175         CLASSPATH,
   176         CP,
   177         SOURCEPATH,
   178         BOOTCLASSPATH,
   179         XBOOTCLASSPATH_PREPEND,
   180         XBOOTCLASSPATH_APPEND,
   181         XBOOTCLASSPATH,
   182         EXTDIRS,
   183         DJAVA_EXT_DIRS,
   184         ENDORSEDDIRS,
   185         DJAVA_ENDORSED_DIRS,
   186         PROCESSORPATH,
   187         D,
   188         S,
   189         ENCODING,
   190         SOURCE);
   192     static Set<OptionName> javacToolOptions = EnumSet.of(
   193         G,
   194         G_NONE,
   195         G_CUSTOM,
   196         XLINT,
   197         XLINT_CUSTOM,
   198         NOWARN,
   199         VERBOSE,
   200         DEPRECATION,
   201         PROC,
   202         PROCESSOR,
   203         IMPLICIT,
   204         SOURCE,
   205         TARGET,
   206         // VERSION,
   207         // FULLVERSION,
   208         // HELP,
   209         A,
   210         // X,
   211         // J,
   212         MOREINFO,
   213         WERROR,
   214         // COMPLEXINFERENCE,
   215         PROMPT,
   216         DOE,
   217         PRINTSOURCE,
   218         WARNUNCHECKED,
   219         XMAXERRS,
   220         XMAXWARNS,
   221         // XSTDOUT,
   222         XPKGINFO,
   223         XPRINT,
   224         XPRINTROUNDS,
   225         XPRINTPROCESSORINFO,
   226         XPREFER,
   227         O,
   228         XJCOV,
   229         XD);
   231     static Option[] getJavaCompilerOptions(OptionHelper helper) {
   232         return getOptions(helper, javacOptions);
   233     }
   235     public static Option[] getJavacFileManagerOptions(OptionHelper helper) {
   236         return getOptions(helper, javacFileManagerOptions);
   237     }
   239     public static Option[] getJavacToolOptions(OptionHelper helper) {
   240         return getOptions(helper, javacToolOptions);
   241     }
   243     static Option[] getOptions(OptionHelper helper, Set<OptionName> desired) {
   244         ListBuffer<Option> options = new ListBuffer<Option>();
   245         for (Option option : getAll(helper))
   246             if (desired.contains(option.getName()))
   247                 options.append(option);
   248         return options.toArray(new Option[options.length()]);
   249     }
   251     /**
   252      * Get all the recognized options.
   253      * @param helper an {@code OptionHelper} to help when processing options
   254      * @return an array of options
   255      */
   256     public static Option[] getAll(final OptionHelper helper) {
   257         return new Option[] {
   258         new Option(G,                                           "opt.g"),
   259         new Option(G_NONE,                                      "opt.g.none") {
   260             @Override
   261             public boolean process(Options options, String option) {
   262                 options.put("-g:", "none");
   263                 return false;
   264             }
   265         },
   267         new Option(G_CUSTOM,                                    "opt.g.lines.vars.source",
   268                 Option.ChoiceKind.ANYOF, "lines", "vars", "source"),
   270         new XOption(XLINT,                                      "opt.Xlint"),
   271         new XOption(XLINT_CUSTOM,                               "opt.Xlint.suboptlist",
   272                 Option.ChoiceKind.ANYOF, getXLintChoices()),
   274         // -nowarn is retained for command-line backward compatibility
   275         new Option(NOWARN,                                      "opt.nowarn") {
   276             @Override
   277             public boolean process(Options options, String option) {
   278                 options.put("-Xlint:none", option);
   279                 return false;
   280             }
   281         },
   283         new Option(VERBOSE,                                     "opt.verbose"),
   285         // -deprecation is retained for command-line backward compatibility
   286         new Option(DEPRECATION,                                 "opt.deprecation") {
   287             @Override
   288             public boolean process(Options options, String option) {
   289                 options.put("-Xlint:deprecation", option);
   290                 return false;
   291             }
   292         },
   294         new Option(CLASSPATH,              "opt.arg.path",      "opt.classpath"),
   295         new Option(CP,                     "opt.arg.path",      "opt.classpath") {
   296             @Override
   297             public boolean process(Options options, String option, String arg) {
   298                 return super.process(options, "-classpath", arg);
   299             }
   300         },
   301         new Option(SOURCEPATH,             "opt.arg.path",      "opt.sourcepath"),
   302         new Option(BOOTCLASSPATH,          "opt.arg.path",      "opt.bootclasspath") {
   303             @Override
   304             public boolean process(Options options, String option, String arg) {
   305                 options.remove("-Xbootclasspath/p:");
   306                 options.remove("-Xbootclasspath/a:");
   307                 return super.process(options, option, arg);
   308             }
   309         },
   310         new XOption(XBOOTCLASSPATH_PREPEND,"opt.arg.path", "opt.Xbootclasspath.p"),
   311         new XOption(XBOOTCLASSPATH_APPEND, "opt.arg.path", "opt.Xbootclasspath.a"),
   312         new XOption(XBOOTCLASSPATH,        "opt.arg.path", "opt.bootclasspath") {
   313             @Override
   314             public boolean process(Options options, String option, String arg) {
   315                 options.remove("-Xbootclasspath/p:");
   316                 options.remove("-Xbootclasspath/a:");
   317                 return super.process(options, "-bootclasspath", arg);
   318             }
   319         },
   320         new Option(EXTDIRS,                "opt.arg.dirs",      "opt.extdirs"),
   321         new XOption(DJAVA_EXT_DIRS,        "opt.arg.dirs",      "opt.extdirs") {
   322             @Override
   323             public boolean process(Options options, String option, String arg) {
   324                 return super.process(options, "-extdirs", arg);
   325             }
   326         },
   327         new Option(ENDORSEDDIRS,            "opt.arg.dirs",     "opt.endorseddirs"),
   328         new XOption(DJAVA_ENDORSED_DIRS,    "opt.arg.dirs",     "opt.endorseddirs") {
   329             @Override
   330             public boolean process(Options options, String option, String arg) {
   331                 return super.process(options, "-endorseddirs", arg);
   332             }
   333         },
   334         new Option(PROC,                                 "opt.proc.none.only",
   335                 Option.ChoiceKind.ONEOF, "none", "only"),
   336         new Option(PROCESSOR,           "opt.arg.class.list",   "opt.processor"),
   337         new Option(PROCESSORPATH,       "opt.arg.path",         "opt.processorpath"),
   338         new Option(D,                   "opt.arg.directory",    "opt.d"),
   339         new Option(S,                   "opt.arg.directory",    "opt.sourceDest"),
   340         new Option(IMPLICIT,                                    "opt.implicit",
   341                 Option.ChoiceKind.ONEOF, "none", "class"),
   342         new Option(ENCODING,            "opt.arg.encoding",     "opt.encoding"),
   343         new Option(SOURCE,              "opt.arg.release",      "opt.source") {
   344             @Override
   345             public boolean process(Options options, String option, String operand) {
   346                 Source source = Source.lookup(operand);
   347                 if (source == null) {
   348                     helper.error("err.invalid.source", operand);
   349                     return true;
   350                 }
   351                 return super.process(options, option, operand);
   352             }
   353         },
   354         new Option(TARGET,              "opt.arg.release",      "opt.target") {
   355             @Override
   356             public boolean process(Options options, String option, String operand) {
   357                 Target target = Target.lookup(operand);
   358                 if (target == null) {
   359                     helper.error("err.invalid.target", operand);
   360                     return true;
   361                 }
   362                 return super.process(options, option, operand);
   363             }
   364         },
   365         new Option(VERSION,                                     "opt.version") {
   366             @Override
   367             public boolean process(Options options, String option) {
   368                 helper.printVersion();
   369                 return super.process(options, option);
   370             }
   371         },
   372         new HiddenOption(FULLVERSION) {
   373             @Override
   374             public boolean process(Options options, String option) {
   375                 helper.printFullVersion();
   376                 return super.process(options, option);
   377             }
   378         },
   379         new HiddenOption(DIAGS) {
   380             @Override
   381             public boolean process(Options options, String option) {
   382                 Option xd = getOptions(helper, EnumSet.of(XD))[0];
   383                 option = option.substring(option.indexOf('=') + 1);
   384                 String diagsOption = option.contains("%") ?
   385                     "-XDdiagsFormat=" :
   386                     "-XDdiags=";
   387                 diagsOption += option;
   388                 if (xd.matches(diagsOption))
   389                     return xd.process(options, diagsOption);
   390                 else
   391                     return false;
   392             }
   393         },
   394         new Option(HELP,                                        "opt.help") {
   395             @Override
   396             public boolean process(Options options, String option) {
   397                 helper.printHelp();
   398                 return super.process(options, option);
   399             }
   400         },
   401         new Option(A,                "opt.arg.key.equals.value","opt.A") {
   402             @Override
   403             String helpSynopsis() {
   404                 hasSuffix = true;
   405                 return super.helpSynopsis();
   406             }
   408             @Override
   409             public boolean matches(String arg) {
   410                 return arg.startsWith("-A");
   411             }
   413             @Override
   414             public boolean hasArg() {
   415                 return false;
   416             }
   417             // Mapping for processor options created in
   418             // JavacProcessingEnvironment
   419             @Override
   420             public boolean process(Options options, String option) {
   421                 int argLength = option.length();
   422                 if (argLength == 2) {
   423                     helper.error("err.empty.A.argument");
   424                     return true;
   425                 }
   426                 int sepIndex = option.indexOf('=');
   427                 String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
   428                 if (!JavacProcessingEnvironment.isValidOptionName(key)) {
   429                     helper.error("err.invalid.A.key", option);
   430                     return true;
   431                 }
   432                 return process(options, option, option);
   433             }
   434         },
   435         new Option(X,                                           "opt.X") {
   436             @Override
   437             public boolean process(Options options, String option) {
   438                 helper.printXhelp();
   439                 return super.process(options, option);
   440             }
   441         },
   443         // This option exists only for the purpose of documenting itself.
   444         // It's actually implemented by the launcher.
   445         new Option(J,                   "opt.arg.flag",         "opt.J") {
   446             @Override
   447             String helpSynopsis() {
   448                 hasSuffix = true;
   449                 return super.helpSynopsis();
   450             }
   451             @Override
   452             public boolean process(Options options, String option) {
   453                 throw new AssertionError
   454                     ("the -J flag should be caught by the launcher.");
   455             }
   456         },
   458         // stop after parsing and attributing.
   459         // new HiddenOption("-attrparseonly"),
   461         // new Option("-moreinfo",                                      "opt.moreinfo") {
   462         new HiddenOption(MOREINFO) {
   463             @Override
   464             public boolean process(Options options, String option) {
   465                 Type.moreInfo = true;
   466                 return super.process(options, option);
   467             }
   468         },
   470         // treat warnings as errors
   471         new Option(WERROR,                                      "opt.Werror"),
   473         // use complex inference from context in the position of a method call argument
   474         new HiddenOption(COMPLEXINFERENCE),
   476         // generare source stubs
   477         // new HiddenOption("-stubs"),
   479         // relax some constraints to allow compiling from stubs
   480         // new HiddenOption("-relax"),
   482         // output source after translating away inner classes
   483         // new Option("-printflat",                             "opt.printflat"),
   484         // new HiddenOption("-printflat"),
   486         // display scope search details
   487         // new Option("-printsearch",                           "opt.printsearch"),
   488         // new HiddenOption("-printsearch"),
   490         // prompt after each error
   491         // new Option("-prompt",                                        "opt.prompt"),
   492         new HiddenOption(PROMPT),
   494         // dump stack on error
   495         new HiddenOption(DOE),
   497         // output source after type erasure
   498         // new Option("-s",                                     "opt.s"),
   499         new HiddenOption(PRINTSOURCE),
   501         // output shrouded class files
   502         // new Option("-scramble",                              "opt.scramble"),
   503         // new Option("-scrambleall",                           "opt.scrambleall"),
   505         // display warnings for generic unchecked operations
   506         new HiddenOption(WARNUNCHECKED) {
   507             @Override
   508             public boolean process(Options options, String option) {
   509                 options.put("-Xlint:unchecked", option);
   510                 return false;
   511             }
   512         },
   514         new XOption(XMAXERRS,           "opt.arg.number",       "opt.maxerrs"),
   515         new XOption(XMAXWARNS,          "opt.arg.number",       "opt.maxwarns"),
   516         new XOption(XSTDOUT,            "opt.arg.file",         "opt.Xstdout") {
   517             @Override
   518             public boolean process(Options options, String option, String arg) {
   519                 try {
   520                     helper.setOut(new PrintWriter(new FileWriter(arg), true));
   521                 } catch (java.io.IOException e) {
   522                     helper.error("err.error.writing.file", arg, e);
   523                     return true;
   524                 }
   525                 return super.process(options, option, arg);
   526             }
   527         },
   529         new XOption(XPRINT,                                     "opt.print"),
   531         new XOption(XPRINTROUNDS,                               "opt.printRounds"),
   533         new XOption(XPRINTPROCESSORINFO,                        "opt.printProcessorInfo"),
   535         new XOption(XPREFER,                                    "opt.prefer",
   536                 Option.ChoiceKind.ONEOF, "source", "newer"),
   538         new XOption(XPKGINFO,                                   "opt.pkginfo",
   539                 Option.ChoiceKind.ONEOF, "always", "legacy", "nonempty"),
   541         /* -O is a no-op, accepted for backward compatibility. */
   542         new HiddenOption(O),
   544         /* -Xjcov produces tables to support the code coverage tool jcov. */
   545         new HiddenOption(XJCOV),
   547         /* This is a back door to the compiler's option table.
   548          * -XDx=y sets the option x to the value y.
   549          * -XDx sets the option x to the value x.
   550          */
   551         new HiddenOption(XD) {
   552             String s;
   553             @Override
   554             public boolean matches(String s) {
   555                 this.s = s;
   556                 return s.startsWith(name.optionName);
   557             }
   558             @Override
   559             public boolean process(Options options, String option) {
   560                 s = s.substring(name.optionName.length());
   561                 int eq = s.indexOf('=');
   562                 String key = (eq < 0) ? s : s.substring(0, eq);
   563                 String value = (eq < 0) ? s : s.substring(eq+1);
   564                 options.put(key, value);
   565                 return false;
   566             }
   567         },
   569         // This option exists only for the purpose of documenting itself.
   570         // It's actually implemented by the CommandLine class.
   571         new Option(AT,                   "opt.arg.file",         "opt.AT") {
   572             @Override
   573             String helpSynopsis() {
   574                 hasSuffix = true;
   575                 return super.helpSynopsis();
   576             }
   577             @Override
   578             public boolean process(Options options, String option) {
   579                 throw new AssertionError
   580                     ("the @ flag should be caught by CommandLine.");
   581             }
   582         },
   584         /*
   585          * TODO: With apt, the matches method accepts anything if
   586          * -XclassAsDecls is used; code elsewhere does the lookup to
   587          * see if the class name is both legal and found.
   588          *
   589          * In apt, the process method adds the candidate class file
   590          * name to a separate list.
   591          */
   592         new HiddenOption(SOURCEFILE) {
   593             String s;
   594             @Override
   595             public boolean matches(String s) {
   596                 this.s = s;
   597                 return s.endsWith(".java")  // Java source file
   598                     || SourceVersion.isName(s);   // Legal type name
   599             }
   600             @Override
   601             public boolean process(Options options, String option) {
   602                 if (s.endsWith(".java") ) {
   603                     File f = new File(s);
   604                     if (!f.exists()) {
   605                         helper.error("err.file.not.found", f);
   606                         return true;
   607                     }
   608                     if (!f.isFile()) {
   609                         helper.error("err.file.not.file", f);
   610                         return true;
   611                     }
   612                     helper.addFile(f);
   613                 }
   614                 else
   615                     helper.addClassName(s);
   616                 return false;
   617             }
   618         },
   619     };
   620     }
   622     public enum PkgInfo {
   623         ALWAYS, LEGACY, NONEMPTY;
   624         public static PkgInfo get(Options options) {
   625             String v = options.get(XPKGINFO);
   626             return (v == null
   627                     ? PkgInfo.LEGACY
   628                     : PkgInfo.valueOf(v.toUpperCase()));
   629         }
   630     }
   632     private static Map<String,Boolean> getXLintChoices() {
   633         Map<String,Boolean> choices = new LinkedHashMap<String,Boolean>();
   634         choices.put("all", false);
   635         for (Lint.LintCategory c : Lint.LintCategory.values())
   636             choices.put(c.option, c.hidden);
   637         for (Lint.LintCategory c : Lint.LintCategory.values())
   638             choices.put("-" + c.option, c.hidden);
   639         choices.put("none", false);
   640         return choices;
   641     }
   643 }

mercurial