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 {