Fixes a latent problem with Jsni.generateJavaScript(); the name implied a lot more generality than was warranted.
- Clarified the behavior by changing names and comments inside Jsni.java
- Changed SelectionScriptGenerator to call JsNode.toSource() directly; it NEVER should have been using the ill-named Jsni.generateJavaScript(), which tries to replace JSNI idents for hosted mode rewriting.

Review by: mmendez


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@930 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java b/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
index 451ce36..1774936 100644
--- a/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
+++ b/dev/core/src/com/google/gwt/dev/shell/JsniInjector.java
@@ -194,7 +194,8 @@
       // Note that the method body itself will print curly braces, so we don't
       // need them around the try/catch.
       //
-      String js = jsTry + Jsni.generateEscapedJavaScript(jsniBody) + jsCatch;
+      String js = jsTry + Jsni.generateEscapedJavaScriptForHostedMode(jsniBody)
+          + jsCatch;
       String jsniSig = Jsni.getJsniSignature(method);
 
       // figure out starting line number
@@ -216,7 +217,7 @@
    * @param expectedHeaderLines
    * @param expectedBodyLines
    * @return a String of the Java code to call a JSNI method, using
-   *     JavaScriptHost.invokeNative*
+   *         JavaScriptHost.invokeNative*
    */
   private String genNonNativeVersionOfJsniMethod(JMethod method,
       int expectedHeaderLines, int expectedBodyLines) {
diff --git a/dev/core/src/com/google/gwt/dev/util/Jsni.java b/dev/core/src/com/google/gwt/dev/util/Jsni.java
index 02a3bf2..1f43e86 100644
--- a/dev/core/src/com/google/gwt/dev/util/Jsni.java
+++ b/dev/core/src/com/google/gwt/dev/util/Jsni.java
@@ -58,10 +58,41 @@
     }
   }
 
-  private static class VisitorImpl extends JsSourceGenerationVisitor {
+  /**
+   * Generate source code, fixing up any JSNI references for hosted mode.
+   * 
+   * <p/><table>
+   * <tr>
+   * <td>Original</td>
+   * <td>Becomes</td>
+   * </tr>
+   * <tr>
+   * <td><code>.@class::method(params)(args)</code></td>
+   * 
+   * <td><code>["@class::method(params)"](args)</code></td>
+   * </tr>
+   * <tr>
+   * <td><code>@class::method(params)(args)</code></td>
+   * 
+   * <td><code>__static["@class::method(params)"](args)</code></td>
+   * </tr>
+   * <tr>
+   * <td><code>.@class::field</code></td>
+   * 
+   * <td><code>["@class::field"]</code></td>
+   * </tr>
+   * <tr>
+   * <td><code>@class::field</code></td>
+   * 
+   * <td><code>__static["@class::field"]</code></td>
+   * </tr>
+   * </table>
+   */
+  private static class JsSourceGenWithJsniIdentFixup extends
+      JsSourceGenerationVisitor {
     private final TextOutput out;
 
-    public VisitorImpl(TextOutput out) {
+    public JsSourceGenWithJsniIdentFixup(TextOutput out) {
       super(out);
       this.out = out;
     }
@@ -69,24 +100,6 @@
     public boolean visit(JsNameRef x, JsContext ctx) {
       String ident = x.getIdent();
       if (ident.startsWith("@")) {
-        // Fix up JSNI references in the js body.
-        // Cases:
-        // .@class::method(params)(args)
-        // becomes
-        // ["@class::method(params)"](args)
-        // 
-        // @class::method(params)(args)
-        // becomes
-        // __static["@class::method(params)"](args)
-        //
-        // .@class::field
-        // becomes
-        // ["@class::field"]
-        // 
-        // @class::field
-        // becomes
-        // __static["@class::field"]
-        //
         JsExpression q = x.getQualifier();
         if (q != null) {
           accept(q);
@@ -246,8 +259,15 @@
     return new Interval(srcStart, srcEnd);
   }
 
-  public static String generateEscapedJavaScript(JsNode node) {
-    String source = generateJavaScript(node);
+  /**
+   * Returns a string representing the source output of the JsNode, where all
+   * JSNI idents have been replaced with legal JavaScript for hosted mode.
+   * 
+   * The output has quotes and slashes escaped so that the result can be part of
+   * a legal Java source code string literal.
+   */
+  public static String generateEscapedJavaScriptForHostedMode(JsNode node) {
+    String source = generateJavaScriptForHostedMode(node);
     StringBuffer body = new StringBuffer(source.length());
     body.append(source);
     escapeQuotesAndSlashes(body);
@@ -255,14 +275,6 @@
     return body.toString();
   }
 
-  public static String generateJavaScript(JsNode node) {
-    TextOutputOnCharArray tooca = new TextOutputOnCharArray(false);
-    VisitorImpl vi = new VisitorImpl(tooca);
-    vi.accept(node);
-    char[] source = tooca.getText();
-    return String.valueOf(source);
-  }
-
   /**
    * Gets a unique name for this method and its signature (this is used to
    * determine whether one method overrides another).
@@ -363,4 +375,16 @@
     }
   }
 
+  /**
+   * Returns a string representing the source output of the JsNode, where all
+   * JSNI idents have been replaced with legal JavaScript for hosted mode.
+   */
+  private static String generateJavaScriptForHostedMode(JsNode node) {
+    TextOutputOnCharArray tooca = new TextOutputOnCharArray(false);
+    JsSourceGenWithJsniIdentFixup vi = new JsSourceGenWithJsniIdentFixup(tooca);
+    vi.accept(node);
+    char[] source = tooca.getText();
+    return String.valueOf(source);
+  }
+
 }
diff --git a/dev/core/src/com/google/gwt/dev/util/SelectionScriptGenerator.java b/dev/core/src/com/google/gwt/dev/util/SelectionScriptGenerator.java
index 7352e93..4114381 100644
--- a/dev/core/src/com/google/gwt/dev/util/SelectionScriptGenerator.java
+++ b/dev/core/src/com/google/gwt/dev/util/SelectionScriptGenerator.java
@@ -296,7 +296,7 @@
         // Emit a provider function, defined by the user in module config.
         PropertyProvider provider = prop.getProvider();
         assert (provider != null) : "expecting a default property provider to have been set";
-        String js = Jsni.generateJavaScript(provider.getBody());
+        String js = provider.getBody().toSource();
         pw.print("providers['" + prop.getName() + "'] = function() ");
         pw.print(js);
         pw.println(";");