Adds <, <=, >, >=, ==, and != to JsStaticEval for numeric values.

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

Review by: acleung@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10749 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 d867d7b..14b2a7d 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsStaticEval.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.dev.js;
 
+import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.impl.OptimizerStats;
 import com.google.gwt.dev.js.ast.CanBooleanEval;
@@ -182,6 +183,17 @@
         trySimplifyNe(x, arg1, arg2, ctx);
       } else if (op == JsBinaryOperator.ADD) {
         trySimplifyAdd(x, arg1, arg2, ctx);
+      } else  {
+       switch (op) {
+         case GT:
+         case GTE:
+         case LT:
+         case LTE:
+           trySimplifyCompare(x, arg1, arg2, op, ctx);
+           break;
+         default:
+           break;
+       }
       }
     }
 
@@ -563,6 +575,37 @@
       return num;
     }
 
+    private JsExpression simplifyCompare(JsExpression original, JsExpression arg1,
+        JsExpression arg2, JsBinaryOperator op) {
+      assert (original != null);
+
+      // TODO(cromwellian) handle all types
+      if (arg1 instanceof JsNumberLiteral && arg2 instanceof JsNumberLiteral) {
+          double num1 = ((JsNumberLiteral) arg1).getValue();
+          double num2 = ((JsNumberLiteral) arg2).getValue();
+          boolean result = false;
+          switch(op) {
+            case LT:
+              result = num1 < num2;
+              break;
+            case LTE:
+              result = num1 <= num2;
+              break;
+            case GT:
+              result = num1 > num2;
+              break;
+            case GTE:
+              result = num1 >= num2;
+              break;
+            default:
+              throw new InternalCompilerException("Can't handle simplify of op " + op);
+          }
+        return JsBooleanLiteral.get(result);
+      }
+      // no simplification made
+      return original;
+    }
+
     private JsExpression simplifyEq(JsExpression original, JsExpression arg1,
         JsExpression arg2) {
       assert (original != null);
@@ -575,6 +618,10 @@
         return simplifyNullEq(original, arg1);
       }
 
+      if (arg1 instanceof JsNumberLiteral && arg2 instanceof JsNumberLiteral) {
+          return JsBooleanLiteral.get(((JsNumberLiteral) arg1).getValue()
+           == ((JsNumberLiteral) arg2).getValue());
+      }
       // no simplification made
       return original;
     }
@@ -591,6 +638,10 @@
         return simplifyNullNe(original, arg1);
       }
 
+      if (arg1 instanceof JsNumberLiteral && arg2 instanceof JsNumberLiteral) {
+        return JsBooleanLiteral.get(((JsNumberLiteral) arg1).getValue()
+            != ((JsNumberLiteral) arg2).getValue());
+      }
       // no simplification made
       return original;
     }
@@ -751,6 +802,14 @@
       return toReturn;
     }
 
+    private void trySimplifyCompare(JsExpression original, JsExpression arg1,
+        JsExpression arg2, JsBinaryOperator op, JsContext ctx) {
+      JsExpression updated = simplifyCompare(original, arg1, arg2, op);
+      if (updated != original) {
+        ctx.replaceMe(updated);
+      }
+    }
+
     private void trySimplifyEq(JsExpression original, JsExpression arg1,
         JsExpression arg2, JsContext ctx) {
       JsExpression updated = simplifyEq(original, arg1, arg2);
diff --git a/dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java b/dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java
index b68fd15..fabbb0d 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsStaticEvalTest.java
@@ -124,6 +124,23 @@
         optimize("if (a()) { b() } else { throw 1; }"));
   }
 
+  public void testLiteralCompares() throws Exception {
+    assertEquals("alert(false);", optimize("alert(2 != 2)"));
+    assertEquals("alert(false);", optimize("alert(2 == 3)"));
+    assertEquals("alert(true);", optimize("alert(2 == 2)"));
+    assertEquals("alert(true);", optimize("alert(2 != 3)"));
+    assertEquals("alert(true);", optimize("alert(2 < 3)"));
+    assertEquals("alert(true);", optimize("alert(3 <= 3)"));
+    assertEquals("alert(true);", optimize("alert(3 > 2)"));
+    assertEquals("alert(true);", optimize("alert(3 >= 3)"));
+    assertEquals("alert(false);", optimize("alert(2 > 3)"));
+    assertEquals("alert(false);", optimize("alert(2 >= 3)"));
+    assertEquals("alert(false);", optimize("alert(3 < 2)"));
+    assertEquals("alert(false);", optimize("alert(3 <= 2)"));
+    assertEquals("alert(false);", optimize("alert(1.8E+10308 < 1.9E+10308)"));
+    assertEquals("alert(false);", optimize("alert(1.8E+10308 > 1.9E+10308)"));
+  }
+
   public void testLiteralEqNull() throws Exception {
     assertEquals("alert(false);", optimize("alert('test' == null)"));
   }