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 {