I don't believe in magic, but as Scott points out, there are consistent
uses of the term to mean "compiler substitution of types", specifically
in java.lang.String and com.google.gwt.util.*.  I took a stab at replacing
the word "magic" in some other contexts where I think different terminology
makes the comments or names clearer.

A grey area is the com.google.gwt.core.GWT class.  Some of its methods are
re-written by the compiler, but in a way that is pretty clearly documented
and not as behind the scenes as the other uses.

Review at http://gwt-code-reviews.appspot.com/1453804


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10303 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java b/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
index 3daf323..d555625 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/AbstractCompiler.java
@@ -242,8 +242,9 @@
         TreeLogger branch =
             logger.branch(TreeLogger.SPAM, "Scanning for additional dependencies: " + loc, null);
 
-        // Examine the cud for magic types.
-        //
+        // Examine the cud for types outside of the flow of the original Java 
+        // source.
+        // 
         String[] typeNames = outer.doFindAdditionalTypesUsingJsni(branch, unit);
         addAdditionalTypes(branch, typeNames);
 
@@ -266,9 +267,9 @@
       }
 
       /**
-       * Helper method for process() that receives the types found by magic.
-       * This causes the compiler to find the additional type, possibly winding
-       * its back to ask for the compilation unit from the source oracle.
+       * Helper method for process() that receives the types found outside the
+       * flow of the original Java source. This causes the compiler to find the
+       * additional type, possibly causing the type to be compiled from source.
        */
       private void addAdditionalTypes(TreeLogger logger, String[] typeNames) {
         for (String typeName : typeNames) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CastNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CastNormalizer.java
index 9a41672..85bc2b6 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CastNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CastNormalizer.java
@@ -431,17 +431,20 @@
       }
       SourceInfo info = x.getSourceInfo();
       if (toType instanceof JNullType) {
-        /*
-         * Magic: a null type cast means the user tried a cast that couldn't
-         * possibly work. Typically this means either the statically resolvable
-         * arg type is incompatible with the target type, or the target type was
-         * globally uninstantiable. We handle this cast by throwing a
-         * ClassCastException, unless the argument is null.
+        /**
+         * A null type cast is used as a placeholder value to indicate that the
+         * user tried a cast that couldn't possibly work. Typically this means
+         * either the statically resolvable arg type is incompatible with the
+         * target type, or the target type was globally uninstantiable.
+         * 
+         * See {@link com.google.gwt.dev.jjs.impl.TypeTightener.TightenTypesVisitor#endVisit(JCastOperation,
+         * Context)}
+         * 
+         * We handle this cast by throwing a ClassCastException, unless the
+         * argument is null.
          */
         JMethod method = program.getIndexedMethod("Cast.throwClassCastExceptionUnlessNull");
-        /*
-         * Override the type of the magic method with the null type.
-         */
+        // Note, we must update the method call to return the null type. 
         JMethodCall call = new JMethodCall(info, null, method, toType);
         call.addArg(expr);
         replaceExpr = call;
@@ -455,6 +458,7 @@
           // just remove the cast
           replaceExpr = curExpr;
         } else {
+          // A cast is still needed.  Substitute the appropriate Cast implementation.
           JMethod method;
           boolean isJsoCast = program.typeOracle.isEffectivelyJavaScriptObject(refType);
           if (isJsoCast) {
@@ -631,5 +635,4 @@
       replacer.accept(program);
     }
   }
