changeset 1156:3809292620c9

7120736: refactor javac option handling Reviewed-by: mcimadamore
author jjg
date Tue, 13 Dec 2011 11:21:28 -0800
parents 4822dfe0922b
children 4e4fed1d02f9
files src/share/classes/com/sun/tools/javac/api/JavacTool.java src/share/classes/com/sun/tools/javac/code/Source.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Enter.java src/share/classes/com/sun/tools/javac/comp/Lower.java src/share/classes/com/sun/tools/javac/file/Locations.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/jvm/Gen.java src/share/classes/com/sun/tools/javac/jvm/Target.java src/share/classes/com/sun/tools/javac/main/JavaCompiler.java src/share/classes/com/sun/tools/javac/main/Main.java src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java src/share/classes/com/sun/tools/javac/util/BaseFileManager.java src/share/classes/com/sun/tools/javac/util/Log.java src/share/classes/com/sun/tools/javac/util/Options.java test/tools/javac/diags/examples/UnsupportedEncoding.java
diffstat 18 files changed, 164 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Tue Dec 13 11:21:28 2011 -0800
@@ -25,18 +25,15 @@
 
 package com.sun.tools.javac.api;
 
-import java.io.File;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.Writer;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 import javax.lang.model.SourceVersion;
@@ -44,17 +41,15 @@
 
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.JavacOption.OptionKind;
-import com.sun.tools.javac.main.JavacOption;
 import com.sun.tools.javac.main.Main;
