The current solution of passing a bunch of boolean parameters around is getting unwieldy.  I've refactored all this stuff out into a class to encapsulate the compiler options.  Then when we add new options, we can do so with a minimal amount of code.

Additionally, people developing external tools that invoke GWT, such as IDE plugins, will have a stable API to work against, and we can add more options in a backwards-compatible way.

Review by: bobv


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1646 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
index 55935c5..d851ff8 100644
--- a/dev/core/src/com/google/gwt/dev/GWTCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
@@ -35,6 +35,8 @@
 import com.google.gwt.dev.jdt.RebindPermutationOracle;
 import com.google.gwt.dev.jdt.StandardSourceOracle;
 import com.google.gwt.dev.jdt.WebModeCompilerFrontEnd;
+import com.google.gwt.dev.jjs.JJSOptions;
+import com.google.gwt.dev.jjs.JsOutputOption;
 import com.google.gwt.dev.jjs.JavaToJavaScriptCompiler;
 import com.google.gwt.dev.shell.StandardRebindOracle;
 import com.google.gwt.dev.util.DefaultTextOutput;
@@ -119,7 +121,7 @@
     }
 
     public boolean setFlag() {
-      validateOnly = true;
+      jjsOptions.setValidateOnly(true);
       return true;
     }
   }
@@ -267,24 +269,20 @@
 
   private Map<String, List<JClassType>> generatedTypesByResultTypeName = new HashMap<String, List<JClassType>>();
 
-  private boolean aggressivelyOptimize = true;
-
   private JavaToJavaScriptCompiler jjs;
 
+  private JJSOptions jjsOptions = new JJSOptions();
+
   private Type logLevel;
 
   private ModuleDef module;
 
   private String moduleName;
 
-  private boolean obfuscate;
-
   private File outDir;
 
   private PropertyPermutations perms;
 
-  private boolean prettyNames;
-
   private Properties properties;
 
   private StaticPropertyOracle propOracle = new StaticPropertyOracle();
@@ -299,8 +297,6 @@
 
   private boolean useGuiLogger;
 
-  private boolean validateOnly = false;
-
   public GWTCompiler() {
     this(null);
   }
@@ -337,22 +333,7 @@
 
     registerHandler(new ArgHandlerModuleName());
 
