This replaces r2963. It adds a very narrow static eval rule for
JavaScript nodes: literal == null can be replaced by true or false
depending on what the literal is.
Review by: scottb (desk check)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2976 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java b/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
index 79f6f08..050bc77 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
@@ -30,10 +30,12 @@
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsIf;
import com.google.gwt.dev.js.ast.JsModVisitor;
+import com.google.gwt.dev.js.ast.JsNullLiteral;
import com.google.gwt.dev.js.ast.JsPrefixOperation;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsStatement;
import com.google.gwt.dev.js.ast.JsUnaryOperator;
+import com.google.gwt.dev.js.ast.JsValueLiteral;
import com.google.gwt.dev.js.ast.JsVars;
import com.google.gwt.dev.js.ast.JsVisitor;
import com.google.gwt.dev.js.ast.JsWhile;
@@ -86,8 +88,8 @@
*/
private class EvalFunctionsAtTopScope extends JsModVisitor {
private final Set<JsFunction> dontMove = new HashSet<JsFunction>();
- private final Stack<JsBlock> scopeStack = new Stack<JsBlock>();
private final Stack<ListIterator<JsStatement>> itrStack = new Stack<ListIterator<JsStatement>>();
+ private final Stack<JsBlock> scopeStack = new Stack<JsBlock>();
@Override
public void endVisit(JsFunction x, JsContext<JsExpression> ctx) {
@@ -233,6 +235,8 @@
shortCircuitOr(arg1, arg2, ctx);
} else if (op == JsBinaryOperator.COMMA) {
trySimplifyComma(arg1, arg2, ctx);
+ } else if (op == JsBinaryOperator.EQ) {
+ trySimplifyEq(x, arg1, arg2, ctx);
}
}
@@ -526,6 +530,47 @@
return jsBlock;
}
}
+
+ private JsExpression simplifyEq(JsExpression original, JsExpression arg1,
+ JsExpression arg2) {
+ assert (original != null);
+
+ if (arg1 instanceof JsNullLiteral) {
+ return simplifyNullEq(original, arg2);
+ }
+
+ if (arg2 instanceof JsNullLiteral) {
+ return simplifyNullEq(original, arg1);
+ }
+
+ // no simplification made
+ return original;
+ }
+
+ /**
+ * Simplify exp == null.
+ */
+ private JsExpression simplifyNullEq(JsExpression original, JsExpression exp) {
+ assert (original != null);
+
+ if (exp instanceof JsValueLiteral) {
+ // "undefined" is not a JsValueLiteral, so the only way
+ // the result can be true is if exp is itself a JsNullLiteral
+ boolean result = exp instanceof JsNullLiteral;
+ return program.getBooleanLiteral(result);
+ }
+
+ // no simplification made
+ return original;
+ }
+
+ private void trySimplifyEq(JsExpression original, JsExpression arg1,
+ JsExpression arg2, JsContext<JsExpression> ctx) {
+ JsExpression updated = simplifyEq(original, arg1, arg2);
+ if (updated != original) {
+ ctx.replaceMe(updated);
+ }
+ }
}
public static boolean exec(JsProgram program) {
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java b/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java
index 41244ed..7abc651 100644
--- a/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java
+++ b/dev/core/src/com/google/gwt/dev/js/ast/JsProgram.java
@@ -55,6 +55,13 @@
objectScope = new JsScope(rootScope, "Object");
}
+ public JsBooleanLiteral getBooleanLiteral(boolean truth) {
+ if (truth) {
+ return getTrueLiteral();
+ }
+ return getFalseLiteral();
+ }
+
/**
* Gets the {@link JsStatement} to use whenever parsed source include a
* <code>debugger</code> statement.