-
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index d42befc..36c534f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -368,12 +368,15 @@
       JMethod method = call.getTarget();
       if (call.isVolatile() && method == runAsyncOnsuccess) {
         /*
-         * Magic magic magic: don't allow code flow from the AsyncFragmentLoader
-         * implementation back into the callback.onSuccess(). If we did, the
-         * rescue path would look like JRunAsync ->
-         * AsyncFragmentLoader.runAsync() -> callback.onSuccess(). This would
-         * completely defeat code splitting as all the code on the other side of
-         * the barrier would become reachable.
+         * Note: In order to preserve code splitting, don't allow code flow from the
+         * AsyncFragmentLoader implementation back into the
+         * callback.onSuccess(). If we did, the rescue path would look like
+         * JRunAsync -> AsyncFragmentLoader.runAsync() -> callback.onSuccess().
+         * This would completely defeat code splitting as all the code on the
+         * other side of the barrier would become reachable.
+         * 
+         * Code flow analysis is run separately on methods which implement
+         * RunAsyncCallback.onSuccess() as top-level entry points.
          */
         return true;
       }
@@ -517,7 +520,7 @@
 
     /**
      * Subclasses of JavaScriptObject are never instantiated directly. They are
-     * created "magically" when a JSNI method passes a reference to an existing
+     * implicitly created when a JSNI method passes a reference to an existing
      * JS object into Java code. If any point in the program can pass a value
      * from JS into Java which could potentially be cast to JavaScriptObject, we
      * must rescue JavaScriptObject.
@@ -643,8 +646,8 @@
              * literal initializers.
              * 
              * TODO: Model ClassLiteral access a different way to avoid special
-             * magic. See
-             * Pruner.transformToNullFieldRef()/transformToNullMethodCall().
+             * handling. See
+             *  Pruner.transformToNullFieldRef()/transformToNullMethodCall().
              */
             JField field = (JField) var;
             accept(field.getInitializer());
@@ -961,15 +964,6 @@
     runAsync.traverseOnSuccess(rescuer);
   }
 
-  /**
-   * Traverse the fragments for all runAsyncs.
-   */
-  public void traverseFromRunAsyncs() {
-    for (JRunAsync runAsync : program.getRunAsyncs()) {
-      traverseFromRunAsync(runAsync);
-    }
-  }
-
   private void buildMethodsOverriding() {
     methodsThatOverrideMe = new HashMap<JMethod, List<JMethod>>();
     for (JDeclaredType type : program.getDeclaredTypes()) {
@@ -985,4 +979,13 @@
       }
     }
   }