-    registerHandler(new ArgHandlerScriptStyle() {
-      @Override
-      public void setStyleDetailed() {
-        GWTCompiler.this.setStyleDetailed();
-      }
-
-      @Override
-      public void setStyleObfuscated() {
-        GWTCompiler.this.setStyleObfuscated();
-      }
-
-      @Override
-      public void setStylePretty() {
-        GWTCompiler.this.setStylePretty();
-      }
-    });
+    registerHandler(new ArgHandlerScriptStyle(jjsOptions));
 
     registerHandler(new ArgHandlerDisableAggressiveOptimization() {
       @Override
@@ -380,7 +361,7 @@
     rules = module.getRules();
     typeOracle = module.getTypeOracle(logger);
     sourceOracle = new StandardSourceOracle(typeOracle);
-    if (validateOnly) {
+    if (jjsOptions.isValidateOnly()) {
       // Pretend that every single compilation unit is an entry point.
       CompilationUnitProvider[] compilationUnits = module.getCompilationUnits();
       declEntryPts = new String[compilationUnits.length];
@@ -398,9 +379,9 @@
     WebModeCompilerFrontEnd frontEnd = new WebModeCompilerFrontEnd(
         sourceOracle, rebindPermOracle);
     jjs = new JavaToJavaScriptCompiler(logger, frontEnd, declEntryPts,
-        obfuscate, prettyNames, aggressivelyOptimize, validateOnly);
+        jjsOptions);
 
-    if (!validateOnly) {
+    if (!jjsOptions.isValidateOnly()) {
       /*
        * See what permutations already exist on disk and are up to date. Skip
        * this for validation mode since we want to recompile everything.
@@ -412,7 +393,7 @@
     //
     SelectionScriptGenerator selGen = compilePermutations(logger);
 
-    if (validateOnly) {
+    if (jjsOptions.isValidateOnly()) {
       logger.log(TreeLogger.INFO, "Validation succeeded", null);
       return;
     }
@@ -445,7 +426,11 @@
   }
 
   public void setAggressivelyOptimize(boolean aggressive) {
-    aggressivelyOptimize = aggressive;
+    jjsOptions.setAggressivelyOptimize(aggressive);
+  }
+
+  public void setCompilerOptions(JJSOptions options) {
+    jjsOptions.copyFrom(options);
   }
 
   public void setGenDir(File dir) {
@@ -465,24 +450,23 @@
   }
 
   public void setStyleDetailed() {
-    obfuscate = false;
-    prettyNames = false;
+    jjsOptions.setOutput(JsOutputOption.DETAILED);
   }
 
   public void setStyleObfuscated() {
-    obfuscate = true;
+    jjsOptions.setOutput(JsOutputOption.OBFUSCATED);
   }
 
   public void setStylePretty() {
-    obfuscate = false;
-    prettyNames = true;
+    jjsOptions.setOutput(JsOutputOption.PRETTY);
   }
 
   /**
    * Ensure the module has at least one entry point (except in validation mode).
    */
   private void checkModule(TreeLogger logger) throws UnableToCompleteException {
-    if (!validateOnly && module.getEntryPointTypeNames().length == 0) {
+    if (!jjsOptions.isValidateOnly()
+        && module.getEntryPointTypeNames().length == 0) {
       logger.log(TreeLogger.ERROR, "Module has no entry points defined", null);
       throw new UnableToCompleteException();
     }
@@ -490,7 +474,7 @@
 
   private SelectionScriptGenerator compilePermutations(TreeLogger logger)
       throws UnableToCompleteException {
-    if (validateOnly) {
+    if (jjsOptions.isValidateOnly()) {
       logger = logger.branch(TreeLogger.INFO, "Validating compilation", null);
     } else {
       logger = logger.branch(TreeLogger.INFO, "Compiling into " + outDir, null);
@@ -504,7 +488,9 @@
       String[] orderedPropValues = iter.next();
       String strongName = realizePermutation(logger, orderedProps,
           orderedPropValues, permNumber);
-      selGen.recordSelection(orderedPropValues, strongName);
+      if (!jjsOptions.isValidateOnly()) {
+        selGen.recordSelection(orderedPropValues, strongName);
+      }
     }
     return selGen;
   }
@@ -536,7 +522,8 @@
   }
 
   private String getHtmlPrefix() {
-    DefaultTextOutput out = new DefaultTextOutput(obfuscate);
+    DefaultTextOutput out = new DefaultTextOutput(
+        jjsOptions.getOutput().shouldMinimize());
     out.print("<html>");
     out.newlineOpt();
 
@@ -565,7 +552,8 @@
   }
 
   private String getHtmlSuffix() {
-    DefaultTextOutput out = new DefaultTextOutput(obfuscate);
+    DefaultTextOutput out = new DefaultTextOutput(
+        jjsOptions.getOutput().shouldMinimize());
     String moduleFunction = module.getName().replace('.', '_');
 
     // Generate the call to tell the bootstrap code that we're ready to go.
@@ -580,7 +568,8 @@
   }
 
   private String getJsPrefix() {
-    DefaultTextOutput out = new DefaultTextOutput(obfuscate);
+    DefaultTextOutput out = new DefaultTextOutput(
+        jjsOptions.getOutput().shouldMinimize());
 
     out.print("(function(){");
     out.newlineOpt();
@@ -600,7 +589,8 @@
   }
 
   private String getJsSuffix() {
-    DefaultTextOutput out = new DefaultTextOutput(obfuscate);
+    DefaultTextOutput out = new DefaultTextOutput(
+        jjsOptions.getOutput().shouldMinimize());
     String moduleFunction = module.getName().replace('.', '_');
 
     // Generate the call to tell the bootstrap code that we're ready to go.
@@ -784,7 +774,7 @@
     // Create JavaScript.
     //
     String js = jjs.compile(logger, rebindOracle);
-    if (validateOnly) {
+    if (jjsOptions.isValidateOnly()) {
       // We're done, there's no actual script to write.
       assert (js == null);
       return null;
@@ -989,7 +979,8 @@
   private void writeSelectionScripts(TreeLogger logger,
       SelectionScriptGenerator selGen) {
     {
-      String html = selGen.generateSelectionScript(obfuscate, false);
+      String html = selGen.generateSelectionScript(
+          jjsOptions.getOutput().shouldMinimize(), false);
       String fn = module.getName() + ".nocache.js";
       File selectionFile = new File(outDir, fn);
       Util.writeStringAsFile(selectionFile, html);
@@ -998,7 +989,8 @@
       logger.log(TreeLogger.TRACE, msg, null);
     }
     {
-      String html = selGen.generateSelectionScript(obfuscate, true);
+      String html = selGen.generateSelectionScript(
+          jjsOptions.getOutput().shouldMinimize(), true);
       String fn = module.getName() + "-xs.nocache.js";
       File selectionFile = new File(outDir, fn);
       Util.writeStringAsFile(selectionFile, html);
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index d07d08d..10c80a5 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -21,6 +21,7 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.cfg.ModuleDefLoader;
+import com.google.gwt.dev.jjs.JJSOptions;
 import com.google.gwt.dev.shell.BrowserWidget;
 import com.google.gwt.dev.shell.BrowserWidgetHost;
 import com.google.gwt.dev.shell.BrowserWidgetHostChecker;
@@ -372,8 +373,6 @@
 
   protected File outDir;
 
-  private boolean aggressivelyOptimize = true;
-
   private BrowserWidgetHostImpl browserHost = new BrowserWidgetHostImpl();
 
   private final List<Shell> browserShells = new ArrayList<Shell>();
@@ -382,16 +381,14 @@
 
   private boolean headlessMode = false;
 
+  private final JJSOptions jjsOptions = new JJSOptions();
+
   private TreeLogger.Type logLevel;
 
   private ShellMainWindow mainWnd;
 
-  private boolean obfuscate;
-
   private int port;
 
-  private boolean prettyNames;
-
   private boolean runTomcat = true;
 
   private boolean saveJsni = false;
@@ -447,29 +444,12 @@
       }
     });
 
-    registerHandler(new ArgHandlerScriptStyle() {
-      @Override
-      public void setStyleDetailed() {
-        obfuscate = false;
-        prettyNames = false;
-      }
-
-      @Override
-      public void setStyleObfuscated() {
-        obfuscate = true;
-      }
-
-      @Override
-      public void setStylePretty() {
-        obfuscate = false;
-        prettyNames = true;
-      }
-    });
+    registerHandler(new ArgHandlerScriptStyle(jjsOptions));
 
     registerHandler(new ArgHandlerDisableAggressiveOptimization() {
       @Override
       public boolean setFlag() {
-        GWTShell.this.setAggressivelyOptimize(false);
+        jjsOptions.setAggressivelyOptimize(false);
         return true;
       }
     });
@@ -620,8 +600,8 @@
     }
   }
 
-  public void setAggressivelyOptimize(boolean optimize) {
-    this.aggressivelyOptimize = optimize;
+  public void setCompilerOptions(JJSOptions options) {
+    jjsOptions.copyFrom(options);
   }
 
   public void setGenDir(File genDir) {
@@ -652,18 +632,11 @@
   protected void compile(TreeLogger logger, ModuleDef moduleDef)
       throws UnableToCompleteException {
     GWTCompiler compiler = new GWTCompiler(moduleDef.getCacheManager());
-    compiler.setAggressivelyOptimize(aggressivelyOptimize);
+    compiler.setCompilerOptions(jjsOptions);
     compiler.setGenDir(genDir);
     compiler.setOutDir(outDir);
     compiler.setModuleName(moduleDef.getName());
     compiler.setLogLevel(logLevel);
-    if (obfuscate) {
-      compiler.setStyleObfuscated();
-    } else if (prettyNames) {
-      compiler.setStylePretty();
-    } else {
-      compiler.setStyleDetailed();
-    }
     compiler.distill(logger, moduleDef);
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
new file mode 100644
index 0000000..879e1d5
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs;
+
+/**
+ * Controls options for the {@link JavaToJavaScriptCompiler}.
+ */
+public class JJSOptions {
+
+  private boolean aggressivelyOptimize = true;
+  private JsOutputOption output = JsOutputOption.OBFUSCATED;
+  private boolean validateOnly = false;
+
+  public JJSOptions() {
+  }
+
+  public JJSOptions(JJSOptions other) {
+    copyFrom(other);
+  }
+
+  public void copyFrom(JJSOptions other) {
+    this.aggressivelyOptimize = other.aggressivelyOptimize;
+    this.output = other.output;
+    this.validateOnly = other.validateOnly;
+  }
+
+  /**
+   * Returns the output format setting.
+   */
+  public JsOutputOption getOutput() {
+    return output;
+  }
+
+  /**
+   * Returns true if the compiler should aggressively optimize.
+   */
+  public boolean isAggressivelyOptimize() {
+    return aggressivelyOptimize;
+  }
+
+  /**
+   * Returns true if the compiler should run in validation mode, not producing
+   * any output.
+   */
+  public boolean isValidateOnly() {
+    return validateOnly;
+  }
+
+  /**
+   * Sets whether or not the compiler should aggressively optimize.
+   */
+  public void setAggressivelyOptimize(boolean aggressivelyOptimize) {
+    this.aggressivelyOptimize = aggressivelyOptimize;
+  }
+
+  /**
+   * Sets the compiler output option.
+   */
+  public void setOutput(JsOutputOption output) {
+    this.output = output;
+  }
+
+  /**
+   * Sets whether or not the compiler should run in validation mode.
+   */
+  public void setValidateOnly(boolean validateOnly) {
+    this.validateOnly = validateOnly;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 405d244..512fe02 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -197,45 +197,33 @@
     return null;
   }
 
-  private final boolean aggressivelyOptimize;
   private final String[] declEntryPoints;
   private final CompilationUnitDeclaration[] goldenCuds;
   private long lastModified;
-  private final boolean obfuscate;
-  private final boolean prettyNames;
+  private final JJSOptions options;
   private final Set<IProblem> problemSet = new HashSet<IProblem>();
-  private boolean validateOnly;
 
   public JavaToJavaScriptCompiler(TreeLogger logger,
       WebModeCompilerFrontEnd compiler, String[] declEntryPts)
       throws UnableToCompleteException {
-    this(logger, compiler, declEntryPts, true, false, true, false);
+    this(logger, compiler, declEntryPts, new JJSOptions());
   }
 
   public JavaToJavaScriptCompiler(TreeLogger logger,
       WebModeCompilerFrontEnd compiler, String[] declEntryPts,
-      boolean obfuscate, boolean prettyNames, boolean aggressivelyOptimize,
-      boolean validateOnly) throws UnableToCompleteException {
+      JJSOptions compilerOptions) throws UnableToCompleteException {
 
     if (declEntryPts.length == 0) {
       throw new IllegalArgumentException("entry point(s) required");
     }
 
-    // Should we attempt to inline Java and JavaScript methods?
-    //
-    this.aggressivelyOptimize = aggressivelyOptimize;
+    this.options = new JJSOptions(compilerOptions);
 
     // Remember these for subsequent compiles.
     //
     this.declEntryPoints = declEntryPts;
 
-    // Should we obfuscate or, if not, use pretty names?
-    //
-    this.obfuscate = obfuscate;
-    this.prettyNames = prettyNames;
-    this.validateOnly = validateOnly;
-
-    if (!validateOnly) {
+    if (!options.isValidateOnly()) {
       // Find all the possible rebound entry points.
       RebindPermutationOracle rpo = compiler.getRebindPermutationOracle();
       Set<String> allEntryPoints = new TreeSet<String>();
@@ -329,7 +317,7 @@
       // Fix up GWT.create() into new operations
       ReplaceRebinds.exec(jprogram);
 
-      if (validateOnly) {
+      if (options.isValidateOnly()) {
         // That's it, we're done.
         return null;
       }
@@ -366,7 +354,7 @@
         // dead code removal??
         didChange = DeadCodeElimination.exec(jprogram) || didChange;
 
-        if (aggressivelyOptimize) {
+        if (options.isAggressivelyOptimize()) {
           // inlining
           didChange = MethodInliner.exec(jprogram) || didChange;
         }
@@ -392,7 +380,7 @@
 
       // (7) Generate a JavaScript code DOM from the Java type declarations
       jprogram.typeOracle.recomputeClinits();
-      GenerateJavaScriptAST.exec(jprogram, jsProgram, obfuscate, prettyNames);
+      GenerateJavaScriptAST.exec(jprogram, jsProgram, options.getOutput());
 
       // (8) Fix invalid constructs created during JS AST gen
       JsNormalizer.exec(jsProgram);
@@ -401,30 +389,37 @@
       JsSymbolResolver.exec(jsProgram);
 
       // (10) Apply optimizations to JavaScript AST
-      if (aggressivelyOptimize) {
+      if (options.isAggressivelyOptimize()) {
         do {
           didChange = false;
           // Inline JavaScript function invocations
-          didChange = aggressivelyOptimize && JsInliner.exec(jsProgram)
-              || didChange;
+          didChange = options.isAggressivelyOptimize()
+              && JsInliner.exec(jsProgram) || didChange;
           // Remove unused functions, possible
           didChange = JsUnusedFunctionRemover.exec(jsProgram) || didChange;
         } while (didChange);
       }
 
       // (11) Obfuscate
-      if (obfuscate) {
-        JsStringInterner.exec(jsProgram);
-        JsObfuscateNamer.exec(jsProgram);
-      } else if (prettyNames) {
-        // We don't intern strings in pretty mode to improve readability
-        JsPrettyNamer.exec(jsProgram);
-      } else {
-        JsStringInterner.exec(jsProgram);
-        JsVerboseNamer.exec(jsProgram);
+      switch (options.getOutput()) {
+        case OBFUSCATED:
+          JsStringInterner.exec(jsProgram);
+          JsObfuscateNamer.exec(jsProgram);
+          break;
+        case PRETTY:
+          // We don't intern strings in pretty mode to improve readability
+          JsPrettyNamer.exec(jsProgram);
+          break;
+        case DETAILED:
+          JsStringInterner.exec(jsProgram);
+          JsVerboseNamer.exec(jsProgram);
+          break;
+        default:
+          throw new InternalCompilerException("Unknown output mode");
       }
 
-      DefaultTextOutput out = new DefaultTextOutput(obfuscate);
+      DefaultTextOutput out = new DefaultTextOutput(
+          options.getOutput().shouldMinimize());
       JsSourceGenerationVisitor v = new JsSourceGenerationVisitor(out);
       v.accept(jsProgram);
       return out.toString();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JsOutputOption.java b/dev/core/src/com/google/gwt/dev/jjs/JsOutputOption.java
new file mode 100644
index 0000000..f89a3d0
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/jjs/JsOutputOption.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs;
+
+/**
+ * Possibly options for JavaScript output format.
+ */
+public enum JsOutputOption {
+  /**
+   * Formatted output with huge but unambiguous identifiers.
+   */
+  DETAILED,
+  /**
+   * Compressed output, using tiny unreadable identifiers (default).
+   */
+  OBFUSCATED,
+  /**
+   * Formatted output with human-readable identifiers.
+   */
+  PRETTY;
+
+  public boolean shouldMinimize() {
+    return this == OBFUSCATED;
+  }
+}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index b06740c..fc42d01 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.jjs.impl;
 
 import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.jjs.JsOutputOption;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 import com.google.gwt.dev.jjs.ast.HasName;
@@ -1550,10 +1551,9 @@
     }
   }
 
-  public static void exec(JProgram program, JsProgram jsProgram,
-      boolean obfuscate, boolean prettyNames) {
+  public static void exec(JProgram program, JsProgram jsProgram, JsOutputOption output) {
     GenerateJavaScriptAST generateJavaScriptAST = new GenerateJavaScriptAST(
-        program, jsProgram, obfuscate, prettyNames);
+        program, jsProgram, output);
     generateJavaScriptAST.execImpl();
   }
 
@@ -1616,19 +1616,17 @@
   private final JsScope topScope;
 
   private final JTypeOracle typeOracle;
-  private final boolean obfuscate;
-  private final boolean prettyNames;
+  private final JsOutputOption output;
 
   private GenerateJavaScriptAST(JProgram program, JsProgram jsProgram,
-      boolean obfuscate, boolean prettyNames) {
+      JsOutputOption output) {
     this.program = program;
     typeOracle = program.typeOracle;
     this.jsProgram = jsProgram;
     topScope = jsProgram.getScope();
     objectScope = jsProgram.getObjectScope();
     interfaceScope = new JsScope(objectScope, "Interfaces");
-    this.obfuscate = obfuscate;
-    this.prettyNames = prettyNames;
+    this.output = output;
 
     /*
      * Because we modify String's prototype, all fields and polymorphic methods
@@ -1722,24 +1720,28 @@
 
   String mangleNameSpecialObfuscate(JField x) {
     assert (specialObfuscatedIdents.containsKey(x.getName()));
-    if (obfuscate) {
-      return specialObfuscatedIdents.get(x.getName());
-    } else if (prettyNames) {
-      return x.getName() + "$";
-    } else {
-      return mangleName(x) + "$";
+    switch (output) {
+      case OBFUSCATED:
+        return specialObfuscatedIdents.get(x.getName());
+      case PRETTY:
+        return x.getName() + "$";
+      case DETAILED:
+        return mangleName(x) + "$";
     }
+    throw new InternalCompilerException("Unknown output mode");
   }
 
   String mangleNameSpecialObfuscate(JMethod x) {
     assert (specialObfuscatedIdents.containsKey(x.getName()));
-    if (obfuscate) {
-      return specialObfuscatedIdents.get(x.getName());
-    } else if (prettyNames) {
-      return x.getName() + "$";
-    } else {
-      return mangleNameForPoly(x) + "$";
+    switch (output) {
+      case OBFUSCATED:
+        return specialObfuscatedIdents.get(x.getName());
+      case PRETTY:
+        return x.getName() + "$";
+      case DETAILED:
+        return mangleNameForPoly(x) + "$";
     }
+    throw new InternalCompilerException("Unknown output mode");
   }
 
   private void execImpl() {
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
index eb2f91c..fff73c9 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerScriptStyle.java
@@ -15,15 +15,23 @@
  */
 package com.google.gwt.dev.util.arg;
 
+import com.google.gwt.dev.jjs.JJSOptions;
+import com.google.gwt.dev.jjs.JsOutputOption;
 import com.google.gwt.util.tools.ArgHandler;
 
 /**
  * Argument handler for processing the script style flag.
  */
-public abstract class ArgHandlerScriptStyle extends ArgHandler {
+public final class ArgHandlerScriptStyle extends ArgHandler {
+
+  private final JJSOptions optionsToModify;
+
+  public ArgHandlerScriptStyle(JJSOptions optionsToModify) {
+    this.optionsToModify = optionsToModify;
+  }
 
   public String[] getDefaultArgs() {
-    return new String[]{"-style", "obfuscate"};
+    return new String[] {"-style", "obfuscate"};
   }
 
   public String getPurpose() {
@@ -35,20 +43,20 @@
   }
 
   public String[] getTagArgs() {
-    return new String[]{"style"};
+    return new String[] {"style"};
   }
 
   public int handle(String[] args, int startIndex) {
     if (startIndex + 1 < args.length) {
       String style = args[startIndex + 1].toLowerCase();
       if (style.startsWith("obf")) {
-        setStyleObfuscated();
+        optionsToModify.setOutput(JsOutputOption.OBFUSCATED);
         return 1;
       } else if ("pretty".equals(style)) {
-        setStylePretty();
+        optionsToModify.setOutput(JsOutputOption.PRETTY);
         return 1;
       } else if ("detailed".equals(style)) {
-        setStyleDetailed();
+        optionsToModify.setOutput(JsOutputOption.DETAILED);
         return 1;
       }
     }
@@ -57,10 +65,4 @@
     System.err.println("  OBF, PRETTY, or DETAILED");
     return -1;
   }
-
-  public abstract void setStyleDetailed();
-
-  public abstract void setStyleObfuscated();
-
-  public abstract void setStylePretty();
 }
\ No newline at end of file