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());