+
+  /**
+   * Traverse the fragments for all runAsyncs.
+   */
+  private void traverseFromRunAsyncs() {
+    for (JRunAsync runAsync : program.getRunAsyncs()) {
+      traverseFromRunAsync(runAsync);
+    }
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
index a1b00f2..af0afd8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
@@ -63,8 +63,9 @@
           && (currentMethod != null && currentMethod.getEnclosingType() == program
               .getIndexedType("AsyncFragmentLoader"))) {
         /*
-         * Magic magic magic: don't optimize calls from AsyncFragmentLoader
-         * to runAsyncCallBack.onSuccess(). This can defeat code splitting!
+         * Note: The volatile marker on the method flags it so that we don't
+         * optimize calls from AsyncFragmentLoader to implementations of
+         * RunAsyncCallback.onSuccess(). This can defeat code splitting.
          */
         x.setVolatile();
         return;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
index 259e8f2..d93006c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/TypeTightener.java
@@ -362,6 +362,16 @@
    */
   public class TightenTypesVisitor extends JModVisitor {
 
+    /**
+     * Tries to determine a specific concrete type for the cast, then either
+     * removes the cast, or tightens the cast to a narrower type.
+     * 
+     * If static analysis determines that a cast is not possible, swap in a cast
+     * to a null type. This will later be normalized into throwing an
+     * Exception.
+     * 
+     * @see CastNormalizer
+     */
     @Override
     public void endVisit(JCastOperation x, Context ctx) {
       JType argType = x.getExpr().getType();
@@ -394,7 +404,7 @@
         // remove the cast operation
         ctx.replaceMe(x.getExpr());
       } else if (triviallyFalse && toType != program.getTypeNull()) {
-        // replace with a magic NULL cast, unless it's already a cast to NULL
+        // replace with a placeholder cast to NULL, unless it's already a cast to NULL
         JCastOperation newOp =
             new JCastOperation(x.getSourceInfo(), program.getTypeNull(), x.getExpr());
         ctx.replaceMe(newOp);
diff --git a/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java b/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
index d4dbda9..4ab5eb5 100644
--- a/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
+++ b/dev/core/src/com/google/gwt/dev/shell/DispatchClassInfo.java
@@ -147,7 +147,7 @@
       addMember(members, field, field.getName());
     }
 
-    // Add a magic field to access class literals from JSNI
+    // Add a synthetic field to access class literals from JSNI
     addMember(members, new SyntheticClassMember(targetClass), "class");
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/util/HttpHeaders.java b/dev/core/src/com/google/gwt/dev/util/HttpHeaders.java
index 873771b..83e64a8 100644
--- a/dev/core/src/com/google/gwt/dev/util/HttpHeaders.java
+++ b/dev/core/src/com/google/gwt/dev/util/HttpHeaders.java
@@ -23,7 +23,7 @@
 import java.util.Locale;
 
 /**
- * Groups predefined magic HTTP header strings.
+ * HTTP header strings defined by RFCs.
  */
 public final class HttpHeaders {
 
diff --git a/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java b/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java
index e6a392a..e76f84e 100644
--- a/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/linker/impl/SelectionScriptJavaScriptTest.java
@@ -149,7 +149,7 @@
   }
   
   /**
-   * Test the fully magic script base with no meta properties.
+   * Test the script base with no meta properties.
    */
   public void testScriptBase() throws IOException {
     StringBuffer testCode = new StringBuffer();
@@ -269,6 +269,7 @@
 
     final List<String> alerts = new ArrayList<String>();
     webClient.setAlertHandler(new AlertHandler() {
+      @Override
       public void handleAlert(Page page, String msg) {
         alerts.add(msg);
       }
diff --git a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
index 39b2f51..a333f54 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
@@ -235,10 +235,8 @@
     //
     JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, false);
 
-    /*
-     * FindDeferredBindingSitesVisitor detects errors in usage of magic methods
-     * in the GWT class.
-     */
+    
+     // Find errors in usage of GWT.create() calls
     for (CompilationUnitDeclaration jdtCud : goldenCuds) {
       jdtCud.traverse(new FindDeferredBindingSitesVisitor(), jdtCud.scope);
     }
diff --git a/dev/core/test/com/google/gwt/lang/LongLibTestBase.java b/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
index 9c49076..d596e5d 100644
--- a/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
+++ b/dev/core/test/com/google/gwt/lang/LongLibTestBase.java
@@ -21,8 +21,8 @@
 import junit.framework.TestCase;
 
 /**
- * Test the LongLib class. The magic expected values were computed by using a
- * Java println on normal Java longs.
+ * Test the LongLib class. The magic numbers being testing against were computed
+ * by using a Java println on normal Java longs.
  */
 public class LongLibTestBase extends TestCase {
     
diff --git a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
index 1cc2cf7..8c5e0af 100644
--- a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
+++ b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
@@ -257,11 +257,12 @@
   }
 
   /**
-   * The standard instance of AsyncFragmentLoader used in a web browser. If not
-   * in GWT (i.e our vanilla JUnit tests, or if referenced in a server context),
-   * this filed is {@code null}. In GWT, the parameters to this call are
-   * rewritten by {@link com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs}. So this
-   * must be a method call of exactly two arguments, or that magic fails.
+   * The standard instance of AsyncFragmentLoader used in a web browser.  Outside
+   * of GWT generated JavaScript (i.e our vanilla JUnit tests, or if referenced
+   * in a server context), this field is {@code null}. When compiled to
+   * JavaScript, the parameters to this call are rewritten by
+   * {@link com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs}. So this must be a
+   * method call of exactly two arguments to succeed when invoked in web mode.
    */
   public static AsyncFragmentLoader BROWSER_LOADER = makeBrowserLoader(1, new int[]{});
 
diff --git a/user/src/com/google/gwt/i18n/client/LocalizableResource.java b/user/src/com/google/gwt/i18n/client/LocalizableResource.java
index 4e5b20c..d126e6f 100644
--- a/user/src/com/google/gwt/i18n/client/LocalizableResource.java
+++ b/user/src/com/google/gwt/i18n/client/LocalizableResource.java
@@ -86,8 +86,8 @@
   public @interface Generate {
 
     /**
-     * Constant "magic" default value used to detect that no value was supplied
-     * for the fileName parameter.
+     * Placeholder used to detect that no value was supplied for the fileName
+     * parameter.
      */
     String DEFAULT = "[default]";
     
diff --git a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
index f4002b4..87e4e52 100644
--- a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
@@ -312,7 +312,7 @@
           numExpressions = concatOp(numExpressions, b);
 
         } else {
-          // This indicates that some magic node is slipping by our visitors
+          // This indicates that some unexpected node is slipping by our visitors
           loopLogger.log(TreeLogger.ERROR, "Unhandled substitution "
               + x.getClass());
           throw new UnableToCompleteException();
diff --git a/user/src/com/google/gwt/user/rebind/ui/ImageBundleGenerator.java b/user/src/com/google/gwt/user/rebind/ui/ImageBundleGenerator.java
index bf4c0d7..eefb238 100644
--- a/user/src/com/google/gwt/user/rebind/ui/ImageBundleGenerator.java
+++ b/user/src/com/google/gwt/user/rebind/ui/ImageBundleGenerator.java
@@ -363,7 +363,7 @@
       JClassType userType = typeOracle.getType(typeName);
 
       // Get the type this generator is designed to support.
-      JClassType magicType = typeOracle.findType(IMAGEBUNDLE_QNAME);
+      JClassType markerType = typeOracle.findType(IMAGEBUNDLE_QNAME);
 
       // Ensure it's an interface.
       if (userType.isInterface() == null) {
@@ -373,9 +373,9 @@
       }
 
       // Ensure proper derivation.
-      if (!userType.isAssignableTo(magicType)) {
+      if (!userType.isAssignableTo(markerType)) {
         logger.log(TreeLogger.ERROR, userType.getQualifiedSourceName()
-            + " must be assignable to " + magicType.getQualifiedSourceName(),
+            + " must be assignable to " + markerType.getQualifiedSourceName(),
             null);
         throw new UnableToCompleteException();
       }
diff --git a/user/super/com/google/gwt/emul/java/lang/Object.java b/user/super/com/google/gwt/emul/java/lang/Object.java
index 23ab9a5..3b8efff 100644
--- a/user/super/com/google/gwt/emul/java/lang/Object.java
+++ b/user/super/com/google/gwt/emul/java/lang/Object.java
@@ -43,7 +43,12 @@
   private transient JavaScriptObject castableTypeMap;
 
   /**
-   * magic magic magic.
+   * A special marker field used internally to the GWT compiler. For example, it
+   * is used for distinguishing whether an object is a Java object or a
+   * JavaScriptObject. It is also used to differentiate our own Java objects
+   * from foreign objects in a different module on the same page.
+   * 
+   * @see com.google.gwt.lang.Cast
    * 
    * @skip
    */
@@ -55,11 +60,11 @@
   }
 
   /*
-   * Magic; unlike the real JRE, we don't spec this method as final. The
-   * compiler will generate a polymorphic override on every other class which
-   * will return the correct class object.
+   * Note: Unlike the real JRE, we don't spec this method as final because the
+   * compiler generates a polymorphic override on every other class which will
+   * return the correct class object.
    * 
-   * TODO(scottb): declare this final, but have the compiler fix it up.
+   * TODO(scottb, compiler magician): declare this final, but have the compiler fix it up.
    */
   public Class<? extends Object> getClass() {
     return Object.class;
@@ -74,7 +79,7 @@
   }
 
   /**
-   * Never called; here for compatibility.
+   * Never called; here for JRE compatibility.
    * 
    * @skip
    */