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(";");