Adds static field&method support for native JsTypes.

Change-Id: I0a3ec05509b58e4237654be99cb5bda81a525e66
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
index a35adcb..70821b8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/HasJsInfo.java
@@ -27,4 +27,6 @@
   String getJsNamespace();
 
   String getQualifiedJsName();
+
+  boolean isJsNative();
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
index 90ffce5..ed23292 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JField.java
@@ -160,6 +160,10 @@
     return jsName != null;
   }
 
+  public boolean isJsNative() {
+    return enclosingType.isJsNative();
+  }
+
   @Override
   public String getJsName() {
     return jsName;
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 845df17..fce135d 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
@@ -1039,7 +1039,7 @@
        * in endVisit(JBinaryOperation) rectifies the situation.
        */
 
-      JsExpression result = names.get(x.getField()).makeRef(x.getSourceInfo());
+      JsExpression result = createStaticReference(x.getField(), x.getSourceInfo());
 
       // Add clinit (if needed).
       result = createCommaExpression(maybeCreateClinitCall(x.getField(), false), result);
@@ -1317,10 +1317,7 @@
 
     private JsExpression dispatchToStatic(JsExpression unnecessaryQualifier, JMethod method,
         List<JsExpression> args, SourceInfo sourceInfo) {
-      JsNameRef methodName =
-          method.isJsNative()
-              ? createJsQualifier(method.getQualifiedJsName(), sourceInfo)
-              : names.get(method).makeRef(sourceInfo);
+      JsNameRef methodName = createStaticReference(method, sourceInfo);
       JsExpression result = new JsInvocation(sourceInfo, methodName, args);
 
       return createCommaExpression(unnecessaryQualifier, result);
@@ -2163,6 +2160,13 @@
       return new JsBinaryOperation(lhs.getSourceInfo(), JsBinaryOperator.COMMA, lhs, rhs);
     }
 
+    private JsNameRef createStaticReference(JMember member, SourceInfo sourceInfo) {
+      assert member.isStatic();
+      return member.isJsNative()
+          ? createJsQualifier(member.getQualifiedJsName(), sourceInfo)
+          : names.get(member).makeRef(sourceInfo);
+    }
+
     private JsExpression generateCastableTypeMap(JClassType x) {
       JCastMap castMap = program.getCastMap(x);
       if (castMap != null) {
diff --git a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
index 7af64fb..edaf15c 100644
--- a/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
+++ b/user/test/com/google/gwt/core/client/interop/JsTypeTest.java
@@ -39,6 +39,8 @@
   @Override
   protected void gwtSetUp() throws Exception {
     ScriptInjector.fromString("function MyJsInterface() {}\n"
+        + "MyJsInterface.staticX = 33;"
+        + "MyJsInterface.answerToLife = function() { return 42;};"
         + "MyJsInterface.prototype.sum = function sum(bias) { return this.x + bias; };")
         .setWindow(TOP_WINDOW).inject();
     patchPrototype(MyClassExtendsJsPrototype.class);
@@ -138,20 +140,30 @@
   }
 
   public void testConcreteNativeType() {
+    assertEquals(33, MyJsClassWithPrototype.staticX);
+    MyJsClassWithPrototype.staticX = 34;
+    assertEquals(34, MyJsClassWithPrototype.staticX);
+    assertEquals(42, MyJsClassWithPrototype.answerToLife());
+
     MyJsClassWithPrototype obj = new MyJsClassWithPrototype();
-    assertTrue(isUndefined(obj.getX()));
-    obj.setX(72);
-    assertEquals(72, obj.getX());
+    assertTrue(isUndefined(obj.x));
+    obj.x = 72;
+    assertEquals(72, obj.x);
     assertEquals(74, obj.sum(2));
+
+    assertTrue(isUndefined(obj.getY()));
+    obj.setY(91);
+    assertEquals(91, obj.getY());
   }
 
   public void testConcreteNativeType_sublasss() {
     MyClassExtendsJsPrototype mc = new MyClassExtendsJsPrototype();
     assertEquals(143, mc.sum(1));
 
-    // Also test with setting properties
-    mc.setX(-mc.getX());
+    mc.x = -mc.x;
     assertEquals(58, mc.sum(0));
+
+    assertEquals(52, mc.getY());
   }
 
   public void testJsPropertyIsX() {
diff --git a/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java b/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
index faf7049..6f3ac8a 100644
--- a/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
+++ b/user/test/com/google/gwt/core/client/interop/MyClassExtendsJsPrototype.java
@@ -18,7 +18,8 @@
 class MyClassExtendsJsPrototype extends MyJsClassWithPrototype {
 
   MyClassExtendsJsPrototype() {
-    setX(42);
+    this.x = 42;
+    setY(52);
   }
 
   @Override
diff --git a/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
index 03e6e80..99cce77 100644
--- a/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
+++ b/user/test/com/google/gwt/core/client/interop/MyJsClassWithPrototype.java
@@ -23,11 +23,18 @@
  */
 @JsType(prototype = "MyJsInterface")
 public class MyJsClassWithPrototype {
-  @JsProperty
-  public native int getX();
+
+  public static int staticX;
+
+  public static native int answerToLife();
+
+  public int x;
 
   @JsProperty
-  public native void setX(int x);
+  public native int getY();
+
+  @JsProperty
+  public native void setY(int x);
 
   public native int sum(int bias);
 }