Fix dangling clinit issue; check if clinit method calls have been replaced or removed, during javascript generation phase.

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


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10223 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 ff3e1f7..d46f89b 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
@@ -127,6 +127,7 @@
 import com.google.gwt.dev.js.ast.JsNew;
 import com.google.gwt.dev.js.ast.JsNode;
 import com.google.gwt.dev.js.ast.JsNormalScope;
+import com.google.gwt.dev.js.ast.JsNullLiteral;
 import com.google.gwt.dev.js.ast.JsNumberLiteral;
 import com.google.gwt.dev.js.ast.JsObjectLiteral;
 import com.google.gwt.dev.js.ast.JsParameter;
@@ -1118,6 +1119,31 @@
 
       popList(jsInvocation.getArguments(), x.getArgs().size()); // args
 
+      if (JProgram.isClinit(method)) {
+        /*
+         * It is possible for clinits to be referenced here that have actually
+         * been retargeted (see {@link
+         * JTypeOracle.recomputeAfterOptimizations}). Most of the time, these
+         * will get cleaned up by other optimization passes prior to this point,
+         * but it's not guaranteed. In this case we need to replace the method
+         * call with the replaced clinit, unless the replacement is null, in
+         * which case we generate a JsNullLiteral as a place-holder expression.
+         */
+        JDeclaredType type = method.getEnclosingType();
+        JDeclaredType clinitTarget = type.getClinitTarget();
+        if (clinitTarget == null) {
+          if (x.getInstance() != null) {
+            pop(); // instance
+          }
+          // generate a null expression, which will get optimized out
+          push(JsNullLiteral.INSTANCE);
+          return;
+        } else if (type != clinitTarget) {
+          // replace the method with its retargeted clinit
+          method = clinitTarget.getMethods().get(0);
+        }
+      }
+
       JsNameRef qualifier;
       JsExpression unnecessaryQualifier = null;
       if (method.isStatic()) {