Reimplements x == null => !x transforms in EqualityNormalizer; the replacements to Cast.jsEquals() were thwarting the GenerateJavaScriptAST version.
Review by: spoon
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2544 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/EqualityNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/EqualityNormalizer.java
index c17fbc0..4c3e437 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/EqualityNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/EqualityNormalizer.java
@@ -93,19 +93,40 @@
x.getSourceInfo(), x.getType(), x.getOp(), lhs, rhs);
ctx.replaceMe(binOp);
} else {
- // Replace with a call to Cast.jsEquals, which does a == internally.
- String methodName;
- if (op == JBinaryOperator.EQ) {
- methodName = "Cast.jsEquals";
+ boolean lhsNullLit = lhs == program.getLiteralNull();
+ boolean rhsNullLit = rhs == program.getLiteralNull();
+ if ((lhsNullLit && rhsStatus == StringStatus.NOTSTRING)
+ || (rhsNullLit && lhsStatus == StringStatus.NOTSTRING)) {
+ /*
+ * If either side is a null literal and the other is non-String,
+ * replace with a null-check.
+ */
+ String methodName;
+ if (op == JBinaryOperator.EQ) {
+ methodName = "Cast.isNull";
+ } else {
+ methodName = "Cast.isNotNull";
+ }
+ JMethod isNullMethod = program.getIndexedMethod(methodName);
+ JMethodCall call = new JMethodCall(program, x.getSourceInfo(), null,
+ isNullMethod);
+ call.getArgs().add(lhsNullLit ? rhs : lhs);
+ ctx.replaceMe(call);
} else {
- methodName = "Cast.jsNotEquals";
+ // Replace with a call to Cast.jsEquals, which does a == internally.
+ String methodName;
+ if (op == JBinaryOperator.EQ) {
+ methodName = "Cast.jsEquals";
+ } else {
+ methodName = "Cast.jsNotEquals";
+ }
+ JMethod eqMethod = program.getIndexedMethod(methodName);
+ JMethodCall call = new JMethodCall(program, x.getSourceInfo(), null,
+ eqMethod);
+ call.getArgs().add(lhs);
+ call.getArgs().add(rhs);
+ ctx.replaceMe(call);
}
- JMethod eqMethod = program.getIndexedMethod(methodName);
- JMethodCall call = new JMethodCall(program, x.getSourceInfo(), null,
- eqMethod);
- call.getArgs().add(lhs);
- call.getArgs().add(rhs);
- ctx.replaceMe(call);
}
}
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 f027b4d..ec71c24 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
@@ -54,7 +54,6 @@
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JNewArray;
import com.google.gwt.dev.jjs.ast.JNewInstance;
-import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JPostfixOperation;
@@ -407,33 +406,6 @@
JsBinaryOperator myOp = JavaToJsOperatorMap.get(x.getOp());
/*
- * Optimize null tests. We cannot do this with strings, however, because
- * in JavaScript the empty string evaluates to boolean false.
- *
- * (foo == null) => !foo
- *
- * (foo != null) => !!foo (coerces to boolean)
- */
- if ((x.getOp() == JBinaryOperator.EQ)
- || (x.getOp() == JBinaryOperator.NEQ)) {
- boolean lhsNull = x.getLhs() instanceof JNullLiteral;
- boolean rhsNull = x.getRhs() instanceof JNullLiteral;
- if (lhsNull || rhsNull) {
- JExpression toUse = lhsNull ? x.getRhs() : x.getLhs();
- JsExpression toUseJs = lhsNull ? rhs : lhs;
- if (!couldBeString(toUse)) {
- if ((x.getOp() == JBinaryOperator.EQ)) {
- push(new JsPrefixOperation(JsUnaryOperator.NOT, toUseJs));
- } else {
- push(new JsPrefixOperation(JsUnaryOperator.NOT,
- new JsPrefixOperation(JsUnaryOperator.NOT, toUseJs)));
- }
- return;
- }
- }
- }
-
- /*
* Use === and !== on reference types, or else you can get wrong answers
* when Object.toString() == 'some string'.
*/
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Cast.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Cast.java
index 2691f4b..54136c1 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Cast.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Cast.java
@@ -78,6 +78,23 @@
return src.typeMarker != getNullMethod() && src.typeId != 2;
}
+ /**
+ * Uses the not operator to perform a null-check; do NOT use on anything that
+ * could be a String.
+ */
+ static native boolean isNotNull(Object src) /*-{
+ // Coerce to boolean.
+ return !!src;
+ }-*/;
+
+ /**
+ * Uses the not operator to perform a null-check; do NOT use on anything that
+ * could be a String.
+ */
+ static native boolean isNull(Object src) /*-{
+ return !src;
+ }-*/;
+
static native boolean jsEquals(Object a, Object b) /*-{
return a == b;
}-*/;