Revert "Cleanup array usage of class literals."
This cleanup breaks assumptions made by EnumOrdinalizer.
This reverts commit a1e72ddbf96b45f58874f721925d67151b180369.
Change-Id: Ib0d51ed5b0fae85ed08fd371f5c1668e32412b24
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
index 8ed0104..1bc3877 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
@@ -28,27 +28,36 @@
SourceInfo info, JArrayType arrayType, List<JExpression> dimensionExpressions) {
// Produce all class literals that will eventually get generated.
assert dimensionExpressions != null;
- return new JNewArray(info, arrayType, dimensionExpressions, null);
+ return new JNewArray(info, arrayType, dimensionExpressions, null,
+ new JClassLiteral(info.makeChild(), arrayType.getLeafType()));
}
public static JNewArray createArrayWithInitializers(SourceInfo info, JArrayType arrayType,
List<JExpression> initializers) {
assert initializers != null;
- return new JNewArray(info, arrayType, null, initializers);
+ return new JNewArray(info, arrayType, null, initializers,
+ new JClassLiteral(info.makeChild(), arrayType.getLeafType()));
}
private final List<JExpression> dimensionExpressions;
private final List<JExpression> initializers;
+ /**
+ * The list of class literals that will be needed to support this expression.
+ */
+ private JClassLiteral leafTypeClassLiteral;
+
private JArrayType type;
public JNewArray(SourceInfo info, JArrayType type, List<JExpression> dimensionExpressions,
- List<JExpression> initializers) {
+ List<JExpression> initializers, JClassLiteral leafTypeClassLiteral) {
super(info);
this.type = type;
this.dimensionExpressions = dimensionExpressions;
this.initializers = initializers;
+ this.leafTypeClassLiteral = leafTypeClassLiteral;
+ assert !(leafTypeClassLiteral.getRefType().isArrayType());
}
public JArrayType getArrayType() {
@@ -63,6 +72,13 @@
return initializers;
}
+ /**
+ * Return a class literal for the leaf type of the array.
+ */
+ public JClassLiteral getLeafTypeClassLiteral() {
+ return leafTypeClassLiteral;
+ }
+
@Override
public JReferenceType getType() {
return type.strengthenToNonNull().strengthenToExact();
@@ -91,6 +107,8 @@
assert ((dimensionExpressions != null) ^ (initializers != null));
visitor.accept(initializers != null ? initializers : dimensionExpressions);
+
+ leafTypeClassLiteral = (JClassLiteral) visitor.accept(leafTypeClassLiteral);
}
visitor.endVisit(this, ctx);
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
index 498d227..226bfb8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
@@ -22,7 +22,6 @@
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JCastMap;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JIntLiteral;
import com.google.gwt.dev.jjs.ast.JLiteral;
@@ -131,7 +130,7 @@
private JExpression initializeUnidimensionalArray(JNewArray x, JArrayType arrayType) {
// override the type of the called method with the array's type
SourceInfo sourceInfo = x.getSourceInfo();
- JLiteral classLiteral = getLeafTypeClassLiteral(x);
+ JLiteral classLit = x.getLeafTypeClassLiteral();
JExpression castableTypeMap = getOrCreateCastMap(sourceInfo, arrayType);
JRuntimeTypeReference arrayElementRuntimeTypeReference =
getElementRuntimeTypeReference(sourceInfo, arrayType);
@@ -141,7 +140,7 @@
JMethodCall call =
new JMethodCall(sourceInfo, null, initializeUnidimensionalArrayMethod);
call.overrideReturnType(arrayType);
- call.addArgs(classLiteral, castableTypeMap, arrayElementRuntimeTypeReference, dim,
+ call.addArgs(classLit, castableTypeMap, arrayElementRuntimeTypeReference, dim,
elementTypeCategory, program.getLiteralInt(arrayType.getDims()));
return call;
}
@@ -153,7 +152,7 @@
JsonArray elementTypeReferences = new JsonArray(sourceInfo, program.getJavaScriptObject());
JsonArray dimList = new JsonArray(sourceInfo, program.getJavaScriptObject());
JType currentElementType = arrayType;
- JLiteral classLit = getLeafTypeClassLiteral(x);
+ JLiteral classLit = x.getLeafTypeClassLiteral();
for (int i = 0; i < x.getDimensionExpressions().size(); ++i) {
// Walk down each type from most dims to least.
JArrayType curArrayType = (JArrayType) currentElementType;
@@ -182,7 +181,7 @@
// override the type of the called method with the array's type
SourceInfo sourceInfo = x.getSourceInfo();
JExpression classLitExpression = program.createArrayClassLiteralExpression(x.getSourceInfo(),
- getLeafTypeClassLiteral(x), arrayType.getDims());
+ x.getLeafTypeClassLiteral(), arrayType.getDims());
JExpression castableTypeMap = getOrCreateCastMap(sourceInfo, arrayType);
JRuntimeTypeReference elementTypeIds = getElementRuntimeTypeReference(sourceInfo, arrayType);
JsonArray initializers =
@@ -203,13 +202,6 @@
}
}
- private JClassLiteral getLeafTypeClassLiteral(JNewArray newArray) {
- JType leafType = newArray.getArrayType().getLeafType();
- JClassLiteral leafClassLiteral = new JClassLiteral(newArray.getSourceInfo(), leafType);
- leafClassLiteral.setField(program.getClassLiteralField(leafType));
- return leafClassLiteral;
- }
-
private JArrayRef needsSetCheck(JBinaryOperation x) {
if (x.getOp() != JBinaryOperator.ASG || !(x.getLhs() instanceof JArrayRef)) {
return null;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
index 5699666..a453256 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
@@ -217,7 +217,8 @@
@Override
public boolean visit(JNewArray x, Context ctx) {
expression = new JNewArray(x.getSourceInfo(), x.getArrayType(),
- cloneExpressions(x.getDimensionExpressions()), cloneExpressions(x.getInitializers()));
+ cloneExpressions(x.getDimensionExpressions()), cloneExpressions(x.getInitializers()),
+ cloneExpression(x.getLeafTypeClassLiteral()));
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index 1014218..1b97a34 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -577,11 +577,6 @@
}
private void maybeRescueClassLiteral(JReferenceType type) {
- if (type.isArrayType()) {
- JArrayType arrayType = (JArrayType) type.getUnderlyingType();
- // Always rescue the leaf type class literal as it is needed for creating arrays.
- rescue(program.getClassLiteralField(arrayType.getLeafType()));
- }
if (liveFieldsAndMethods.contains(getClassMethod) ||
liveFieldsAndMethods.contains(getClassField)) {
// getClass() already live so rescue class literal immediately
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
index 6d1ddf2..d13ed82 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
@@ -15,7 +15,6 @@
import com.google.gwt.dev.StringAnalyzableTypeEnvironment;
import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
@@ -24,8 +23,6 @@
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
-import com.google.gwt.dev.jjs.ast.JNewArray;
-import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;
@@ -70,13 +67,22 @@
@Override
public void endVisit(JClassLiteral x, Context ctx) {
- recordClassLiteralReferenced(x.getRefType());
- }
-
- @Override
- public void endVisit(JNewArray x, Context ctx) {
- JType type = x.getArrayType().getLeafType();
- recordClassLiteralReferenced(type);
+ JType type = x.getRefType();
+ if (type instanceof JDeclaredType) {
+ String typeName = type.getName();
+ stringAnalyzableTypeEnvironment.recordStaticReferenceInMethod(typeName, currentMethodName);
+ maybeRecordClinitCall(typeName);
+ }
+ // Any Enum subtype whose class literal is referenced might have its enumValueOfFunc
+ // reflectively called at runtime (see Enum.valueOf()). So to be safe the enumValueOfFunc
+ // must be assumed to be called.
+ if (type.isEnumOrSubclass() != null && !type.getName().equals("java.lang.Enum")) {
+ JMethod valueOfMethod = getValueOfMethod((JDeclaredType) type);
+ if (valueOfMethod != null) {
+ stringAnalyzableTypeEnvironment.recordMethodCallsMethod(currentMethodName,
+ computeName(valueOfMethod));
+ }
+ }
}
@Override
@@ -106,6 +112,7 @@
@Override
public boolean visit(JField x, Context ctx) {
String typeName = x.getEnclosingType().getName();
+
if (x.isJsInteropEntryPoint()) {
stringAnalyzableTypeEnvironment.recordExportedStaticReferenceInType(typeName);
}
@@ -143,12 +150,6 @@
recordCurrentMethodInstantiatesType(x.getEnclosingType());
}
- for (JParameter parameter : x.getParams()) {
- if (x.isJsMethodVarargs() && parameter.isVarargs()) {
- recordClassLiteralReferenced(
- ((JArrayType) parameter.getType().getUnderlyingType()).getLeafType());
- }
- }
return true;
}
@@ -178,24 +179,6 @@
}
}
- private void recordClassLiteralReferenced(JType type) {
- if (type instanceof JDeclaredType) {
- String typeName = type.getName();
- stringAnalyzableTypeEnvironment.recordStaticReferenceInMethod(typeName, currentMethodName);
- maybeRecordClinitCall(typeName);
- }
- // Any Enum subtype whose class literal is referenced might have its enumValueOfFunc
- // reflectively called at runtime (see Enum.valueOf()). So to be safe the enumValueOfFunc
- // must be assumed to be called.
- if (type.isEnumOrSubclass() != null && !type.getName().equals("java.lang.Enum")) {
- JMethod valueOfMethod = getValueOfMethod((JDeclaredType) type);
- if (valueOfMethod != null) {
- stringAnalyzableTypeEnvironment.recordMethodCallsMethod(currentMethodName,
- computeName(valueOfMethod));
- }
- }
- }
-
private void processJFieldRef(JFieldRef x) {
if (x.getTarget() instanceof JField) {
JField field = (JField) x.getTarget();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
index 0eaae52..11d373a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
@@ -396,11 +396,6 @@
resolveClassLiteralField(type);
}
}
- // Class literals for array types are implicitly used in array creation, so they must be
- // considered reachable.
- for (JArrayType arrayType : program.getAllArrayTypes()) {
- resolveClassLiteralField(arrayType.getLeafType());
- }
NormalizeVisitor visitor = new NormalizeVisitor();
visitor.accept(program);
program.recordClassLiteralFields(classLiteralFields);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
index a0bd259..0938544 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
@@ -374,6 +374,8 @@
new JIntLiteral(sourceInfo, varargsIndex));
JNewArray arrayVariable = JNewArray.createArrayWithDimensionExpressions(sourceInfo,
varargsArrayType, Collections.singletonList(lengthMinusVarargsIndex));
+ arrayVariable.getLeafTypeClassLiteral().setField(
+ program.getClassLiteralField(varargsArrayType.getLeafType()));
preamble.addStmt(new JDeclarationStatement(
sourceInfo, argumentsCopyVariable.createRef(sourceInfo), arrayVariable));
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
index a435dfd..deaa8f5 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
@@ -252,15 +252,11 @@
// Returning a JSO from a JSNI method rescues.
analyzeSnippet("Foo.create_array();").assertOnlyInstantiatedTypes(
- "int[]", "Object",
- // Classes rescued due to rescueing classliterals for instantiated arrays.
- "Class", "String", "Serializable", "Comparable", "CharSequence");
+ "int[]", "Object");
// Returning a JSO from a JSNI method rescues.
analyzeSnippet("Foo.create_2d_array();").assertOnlyInstantiatedTypes(
- "int[][]", "Object[]", "Object",
- // Classes rescued due to rescueing classliterals for instantiated arrays.
- "Class", "String", "Serializable", "Comparable", "CharSequence");
+ "int[][]", "Object[]", "Object");
}
private Result analyzeSnippet(String codeSnippet)
diff --git a/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java b/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
index 68322a7..9ab1c19 100644
--- a/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
+++ b/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
@@ -287,7 +287,6 @@
sideEffectCount++;
return obj;
}
-
public void testVarargsCall_sideEffectingInstance() {
SubclassNativeWithVarargsConstructor object =
new SubclassNativeWithVarargsConstructor(0, new Object[0]);
@@ -296,16 +295,4 @@
assertSame(object, doSideEffect(object).varargsMethod(0, params));
assertSame(1, sideEffectCount);
}
-
- static class UninstantiatedClass {
- }
-
- @JsMethod(namespace = JsPackage.GLOBAL)
- public static UninstantiatedClass[] varargJsMethodUninstantiatedVararg(UninstantiatedClass... varargs) {
- return varargs;
- }
-
- public native void testVarargsCall_uninstantiatedVararg() /*-{
- @GWTTestCase::assertEquals(II)(0, $global.varargJsMethodUninstantiatedVararg().length);
- }-*/;
}