Simplify RuntypeTypeId generation.
Change-Id: I4a5ad99b849e7c2b04ab56b6320f5c83b2ab2a88
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index 133ac68..1546051 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -1492,7 +1492,7 @@
}
if (this.options.useDetailedTypeIds()) {
- return new StringTypeMapper();
+ return new StringTypeMapper(jprogram);
}
return this.options.isIncrementalCompileEnabled() ?
compilerContext.getMinimalRebuildCache().getTypeMapper() :
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 af64f2f..0e8a567 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
@@ -947,7 +947,7 @@
// then we could do Type.prototype.polyname.call(this, ...). Currently prototypes do not
// have global names instead they are stuck into the prototypesByTypeId array.
return constructInvocation(sourceInfo, "JavaClassHierarchySetupUtil.getClassPrototype",
- convertJavaLiteral(typeMapper.get(type)));
+ (JsExpression) transform(getRuntimeTypeReference(type)));
}
}
@@ -2000,7 +2000,6 @@
private void generateCallToDefineClass(JClassType x,
List<JsNameRef> constructorArgs) {
- JExpression typeId = getRuntimeTypeReference(x);
JClassType superClass = x.getSuperClass();
JExpression superTypeId = (superClass == null) ? JNullLiteral.INSTANCE :
getRuntimeTypeReference(superClass);
@@ -2008,8 +2007,8 @@
List<JsExpression> defineClassArguments = Lists.newArrayList();
- defineClassArguments.add(convertJavaLiteral(typeId));
- defineClassArguments.add(jsPrototype == null ? convertJavaLiteral(superTypeId) :
+ defineClassArguments.add(transform(getRuntimeTypeReference(x)));
+ defineClassArguments.add(jsPrototype == null ? transform(superTypeId) :
createJsQualifier(jsPrototype, x.getSourceInfo()));
defineClassArguments.add(generateCastableTypeMap(x));
defineClassArguments.addAll(constructorArgs);
@@ -2361,13 +2360,9 @@
* Returns either _ or ClassCtor.prototype depending on output mode.
*/
private JsNameRef getPrototypeQualifierOf(JDeclaredType type, SourceInfo info) {
- if (closureCompilerFormatEnabled) {
- JsNameRef protoRef = prototype.makeRef(info);
- protoRef.setQualifier(names.get(type).makeRef(info));
- return protoRef;
- } else {
- return globalTemp.makeRef(info);
- }
+ return closureCompilerFormatEnabled
+ ? prototype.makeQualifiedRef(info, names.get(type).makeRef(info))
+ : globalTemp.makeRef(info);
}
private void collectExports(JDeclaredType type) {
@@ -2503,14 +2498,6 @@
* If a field is a literal, we can potentially treat it as immutable and assign it once on the
* prototype, to be reused by all instances of the class, instead of re-assigning the same
* literal in each constructor.
- *
- * Technically, to match JVM semantics, we should only do this for final or static fields. For
- * non-final/non-static fields, a super class's cstr, when it calls a polymorphic method that is
- * overridden in the subclass, should actually see default values (not the literal initializer)
- * before the subclass's cstr runs.
- *
- * However, cstr's calling polymorphic methods is admittedly an uncommon case, so we apply some
- * heuristics to see if we can initialize the field on the prototype anyway.
*/
private boolean initializeAtTopScope(JField x) {
if (x.getLiteralInitializer() == null) {
@@ -2936,14 +2923,7 @@
* Retrieves the runtime typeId for {@code type}.
*/
JExpression getRuntimeTypeReference(JReferenceType type) {
- Object typeId = typeMapper.get(type);
- if (typeId == null) {
- return null;
- }
- if (typeId instanceof JMethodCall) {
- return (JMethodCall) typeId;
- }
- return program.getLiteral(typeId);
+ return typeMapper.get(type);
}
private String mangleName(JField x) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRuntimeTypeReferences.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRuntimeTypeReferences.java
index 1d89caf..8fa4da3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRuntimeTypeReferences.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ResolveRuntimeTypeReferences.java
@@ -19,12 +19,14 @@
import com.google.gwt.dev.jjs.ast.HasName;
import com.google.gwt.dev.jjs.ast.JCastMap;
import com.google.gwt.dev.jjs.ast.JExpression;
+import com.google.gwt.dev.jjs.ast.JIntLiteral;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JRuntimeTypeReference;
+import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.thirdparty.guava.common.annotations.VisibleForTesting;
@@ -56,7 +58,7 @@
/**
* Maps a type into a type id literal.
*/
- public interface TypeMapper<T> {
+ public interface TypeMapper<T extends JExpression> {
T getOrCreateTypeId(JType type);
void copyFrom(TypeMapper<T> typeMapper);
@@ -67,14 +69,14 @@
/**
* Sequentially creates int type ids for types.
*/
- public static class IntTypeMapper implements Serializable, TypeMapper<Integer> {
+ public static class IntTypeMapper implements Serializable, TypeMapper<JIntLiteral> {
// NOTE: DO NOT STORE ANY AST REFERENCE. Objects of this type persist across compiles.
private final Map<String, Integer> typeIdByTypeName = Maps.newHashMap();
private int nextAvailableId = 0;
@Override
- public void copyFrom(TypeMapper<Integer> that) {
+ public void copyFrom(TypeMapper<JIntLiteral> that) {
if (!(that instanceof IntTypeMapper)) {
throw new IllegalArgumentException("Can only copy from IntTypeMapper");
}
@@ -92,43 +94,49 @@
}
@Override
- public Integer get(JType type) {
- return typeIdByTypeName.get(type.getName());
+ public JIntLiteral get(JType type) {
+ Integer typeId = typeIdByTypeName.get(type.getName());
+ return typeId == null ? null : new JIntLiteral(type.getSourceInfo(), typeId);
}
@Override
- public Integer getOrCreateTypeId(JType type) {
+ public JIntLiteral getOrCreateTypeId(JType type) {
String typeName = type.getName();
- if (typeIdByTypeName.containsKey(typeName)) {
- return typeIdByTypeName.get(typeName);
+ if (!typeIdByTypeName.containsKey(typeName)) {
+ int nextId = nextAvailableId++;
+ typeIdByTypeName.put(typeName, nextId);
}
- int nextId = nextAvailableId++;
- typeIdByTypeName.put(typeName, nextId);
- return nextId;
+ return get(type);
}
}
/**
* Predictably creates String type id literals for castable and instantiable types.
*/
- public static class StringTypeMapper implements TypeMapper<String> {
+ public static class StringTypeMapper implements TypeMapper<JStringLiteral> {
+
+ private JProgram program;
+
+ public StringTypeMapper(JProgram program) {
+ this.program = program;
+ }
@Override
- public void copyFrom(TypeMapper<String> that) {
+ public void copyFrom(TypeMapper<JStringLiteral> that) {
if (!(that instanceof StringTypeMapper)) {
throw new IllegalArgumentException("Can only copy from StringTypeMapper");
}
}
@Override
- public String getOrCreateTypeId(JType type) {
+ public JStringLiteral getOrCreateTypeId(JType type) {
return get(type);
}
@Override
- public String get(JType type) {
- return type.getName();
+ public JStringLiteral get(JType type) {
+ return program.getStringLiteral(type.getSourceInfo(), type.getName());
}
}
@@ -202,7 +210,7 @@
private class ReplaceRuntimeTypeReferencesVisitor extends JModVisitor {
@Override
public void endVisit(JRuntimeTypeReference x, Context ctx) {
- ctx.replaceMe(getTypeIdLiteral(x.getReferredType()));
+ ctx.replaceMe(getTypeIdExpression(x.getReferredType()));
}
}
@@ -272,9 +280,8 @@
}
}
- private JExpression getTypeIdLiteral(JType type) {
- Object typeId = typeMapper.getOrCreateTypeId(type);
- return typeId instanceof JMethodCall ? (JExpression) typeId : program.getLiteral(typeId);
+ private JExpression getTypeIdExpression(JType type) {
+ return typeMapper.getOrCreateTypeId(type);
}
public static void exec(JProgram program, TypeMapper<?> typeMapper, TypeOrder typeOrder) {
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/FullCompileTestBase.java b/dev/core/test/com/google/gwt/dev/jjs/impl/FullCompileTestBase.java
index 7d72375..e52b521 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/FullCompileTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/FullCompileTestBase.java
@@ -31,7 +31,6 @@
import com.google.gwt.dev.jjs.JavaAstConstructor;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.IntTypeMapper;
-import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.TypeMapper;
import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.TypeOrder;
import com.google.gwt.dev.js.ast.JsName;
import com.google.gwt.dev.js.ast.JsNode;
@@ -101,7 +100,7 @@
MethodCallTightener.exec(jProgram);
NameClashesFixer.exec(jProgram);
- TypeMapper<Integer> typeMapper = new IntTypeMapper();
+ IntTypeMapper typeMapper = new IntTypeMapper();
ResolveRuntimeTypeReferences.exec(jProgram, typeMapper, TypeOrder.FREQUENCY);
Map<StandardSymbolData, JsName> symbolTable =
diff --git a/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java b/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java
index 2bba3e7..5ee2152 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java
@@ -46,7 +46,6 @@
import com.google.gwt.dev.jjs.impl.MethodInliner;
import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences;
import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.StringTypeMapper;
-import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.TypeMapper;
import com.google.gwt.dev.jjs.impl.ResolveRuntimeTypeReferences.TypeOrder;
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsName;
@@ -283,7 +282,7 @@
ImplementCastsAndTypeChecks.exec(jProgram, false);
ArrayNormalizer.exec(jProgram);
- TypeMapper<String> typeMapper = new StringTypeMapper();
+ StringTypeMapper typeMapper = new StringTypeMapper(jProgram);
ResolveRuntimeTypeReferences.exec(jProgram, typeMapper, TypeOrder.FREQUENCY);
Map<StandardSymbolData, JsName> symbolTable =
new TreeMap<StandardSymbolData, JsName>(new SymbolData.ClassIdentComparator());