Avoid static initializers for native JsType and JsFunction.

Change-Id: I6190f2ef660a5405032ee3fc6a9c8ea641e2a8cd
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
index 58d6551..c16b8f7 100755
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JDeclaredType.java
@@ -262,6 +262,9 @@
    * superclass, or <code>null</code> if this class has no static initializer.
    */
   public final JDeclaredType getClinitTarget() {
+    if (isJsNative() || isJsFunction()) {
+      return null;
+    }
     return clinitTarget;
   }
 
@@ -391,7 +394,7 @@
    * Returns <code>true</code> when this class's clinit must be run dynamically.
    */
   public boolean hasClinit() {
-    return clinitTarget != null;
+    return getClinitTarget() != null;
   }
 
   @Override
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index 03ce95f..e9feaad 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -415,6 +415,8 @@
     }
 
     if (IMMORTAL_CODEGEN_TYPES_SET.contains(name)) {
+      // Immortal types by definition won't run clinits.
+      type.setClinitTarget(null);
       immortalCodeGenTypes.add((JClassType) type);
     }
 
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 4a8d608..69a01c6 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
@@ -1759,12 +1759,9 @@
         }
 
         if (JProgram.isClinit(method)) {
-          if (type.getClinitTarget() == type) {
-            handleClinit(type, function);
-          } else {
-            continue;
-          }
+          handleClinit(type, function);
         }
+
         emitMethodImplementation(method,
             function.getName().makeRef(function.getSourceInfo()), function.makeStmt());
       }
@@ -1962,22 +1959,8 @@
               || doesNotHaveConcreteImplementation(method)) {
             continue;
           }
-          JsFunction function = null;
-          if (JProgram.isClinit(method)) {
-            /**
-             * Emit empty clinits that will be pruned. If a type B extends A, then even if
-             * B and A have no fields to initialize, there will be a call inserted in B's clinit
-             * to invoke A's clinit. Likewise, if you have a static field initialized to
-             * JavaScriptObject.createObject(), the clinit() will include this initializer code,
-             * which we don't want.
-             */
-            function = new JsFunction(x.getSourceInfo(), topScope,
-                topScope.declareName(mangleNameForGlobal(method)), true);
-            function.setBody(new JsBlock(method.getBody().getSourceInfo()));
-          } else {
-            function = transform(method);
-          }
           // add after var declaration, but before everything else
+          JsFunction function = transform(method);
           assert function.getName() != null;
           addMethodDefinitionStatement(1, method, function.makeStmt());
         }
@@ -2439,7 +2422,7 @@
       clinitFunctionForType.put(type, clinitFunction);
       JDeclaredType superClass = type.getSuperClass();
       JsFunction superClinitFunction = superClass == null
-          ? null : clinitFunctionForType.get(superClass);
+          ? null : clinitFunctionForType.get(superClass.getClinitTarget());
 
       clinitFunction.setSuperClinit(superClinitFunction);
       List<JsStatement> statements = clinitFunction.getBody().getStatements();
@@ -2577,11 +2560,13 @@
   }
 
   /**
-   * Return false if the methods need to be generated. Some methods do not need any output,
+   * Return false if the method needs to be generated. Some methods do not need any output,
    * in particular abstract methods and static intializers that are never called.
    */
   private static boolean doesNotHaveConcreteImplementation(JMethod method) {
-    return method.isAbstract();
+    return method.isAbstract()
+        || JProgram.isClinit(method)
+            && method.getEnclosingType().getClinitTarget() != method.getEnclosingType();
   }
 
   private static class JavaToJsOperatorMap {