-import com.sun.tools.javac.main.RecognizedOptions.GrumpyHelper;
-import com.sun.tools.javac.main.RecognizedOptions;
+import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.OptionHelper;
+import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
 import com.sun.tools.javac.util.ClientCodeException;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.util.Pair;
 
 /**
  * TODO: describe com.sun.tools.javac.api.Tool
@@ -67,23 +62,10 @@
  * @author Peter von der Ah\u00e9
  */
 public final class JavacTool implements JavaCompiler {
-    private final List<Pair<String,String>> options
-        = new ArrayList<Pair<String,String>>();
-    private final Context dummyContext = new Context();
-
-    private final PrintWriter silent = new PrintWriter(new OutputStream(){
-        public void write(int b) {}
-    });
-
-    private final Main sharedCompiler = new Main("javac", silent);
-    {
-        sharedCompiler.setOptions(Options.instance(dummyContext));
-    }
-
     /**
-     * Constructor used by service provider mechanism.  The correct way to
-     * obtain an instance of this class is using create or the service provider
-     * mechanism.
+     * Constructor used by service provider mechanism.  The recommended way to
+     * obtain an instance of this class is by using {@link #create} or the
+     * service provider mechanism.
      * @see javax.tools.JavaCompilerTool
      * @see javax.tools.ToolProvider
      * @see #create
@@ -99,49 +81,6 @@
         return new JavacTool();
     }
 
-    private String argsToString(Object... args) {
-        String newArgs = null;
-        if (args.length > 0) {
-            StringBuilder sb = new StringBuilder();
-            String separator = "";
-            for (Object arg : args) {
-                sb.append(separator).append(arg.toString());
-                separator = File.pathSeparator;
-            }
-            newArgs = sb.toString();
-        }
-        return newArgs;
-    }
-
-    private void setOption1(String name, OptionKind kind, Object... args) {
-        String arg = argsToString(args);
-        JavacOption option = sharedCompiler.getOption(name);
-        if (option == null || !match(kind, option.getKind()))
-            throw new IllegalArgumentException(name);
-        if ((args.length != 0) != option.hasArg())
-            throw new IllegalArgumentException(name);
-        if (option.hasArg()) {
-            if (option.process(null, name, arg)) // FIXME
-                throw new IllegalArgumentException(name);
-        } else {
-            if (option.process(null, name)) // FIXME
-                throw new IllegalArgumentException(name);
-        }
-        options.add(new Pair<String,String>(name,arg));
-    }
-
-    public void setOption(String name, Object... args) {
-        setOption1(name, OptionKind.NORMAL, args);
-    }
-
-    public void setExtendedOption(String name, Object... args)  {
-        setOption1(name, OptionKind.EXTENDED, args);
-    }
-
-    private static boolean match(OptionKind clientKind, OptionKind optionKind) {
-        return (clientKind == (optionKind == OptionKind.HIDDEN ? OptionKind.EXTENDED : optionKind));
-    }
-
     public JavacFileManager getStandardFileManager(
         DiagnosticListener<? super JavaFileObject> diagnosticListener,
         Locale locale,
@@ -209,7 +148,9 @@
             if (fileManager == null)
                 fileManager = getStandardFileManager(diagnosticListener, null, null);
             fileManager = ccw.wrap(fileManager);
+
             context.put(JavaFileManager.class, fileManager);
+
             processOptions(context, fileManager, options);
             Main compiler = new Main("javacTask", context.get(Log.outKey));
             return new JavacTaskImpl(compiler, options, context, classes, compilationUnits);
@@ -225,11 +166,28 @@
         if (options == null)
             return;
 
-        Options optionTable = Options.instance(context);
+        final Options optionTable = Options.instance(context);
         Log log = Log.instance(context);
 
-        JavacOption[] recognizedOptions =
-            RecognizedOptions.getJavacToolOptions(new GrumpyHelper(log));
+        Option[] recognizedOptions =
+                Option.getJavacToolOptions().toArray(new Option[0]);
+        OptionHelper optionHelper = new GrumpyHelper(log) {
+            @Override
+            public String get(Option option) {
+                return optionTable.get(option.getText());
+            }
+
+            @Override
+            public void put(String name, String value) {
+                optionTable.put(name, value);
+            }
+
+            @Override
+            public void remove(String name) {
+                optionTable.remove(name);
+            }
+        };
+
         Iterator<String> flags = options.iterator();
         while (flags.hasNext()) {
             String flag = flags.next();
@@ -247,19 +205,19 @@
                 }
             }
 
-            JavacOption option = recognizedOptions[j];
+            Option option = recognizedOptions[j];
             if (option.hasArg()) {
                 if (!flags.hasNext()) {
                     String msg = log.localize(PrefixKind.JAVAC, "err.req.arg", flag);
                     throw new IllegalArgumentException(msg);
                 }
                 String operand = flags.next();
-                if (option.process(optionTable, flag, operand))
+                if (option.process(optionHelper, flag, operand))
                     // should not happen as the GrumpyHelper will throw exceptions
                     // in case of errors
                     throw new IllegalArgumentException(flag + " " + operand);
             } else {
-                if (option.process(optionTable, flag))
+                if (option.process(optionHelper, flag))
                     // should not happen as the GrumpyHelper will throw exceptions
                     // in case of errors
                     throw new IllegalArgumentException(flag);
@@ -283,9 +241,8 @@
     }
 
     public int isSupportedOption(String option) {
-        JavacOption[] recognizedOptions =
-            RecognizedOptions.getJavacToolOptions(new GrumpyHelper(null));
-        for (JavacOption o : recognizedOptions) {
+        Set<Option> recognizedOptions = Option.getJavacToolOptions();
+        for (Option o : recognizedOptions) {
             if (o.matches(option))
                 return o.hasArg() ? 1 : 0;
         }
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Tue Dec 13 11:21:28 2011 -0800
@@ -32,7 +32,7 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.jvm.Target;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** The source language version accepted.
  *
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Tue Dec 13 11:21:28 2011 -0800
@@ -48,7 +48,6 @@
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.code.TypeTags.WILDCARD;
 
-import static com.sun.tools.javac.main.OptionName.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 
 /** Type checking helper class for the attribution phase.
@@ -110,7 +109,7 @@
         allowAnnotations = source.allowAnnotations();
         allowCovariantReturns = source.allowCovariantReturns();
         allowSimplifiedVarargs = source.allowSimplifiedVarargs();
-        complexInference = options.isSet(COMPLEXINFERENCE);
+        complexInference = options.isSet("complexinference");
         skipAnnotations = options.isSet("skipAnnotations");
         warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
         suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
@@ -2482,7 +2481,7 @@
                     warnDeprecated(pos, s);
                 }
             });
-        };
+        }
     }
 
     void checkSunAPI(final DiagnosticPosition pos, final Symbol s) {
--- a/src/share/classes/com/sun/tools/javac/comp/Enter.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java	Tue Dec 13 11:21:28 2011 -0800
@@ -34,7 +34,7 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.jvm.*;
-import com.sun.tools.javac.main.RecognizedOptions.PkgInfo;
+import com.sun.tools.javac.main.Option.PkgInfo;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.util.*;
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Dec 13 11:21:28 2011 -0800
@@ -29,7 +29,7 @@
 
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.jvm.*;
-import com.sun.tools.javac.main.RecognizedOptions.PkgInfo;
+import com.sun.tools.javac.main.Option.PkgInfo;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
--- a/src/share/classes/com/sun/tools/javac/file/Locations.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/file/Locations.java	Tue Dec 13 11:21:28 2011 -0800
@@ -47,14 +47,14 @@
 import javax.tools.StandardLocation;
 
 import com.sun.tools.javac.code.Lint;
-import com.sun.tools.javac.main.OptionName;
+import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Options;
 
 import javax.tools.JavaFileManager;
 import static javax.tools.StandardLocation.*;
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** This class converts command line arguments, environment variables
  *  and system properties (in File.pathSeparator-separated String form)
@@ -318,23 +318,23 @@
      */
     protected abstract class LocationHandler {
         final Location location;
-        final Set<OptionName> options;
+        final Set<Option> options;
 
         /**
          * Create a handler. The location and options provide a way to map
          * from a location or an option to the corresponding handler.
          * @see #initHandlers
          */
-        protected LocationHandler(Location location, OptionName... options) {
+        protected LocationHandler(Location location, Option... options) {
             this.location = location;
             this.options = options.length == 0 ?
-                EnumSet.noneOf(OptionName.class):
+                EnumSet.noneOf(Option.class):
                 EnumSet.copyOf(Arrays.asList(options));
         }
 
         // TODO: TEMPORARY, while Options still used for command line options
         void update(Options optionTable) {
-            for (OptionName o: options) {
+            for (Option o: options) {
                 String v = optionTable.get(o);
                 if (v != null) {
                     handleOption(o, v);
@@ -343,7 +343,7 @@
         }
 
         /** @see JavaFileManager#handleOption. */
-        abstract boolean handleOption(OptionName option, String value);
+        abstract boolean handleOption(Option option, String value);
         /** @see JavaFileManager#getLocation. */
         abstract Collection<File> getLocation();
         /** @see JavaFileManager#setLocation. */
@@ -359,12 +359,12 @@
     private class OutputLocationHandler extends LocationHandler {
         private File outputDir;
 
-        OutputLocationHandler(Location location, OptionName... options) {
+        OutputLocationHandler(Location location, Option... options) {
             super(location, options);
         }
 
         @Override
-        boolean handleOption(OptionName option, String value) {
+        boolean handleOption(Option option, String value) {
             if (!options.contains(option))
                 return false;
 
@@ -410,12 +410,12 @@
     private class SimpleLocationHandler extends LocationHandler {
         protected Collection<File> searchPath;
 
-        SimpleLocationHandler(Location location, OptionName... options) {
+        SimpleLocationHandler(Location location, Option... options) {
             super(location, options);
         }
 
         @Override
-        boolean handleOption(OptionName option, String value) {
+        boolean handleOption(Option option, String value) {
             if (!options.contains(option))
                 return false;
             searchPath = value == null ? null :
@@ -452,7 +452,7 @@
     private class ClassPathLocationHandler extends SimpleLocationHandler {
         ClassPathLocationHandler() {
             super(StandardLocation.CLASS_PATH,
-                    OptionName.CLASSPATH, OptionName.CP);
+                    Option.CLASSPATH, Option.CP);
         }
 
         @Override
@@ -500,7 +500,7 @@
      */
     private class BootClassPathLocationHandler extends LocationHandler {
         private Collection<File> searchPath;
-        final Map<OptionName, String> optionValues = new EnumMap<OptionName,String>(OptionName.class);
+        final Map<Option, String> optionValues = new EnumMap<Option,String>(Option.class);
 
         /**
          * rt.jar as found on the default bootclasspath.
@@ -515,11 +515,11 @@
 
         BootClassPathLocationHandler() {
             super(StandardLocation.PLATFORM_CLASS_PATH,
-                    OptionName.BOOTCLASSPATH, OptionName.XBOOTCLASSPATH,
-                    OptionName.XBOOTCLASSPATH_PREPEND,
-                    OptionName.XBOOTCLASSPATH_APPEND,
-                    OptionName.ENDORSEDDIRS, OptionName.DJAVA_ENDORSED_DIRS,
-                    OptionName.EXTDIRS, OptionName.DJAVA_EXT_DIRS);
+                    Option.BOOTCLASSPATH, Option.XBOOTCLASSPATH,
+                    Option.XBOOTCLASSPATH_PREPEND,
+                    Option.XBOOTCLASSPATH_APPEND,
+                    Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS,
+                    Option.EXTDIRS, Option.DJAVA_EXT_DIRS);
         }
 
         boolean isDefault() {
@@ -533,7 +533,7 @@
         }
 
         @Override
-        boolean handleOption(OptionName option, String value) {
+        boolean handleOption(Option option, String value) {
             if (!options.contains(option))
                 return false;
 
@@ -549,14 +549,14 @@
         // where
             // TODO: would be better if option aliasing was handled at a higher
             // level
-            private OptionName canonicalize(OptionName option) {
+            private Option canonicalize(Option option) {
                 switch (option) {
                     case XBOOTCLASSPATH:
-                        return OptionName.BOOTCLASSPATH;
+                        return Option.BOOTCLASSPATH;
                     case DJAVA_ENDORSED_DIRS:
-                        return OptionName.ENDORSEDDIRS;
+                        return Option.ENDORSEDDIRS;
                     case DJAVA_EXT_DIRS:
-                        return OptionName.EXTDIRS;
+                        return Option.EXTDIRS;
                     default:
                         return option;
                 }
@@ -636,29 +636,29 @@
     }
 
     Map<Location, LocationHandler> handlersForLocation;
-    Map<OptionName, LocationHandler> handlersForOption;
+    Map<Option, LocationHandler> handlersForOption;
 
     void initHandlers() {
         handlersForLocation = new HashMap<Location, LocationHandler>();
-        handlersForOption = new EnumMap<OptionName, LocationHandler>(OptionName.class);
+        handlersForOption = new EnumMap<Option, LocationHandler>(Option.class);
 
         LocationHandler[] handlers = {
             new BootClassPathLocationHandler(),
             new ClassPathLocationHandler(),
-            new SimpleLocationHandler(StandardLocation.SOURCE_PATH, OptionName.SOURCEPATH),
-            new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, OptionName.PROCESSORPATH),
-            new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), OptionName.D),
-            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), OptionName.S)
+            new SimpleLocationHandler(StandardLocation.SOURCE_PATH, Option.SOURCEPATH),
+            new SimpleLocationHandler(StandardLocation.ANNOTATION_PROCESSOR_PATH, Option.PROCESSORPATH),
+            new OutputLocationHandler((StandardLocation.CLASS_OUTPUT), Option.D),
+            new OutputLocationHandler((StandardLocation.SOURCE_OUTPUT), Option.S)
         };
 
         for (LocationHandler h: handlers) {
             handlersForLocation.put(h.location, h);
-            for (OptionName o: h.options)
+            for (Option o: h.options)
                 handlersForOption.put(o, h);
         }
     }
 
-    boolean handleOption(OptionName option, String value) {
+    boolean handleOption(Option option, String value) {
         LocationHandler h = handlersForOption.get(option);
         return (h == null ? false : h.handleOption(option, value));
     }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Dec 13 11:21:28 2011 -0800
@@ -59,7 +59,7 @@
 import static com.sun.tools.javac.jvm.ClassFile.*;
 import static com.sun.tools.javac.jvm.ClassFile.Version.*;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** This class provides operations to read a classfile into an internal
  *  representation. The internal representation is anchored in a
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Dec 13 11:21:28 2011 -0800
@@ -45,7 +45,7 @@
 import static com.sun.tools.javac.code.Kinds.*;
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.jvm.UninitializedType.*;
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 
 
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Dec 13 11:21:28 2011 -0800
@@ -45,7 +45,7 @@
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.jvm.ByteCodes.*;
 import static com.sun.tools.javac.jvm.CRTFlags.*;
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.BLOCK;
 
--- a/src/share/classes/com/sun/tools/javac/jvm/Target.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/Target.java	Tue Dec 13 11:21:28 2011 -0800
@@ -31,7 +31,7 @@
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.util.*;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** The classfile version target.
  *
--- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Dec 13 11:21:28 2011 -0800
@@ -62,7 +62,7 @@
 import com.sun.tools.javac.util.Log.WriterKind;
 
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
 import static com.sun.tools.javac.util.ListBuffer.lb;
 
@@ -817,8 +817,8 @@
 
         // forcibly set the equivalent of -Xlint:-options, so that no further
         // warnings about command line options are generated from this point on
-        options.put(XLINT_CUSTOM + "-" + LintCategory.OPTIONS.option, "true");
-        options.remove(XLINT_CUSTOM + LintCategory.OPTIONS.option);
+        options.put(XLINT_CUSTOM.text + "-" + LintCategory.OPTIONS.option, "true");
+        options.remove(XLINT_CUSTOM.text + LintCategory.OPTIONS.option);
 
         start_msec = now();
 
--- a/src/share/classes/com/sun/tools/javac/main/Main.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/main/Main.java	Tue Dec 13 11:21:28 2011 -0800
@@ -42,14 +42,12 @@
 import com.sun.tools.javac.file.CacheFSInfo;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.jvm.Target;
-import com.sun.tools.javac.main.JavacOption.Option;
-import com.sun.tools.javac.main.RecognizedOptions.OptionHelper;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.Log.WriterKind;
 import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** This class provides a commandline interface to the GJC compiler.
  *
@@ -99,42 +97,51 @@
         public final int exitCode;
     }
 
-    private Option[] recognizedOptions = RecognizedOptions.getJavaCompilerOptions(new OptionHelper() {
+    private Option[] recognizedOptions =
+            Option.getJavaCompilerOptions().toArray(new Option[0]);
 
-        public void setOut(PrintWriter out) {
-            Main.this.out = out;
-            Main.this.log.setWriters(out);
+    private OptionHelper optionHelper = new OptionHelper() {
+        @Override
+        public String get(Option option) {
+            return options.get(option);
+        }
+
+        @Override
+        public void put(String name, String value) {
+            options.put(name, value);
         }
 
+        @Override
+        public void remove(String name) {
+            options.remove(name);
+        }
+
+        @Override
+        public Log getLog() {
+            return log;
+        }
+
+        @Override
+        public String getOwnName() {
+            return ownName;
+        }
+
+        @Override
         public void error(String key, Object... args) {
             Main.this.error(key, args);
         }
 
-        public void printVersion() {
-            log.printLines(PrefixKind.JAVAC, "version", ownName,  JavaCompiler.version());
-        }
-
-        public void printFullVersion() {
-            log.printLines(PrefixKind.JAVAC, "fullVersion", ownName,  JavaCompiler.fullVersion());
-        }
-
-        public void printHelp() {
-            help();
-        }
-
-        public void printXhelp() {
-            xhelp();
-        }
-
+        @Override
         public void addFile(File f) {
             filenames.add(f);
         }
 
+        @Override
         public void addClassName(String s) {
             classnames.append(s);
         }
 
-    });
+    };
 
     /**
      * Construct a compiler instance.
@@ -161,26 +168,6 @@
      */
     public ListBuffer<String> classnames = null; // XXX sb protected
 
-    /** Print a string that explains usage.
-     */
-    void help() {
-        log.printLines(PrefixKind.JAVAC, "msg.usage.header", ownName);
-        for (int i=0; i<recognizedOptions.length; i++) {
-            recognizedOptions[i].help(log);
-        }
-        log.printNewline();
-    }
-
-    /** Print a string that explains usage for X options.
-     */
-    void xhelp() {
-        for (int i=0; i<recognizedOptions.length; i++) {
-            recognizedOptions[i].xhelp(log);
-        }
-        log.printNewline();
-        log.printLines(PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
-    }
-
     /** Report a usage error.
      */
     void error(String key, Object... args) {
@@ -253,10 +240,10 @@
                 }
                 String operand = flags[ac];
                 ac++;
-                if (option.process(options, flag, operand))
+                if (option.process(optionHelper, flag, operand))
                     return null;
             } else {
-                if (option.process(options, flag))
+                if (option.process(optionHelper, flag))
                     return null;
             }
         }
@@ -317,8 +304,8 @@
         return filenames;
     }
     // where
-        private boolean checkDirectory(OptionName optName) {
-            String value = options.get(optName);
+        private boolean checkDirectory(Option option) {
+            String value = options.get(option);
             if (value == null)
                 return true;
             File file = new File(value);
@@ -375,7 +362,7 @@
          */
         try {
             if (args.length == 0 && fileObjects.isEmpty()) {
-                help();
+                Option.HELP.process(optionHelper, "-help");
                 return Result.CMDERR;
             }
 
@@ -407,8 +394,7 @@
             boolean forceStdOut = options.isSet("stdout");
             if (forceStdOut) {
                 log.flush();
-                out = new PrintWriter(System.out, true);
-                log.setWriters(out);
+                log.setWriters(new PrintWriter(System.out, true));
             }
 
             // allow System property in following line as a Mustang legacy
--- a/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java	Tue Dec 13 11:21:28 2011 -0800
@@ -63,7 +63,7 @@
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 
 // NOTE the imports carefully for this compilation unit.
--- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Tue Dec 13 11:21:28 2011 -0800
@@ -82,7 +82,7 @@
 
 import static javax.tools.StandardLocation.*;
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag.*;
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 import static com.sun.tools.javac.code.Lint.LintCategory.PROCESSING;
 
 /**
--- a/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Tue Dec 13 11:21:28 2011 -0800
@@ -46,6 +46,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 import javax.tools.JavaFileObject;
 import javax.tools.JavaFileObject.Kind;
 
@@ -53,9 +54,9 @@
 import com.sun.tools.javac.code.Source;
 import com.sun.tools.javac.file.FSInfo;
 import com.sun.tools.javac.file.Locations;
-import com.sun.tools.javac.main.JavacOption;
-import com.sun.tools.javac.main.OptionName;
-import com.sun.tools.javac.main.RecognizedOptions;
+import com.sun.tools.javac.main.Option;
+import com.sun.tools.javac.main.OptionHelper;
+import com.sun.tools.javac.main.OptionHelper.GrumpyHelper;
 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
 
 /**
@@ -101,7 +102,7 @@
     protected Locations locations;
 
     protected Source getSource() {
-        String sourceName = options.get(OptionName.SOURCE);
+        String sourceName = options.get(Option.SOURCE);
         Source source = null;
         if (sourceName != null)
             source = Source.lookup(sourceName);
@@ -145,15 +146,31 @@
 
     // <editor-fold defaultstate="collapsed" desc="Option handling">
     public boolean handleOption(String current, Iterator<String> remaining) {
-        for (JavacOption o: javacFileManagerOptions) {
+        OptionHelper helper = new GrumpyHelper(log) {
+            @Override
+            public String get(Option option) {
+                return options.get(option.getText());
+            }
+
+            @Override
+            public void put(String name, String value) {
+                options.put(name, value);
+            }
+
+            @Override
+            public void remove(String name) {
+                options.remove(name);
+            }
+        };
+        for (Option o: javacFileManagerOptions) {
             if (o.matches(current))  {
                 if (o.hasArg()) {
                     if (remaining.hasNext()) {
-                        if (!o.process(options, current, remaining.next()))
+                        if (!o.process(helper, current, remaining.next()))
                             return true;
                     }
                 } else {
-                    if (!o.process(options, current))
+                    if (!o.process(helper, current))
                         return true;
                 }
                 // operand missing, or process returned false
@@ -164,12 +181,11 @@
         return false;
     }
     // where
-        private static JavacOption[] javacFileManagerOptions =
-            RecognizedOptions.getJavacFileManagerOptions(
-            new RecognizedOptions.GrumpyHelper(Log.instance(new Context())));
+        private static Set<Option> javacFileManagerOptions =
+            Option.getJavacFileManagerOptions();
 
     public int isSupportedOption(String option) {
-        for (JavacOption o : javacFileManagerOptions) {
+        for (Option o : javacFileManagerOptions) {
             if (o.matches(option))
                 return o.hasArg() ? 1 : 0;
         }
@@ -191,7 +207,7 @@
     }
 
     public String getEncodingName() {
-        String encName = options.get(OptionName.ENCODING);
+        String encName = options.get(Option.ENCODING);
         if (encName == null)
             return getDefaultEncodingName();
         else
--- a/src/share/classes/com/sun/tools/javac/util/Log.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/util/Log.java	Tue Dec 13 11:21:28 2011 -0800
@@ -25,25 +25,23 @@
 
 package com.sun.tools.javac.util;
 
-import com.sun.tools.javac.main.Main;
 import java.io.*;
 import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Queue;
 import java.util.Set;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
-import com.sun.tools.javac.main.OptionName;
+import com.sun.tools.javac.main.Main;
+import com.sun.tools.javac.main.Option;
 import com.sun.tools.javac.parser.EndPosTable;
-import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
 
-import static com.sun.tools.javac.main.OptionName.*;
+import static com.sun.tools.javac.main.Option.*;
 
 /** A class for error logs. Reports errors and warnings, and
  *  keeps track of error numbers and positions.
@@ -179,8 +177,8 @@
                 expectDiagKeys = new HashSet<String>(Arrays.asList(ek.split(", *")));
         }
 
-        private int getIntOption(Options options, OptionName optionName, int defaultValue) {
-            String s = options.get(optionName);
+        private int getIntOption(Options options, Option option, int defaultValue) {
+            String s = options.get(option);
             try {
                 if (s != null) {
                     int n = Integer.parseInt(s);
--- a/src/share/classes/com/sun/tools/javac/util/Options.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/util/Options.java	Tue Dec 13 11:21:28 2011 -0800
@@ -26,8 +26,8 @@
 package com.sun.tools.javac.util;
 
 import java.util.*;
-import com.sun.tools.javac.main.OptionName;
-import static com.sun.tools.javac.main.OptionName.*;
+import com.sun.tools.javac.main.Option;
+import static com.sun.tools.javac.main.Option.*;
 
 /** A table of all command-line options.
  *  If an option has an argument, the option name is mapped to the argument.
@@ -71,8 +71,8 @@
     /**
      * Get the value for an option.
      */
-    public String get(OptionName name) {
-        return values.get(name.optionName);
+    public String get(Option option) {
+        return values.get(option.text);
     }
 
     /**
@@ -101,15 +101,15 @@
     /**
      * Check if the value for an option has been set.
      */
-    public boolean isSet(OptionName name) {
-        return (values.get(name.optionName) != null);
+    public boolean isSet(Option option) {
+        return (values.get(option.text) != null);
     }
 
     /**
      * Check if the value for a choice option has been set to a specific value.
      */
-    public boolean isSet(OptionName name, String value) {
-        return (values.get(name.optionName + value) != null);
+    public boolean isSet(Option option, String value) {
+        return (values.get(option.text + value) != null);
     }
 
     /**
@@ -122,23 +122,23 @@
     /**
      * Check if the value for an option has not been set.
      */
-    public boolean isUnset(OptionName name) {
-        return (values.get(name.optionName) == null);
+    public boolean isUnset(Option option) {
+        return (values.get(option.text) == null);
     }
 
     /**
      * Check if the value for a choice option has not been set to a specific value.
      */
-    public boolean isUnset(OptionName name, String value) {
-        return (values.get(name.optionName + value) == null);
+    public boolean isUnset(Option option, String value) {
+        return (values.get(option.text + value) == null);
     }
 
     public void put(String name, String value) {
         values.put(name, value);
     }
 
-    public void put(OptionName name, String value) {
-        values.put(name.optionName, value);
+    public void put(Option option, String value) {
+        values.put(option.text, value);
     }
 
     public void putAll(Options options) {
--- a/test/tools/javac/diags/examples/UnsupportedEncoding.java	Mon Dec 12 08:15:32 2011 -0800
+++ b/test/tools/javac/diags/examples/UnsupportedEncoding.java	Tue Dec 13 11:21:28 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2011, 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
@@ -23,5 +23,6 @@
 
 // key: compiler.err.unsupported.encoding
 // options: -encoding UNSUPPORTED -doe
+// run: simple
 
 class UnsupportedEncoding { }