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

Tue, 11 Mar 2008 13:14:55 -0700

author
jjg
date
Tue, 11 Mar 2008 13:14:55 -0700
changeset 11
b66d15dfd001
parent 1
9a66ca7c79fa
child 54
eaf608c64fec
permissions
-rw-r--r--

6307187: clean up code for -Xlint:options
Summary: introduce common code for handling one-of and any-of options
Reviewed-by: mcimadamore

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

mercurial