Allow JTypeOracle information to be reused across compiles.
Change-Id: I8afe419c0e41004882a0c9da7fc965fdb5dd12a9
Review-Link: https://gwt-review.googlesource.com/#/c/8418/
diff --git a/dev/BUILD b/dev/BUILD
index fe265e6..44b019f 100644
--- a/dev/BUILD
+++ b/dev/BUILD
@@ -186,6 +186,7 @@
"core/src/com/google/gwt/dev/CompileTaskOptionsImpl.java",
"core/src/com/google/gwt/dev/GwtCreateMap.java",
"core/src/com/google/gwt/dev/GwtVersion.java",
+ "core/src/com/google/gwt/dev/MinimalRebuildCache.java",
"core/src/com/google/gwt/dev/Permutation.java",
"core/src/com/google/gwt/dev/PrecompileTaskOptions.java",
"core/src/com/google/gwt/dev/PrecompileTaskOptionsImpl.java",
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/ModuleState.java b/dev/codeserver/java/com/google/gwt/dev/codeserver/ModuleState.java
index d63c706..20fda87 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/ModuleState.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/ModuleState.java
@@ -78,7 +78,7 @@
*/
boolean recompile(Map<String, String> bindingProperties, AtomicReference<Progress> progress) {
try {
- current.set(recompiler.compile(bindingProperties, progress));
+ current.set(recompiler.recompile(bindingProperties, progress));
return true;
} catch (UnableToCompleteException e) {
logger.log(TreeLogger.Type.WARN, "continuing to serve previous version");
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java b/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
index 4518f21..abef180 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/Recompiler.java
@@ -25,6 +25,7 @@
import com.google.gwt.dev.CompilerOptions;
import com.google.gwt.dev.IncrementalBuilder;
import com.google.gwt.dev.IncrementalBuilder.BuildResultStatus;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ConfigProps;
import com.google.gwt.dev.cfg.ConfigurationProperty;
@@ -56,6 +57,7 @@
private final TreeLogger logger;
private String serverPrefix;
private int compilesDone = 0;
+ private MinimalRebuildCache minimalRebuildCache;
// after renaming
private AtomicReference<String> moduleName = new AtomicReference<String>(null);
@@ -77,10 +79,22 @@
compilerContext = compilerContextBuilder.build();
}
- synchronized CompileDir compile(Map<String, String> bindingProperties,
- AtomicReference<Progress> progress)
+ CompileDir recompile(Map<String, String> bindingProperties, AtomicReference<Progress> progress)
throws UnableToCompleteException {
+ if (options.shouldCompilePerFile()) {
+ return compile(bindingProperties, progress, minimalRebuildCache);
+ }
+ return compile(bindingProperties, progress, new MinimalRebuildCache());
+ }
+ synchronized CompileDir compile(Map<String, String> bindingProperties,
+ AtomicReference<Progress> progress) throws UnableToCompleteException {
+ return compile(bindingProperties, progress, new MinimalRebuildCache());
+ }
+
+ private synchronized CompileDir compile(Map<String, String> bindingProperties,
+ AtomicReference<Progress> progress, MinimalRebuildCache minimalRebuildCache)
+ throws UnableToCompleteException {
if (compilesDone == 0) {
System.setProperty("java.awt.headless", "true");
if (System.getProperty("gwt.speedtracerlog") == null) {
@@ -112,7 +126,8 @@
success = compileIncremental(compileLogger, compileDir);
} else {
- success = compileMonolithic(compileLogger, bindingProperties, compileDir, progress);
+ success = compileMonolithic(compileLogger, bindingProperties, compileDir, progress,
+ minimalRebuildCache);
}
} finally {
try {
@@ -128,6 +143,9 @@
throw new UnableToCompleteException();
}
+ // keep the minimal rebuild cache for the next compile
+ this.minimalRebuildCache = minimalRebuildCache;
+
long elapsedTime = System.currentTimeMillis() - startTime;
compileLogger.log(TreeLogger.Type.INFO,
String.format("%.3fs total -- Compile completed", elapsedTime / 1000d));
@@ -208,7 +226,8 @@
}
private boolean compileMonolithic(TreeLogger compileLogger, Map<String, String> bindingProperties,
- CompileDir compileDir, AtomicReference<Progress> progress) throws UnableToCompleteException {
+ CompileDir compileDir, AtomicReference<Progress> progress, MinimalRebuildCache rebuildCache)
+ throws UnableToCompleteException {
progress.set(new Progress.Compiling(moduleName.get(), compilesDone, 0, 2, "Loading modules"));
@@ -226,7 +245,7 @@
CompilerOptions runOptions = new CompilerOptionsImpl(compileDir, newModuleName, options);
compilerContext = compilerContextBuilder.options(runOptions).build();
- boolean success = new Compiler(runOptions).run(compileLogger, module);
+ boolean success = new Compiler(runOptions, rebuildCache).run(compileLogger, module);
if (success) {
publishedCompileDir = compileDir;
}
diff --git a/dev/core/src/com/google/gwt/dev/Compiler.java b/dev/core/src/com/google/gwt/dev/Compiler.java
index 320e8b1..8b46fe7 100644
--- a/dev/core/src/com/google/gwt/dev/Compiler.java
+++ b/dev/core/src/com/google/gwt/dev/Compiler.java
@@ -123,9 +123,14 @@
private final CompilerOptionsImpl options;
public Compiler(CompilerOptions compilerOptions) {
+ this(compilerOptions, new MinimalRebuildCache());
+ }
+
+ public Compiler(CompilerOptions compilerOptions, MinimalRebuildCache minimalRebuildCache) {
this.options = new CompilerOptionsImpl(compilerOptions);
this.compilerContextBuilder = new CompilerContext.Builder();
- this.compilerContext = compilerContextBuilder.options(options).build();
+ this.compilerContext = compilerContextBuilder.options(options)
+ .minimalRebuildCache(minimalRebuildCache).build();
}
public boolean run(TreeLogger logger) throws UnableToCompleteException {
diff --git a/dev/core/src/com/google/gwt/dev/CompilerContext.java b/dev/core/src/com/google/gwt/dev/CompilerContext.java
index 5155d9d..410d265 100644
--- a/dev/core/src/com/google/gwt/dev/CompilerContext.java
+++ b/dev/core/src/com/google/gwt/dev/CompilerContext.java
@@ -46,6 +46,7 @@
private ResourceOracle buildResourceOracle;
private boolean compileMonolithic = true;
+ private MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
private CompilationErrorsIndex globalCompilationErrorsIndex;
private CompilationErrorsIndex libraryCompilationErrorsIndex;
private LibraryGroup libraryGroup = new ImmutableLibraryGroup();
@@ -63,6 +64,7 @@
CompilerContext compilerContext = new CompilerContext();
compilerContext.buildResourceOracle = buildResourceOracle;
+ compilerContext.minimalRebuildCache = minimalRebuildCache;
compilerContext.libraryWriter = libraryWriter;
compilerContext.libraryGroup = libraryGroup;
compilerContext.module = module;
@@ -110,6 +112,12 @@
return this;
}
+ public Builder minimalRebuildCache(MinimalRebuildCache minimalRebuildCache) {
+ assert minimalRebuildCache != null;
+ this.minimalRebuildCache = minimalRebuildCache;
+ return this;
+ }
+
public Builder unitCache(UnitCache unitCache) {
this.unitCache = unitCache;
return this;
@@ -169,6 +177,8 @@
* they should be grouped together instead of floating free here.
*/
private boolean compileMonolithic = true;
+
+ private MinimalRebuildCache minimalRebuildCache = new MinimalRebuildCache();
private LibraryGroup libraryGroup = new ImmutableLibraryGroup();
private LibraryWriter libraryWriter = new NullLibraryWriter();
private CompilationErrorsIndex localCompilationErrorsIndex = new CompilationErrorsIndexImpl();
@@ -188,6 +198,10 @@
return buildResourceOracle;
}
+ public MinimalRebuildCache getMinimalRebuildCache() {
+ return minimalRebuildCache;
+ }
+
/**
* Returns the immutable compilation errors index that provides a combined view of compilation
* errors for both the current compile as well as previously compiled libraries.
diff --git a/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java b/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java
new file mode 100644
index 0000000..72a0059
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.dev.jjs.ast.JTypeOracle.ImmediateTypeRelations;
+
+import java.io.Serializable;
+
+/**
+ * MinimalRebuildCache contains compiler information that can be persisted between compiles to
+ * decrease compilation time.
+ */
+public class MinimalRebuildCache implements Serializable {
+ private ImmediateTypeRelations immediateTypeRelations = new ImmediateTypeRelations();
+
+ public ImmediateTypeRelations getImmediateTypeRelations() {
+ return immediateTypeRelations;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java b/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
index 744dfdf..df06c8d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
@@ -18,6 +18,7 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilerContext;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.PrecompileTaskOptions;
import com.google.gwt.dev.cfg.ConfigProps;
import com.google.gwt.dev.javac.CompilationState;
@@ -49,7 +50,8 @@
InternalCompilerException.preload();
- CompilerContext compilerContext = new CompilerContext.Builder().options(options).build();
+ CompilerContext compilerContext = new CompilerContext.Builder().options(options)
+ .minimalRebuildCache(new MinimalRebuildCache()).build();
RebindPermutationOracle rpo = new RebindPermutationOracle() {
@Override
@@ -73,7 +75,7 @@
}
};
- JProgram jprogram = new JProgram();
+ JProgram jprogram = new JProgram(compilerContext.getMinimalRebuildCache());
JsProgram jsProgram = new JsProgram();
UnifyAst unifyAst = new UnifyAst(logger, compilerContext, jprogram, jsProgram, rpo);
unifyAst.buildEverything();
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 a21e4c2..e41a2b3 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -827,7 +827,7 @@
protected abstract void checkEntryPoints(String[] additionalRootTypes);
- protected abstract void createJProgram();
+ protected abstract void createJProgram(CompilerContext compilerContext);
/**
* Takes as input a CompilationState and transforms that into a unified by not yet resolved Java
@@ -863,7 +863,7 @@
*/
// (1) Initialize local state
- createJProgram();
+ createJProgram(compilerContext);
// Synchronize JTypeOracle with compile optimization behavior.
jprogram.typeOracle.setOptimize(
options.getOptimizationLevel() > OptionOptimize.OPTIMIZE_LEVEL_DRAFT);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
index cc05df7..edec35a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompiler.java
@@ -165,8 +165,8 @@
}
@Override
- protected void createJProgram() {
- jprogram = new JProgram(false);
+ protected void createJProgram(CompilerContext compilerContext) {
+ jprogram = new JProgram(compilerContext.getMinimalRebuildCache(), false);
}
@VisibleForTesting
diff --git a/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
index e93fa33..427181f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/MonolithicJavaToJavaScriptCompiler.java
@@ -261,8 +261,8 @@
}
@Override
- protected void createJProgram() {
- jprogram = new JProgram();
+ protected void createJProgram(CompilerContext compilerContext) {
+ jprogram = new JProgram(compilerContext.getMinimalRebuildCache());
}
}
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 bdd0316..52ef015 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
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.jjs.ast;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.jjs.Correlation.Literal;
import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.SourceInfo;
@@ -377,14 +378,14 @@
pinnedMethods.add(method);
}
- public JProgram() {
+ public JProgram(MinimalRebuildCache minimalRebuildCache) {
super(SourceOrigin.UNKNOWN);
- typeOracle = new JTypeOracle(this, true);
+ typeOracle = new JTypeOracle(this, minimalRebuildCache, true);
}
- public JProgram(boolean hasWholeWorldKnowledge) {
+ public JProgram(MinimalRebuildCache minimalRebuildCache, boolean hasWholeWorldKnowledge) {
super(SourceOrigin.UNKNOWN);
- typeOracle = new JTypeOracle(this, hasWholeWorldKnowledge);
+ typeOracle = new JTypeOracle(this, minimalRebuildCache, hasWholeWorldKnowledge);
}
public void addEntryMethod(JMethod entryPoint) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index fb03c8f..45d4892 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.dev.jjs.ast;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
import com.google.gwt.dev.util.arg.JsInteropMode;
import com.google.gwt.dev.util.collect.HashMap;
@@ -485,14 +486,16 @@
/**
* Constructs a new JTypeOracle.
*/
- public JTypeOracle(ArrayTypeCreator arrayTypeCreator, boolean hasWholeWorldKnowledge) {
- this.immediateTypeRelations = new ImmediateTypeRelations();
+ public JTypeOracle(ArrayTypeCreator arrayTypeCreator, MinimalRebuildCache minimalRebuildCache,
+ boolean hasWholeWorldKnowledge) {
+ this.immediateTypeRelations = minimalRebuildCache.getImmediateTypeRelations();
this.arrayTypeCreator = arrayTypeCreator;
this.hasWholeWorldKnowledge = hasWholeWorldKnowledge;
}
/**
- * True if the type is a JSO or interface implemented by JSO..
+ * True if the type is a JSO or interface implemented by JSO or a JsType without
+ * prototype.
*/
public boolean canBeJavaScriptObject(JType type) {
if (type instanceof JNonNullType) {
@@ -502,8 +505,7 @@
}
/**
- * True if the type is a JSO or interface implemented by JSO or a JsType without
- * prototype.
+ * True if the type is a JSO or interface implemented by JSO or a JsType without prototype.
*/
public boolean canCrossCastLikeJso(JType type) {
JDeclaredType dtype = getNearestJsType(type, false);
@@ -525,7 +527,7 @@
return true;
}
if (type instanceof JInterfaceType && isImplementedMap.get(type.getName()) != null) {
- for (JReferenceType impl : getTypes(isImplementedMap, (JReferenceType) type)) {
+ for (JReferenceType impl : getTypes(isImplementedMap, type.getName())) {
if (isInstantiatedType((JClassType) impl)) {
return true;
}
@@ -692,6 +694,14 @@
return false;
}
+ public void updateImmediateTypeRelations(Set<JDeclaredType> changedTypes,
+ Set<JDeclaredType> deletedTypes) {
+ deleteImmediateTypeRelations(deletedTypes);
+ deleteImmediateTypeRelations(changedTypes);
+ recordImmediateTypeRelations(changedTypes);
+ computeExtendedTypeRelations();
+ }
+
public void computeBeforeAST(StandardTypes standardTypes,
Collection<JDeclaredType> declaredTypes) {
this.standardTypes = standardTypes;
@@ -813,8 +823,8 @@
// Class arrays reuse their leaf type super hierarchy.
JDeclaredType leafType = (JDeclaredType) arrayType.getLeafType();
for (JReferenceType leafSuperType : getSuperHierarchyTypes(leafType)) {
- JArrayType superArrayType = arrayTypeCreator.getOrCreateArrayType(
- leafSuperType, arrayType.getDims());
+ JArrayType superArrayType =
+ arrayTypeCreator.getOrCreateArrayType(leafSuperType, arrayType.getDims());
superHierarchyTypes.add(superArrayType);
}
}
@@ -823,13 +833,13 @@
Set<JReferenceType> superHierarchyTypes = Sets.newHashSet();
if (superClassMap.containsKey(type.getName())) {
- superHierarchyTypes.addAll(getTypes(superClassMap, type));
+ superHierarchyTypes.addAll(getTypes(superClassMap, type.getName()));
}
if (superInterfaceMap.containsKey(type.getName())) {
- superHierarchyTypes.addAll(getTypes(superInterfaceMap, type));
+ superHierarchyTypes.addAll(getTypes(superInterfaceMap, type.getName()));
}
if (implementsMap.containsKey(type.getName())) {
- superHierarchyTypes.addAll(getTypes(implementsMap, type));
+ superHierarchyTypes.addAll(getTypes(implementsMap, type.getName()));
}
superHierarchyTypes.add(type);
@@ -896,8 +906,14 @@
if (referenceType instanceof JNullType) {
return true;
}
+ return isJavaScriptObject(referenceType.getName());
+ }
- String typeName = referenceType.getName();
+ // Note: This method does not account for null types and only relies on static
+ // class inheritance and does not account for any changes due to optimizations.
+ // Therefore this method should be kept private since callers need to be aware
+ // of this semantic difference.
+ private boolean isJavaScriptObject(String typeName) {
if (typeName.equals(JProgram.JAVASCRIPTOBJECT)) {
return true;
}
@@ -1009,17 +1025,17 @@
}
/**
- * Returns true if qType is a subclass of type, directly or indirectly.
+ * Returns true if possibleSubType is a subclass of type, directly or indirectly.
*/
- public boolean isSubClass(JClassType type, JClassType qType) {
- return get(subClassMap, type.getName()).contains(qType.getName());
+ public boolean isSubClass(JClassType type, JClassType possibleSubType) {
+ return get(subClassMap, type.getName()).contains(possibleSubType.getName());
}
/**
- * Returns true if qType is a superclass of type, directly or indirectly.
+ * Returns true if possibleSuperClass is a superclass of type, directly or indirectly.
*/
- public boolean isSuperClass(JClassType type, JClassType qType) {
- return isSuperClass(type.getName(), qType.getName());
+ public boolean isSuperClass(JClassType type, JClassType possibleSuperClass) {
+ return isSuperClass(type.getName(), possibleSuperClass.getName());
}
/**
@@ -1078,7 +1094,18 @@
getOrCreate(map, key).add(value);
}
- private void recordImmediateTypeRelations(Collection<JDeclaredType> types) {
+ private void deleteImmediateTypeRelations(Set<JDeclaredType> types) {
+ for (JDeclaredType type : types) {
+ if (type instanceof JClassType) {
+ immediateTypeRelations.superClassesByClass.remove(type.getName());
+ immediateTypeRelations.implementedIntfsByClass.remove(type.getName());
+ } else if (type instanceof JInterfaceType) {
+ immediateTypeRelations.superIntfsByIntf.remove(type.getName());
+ }
+ }
+ }
+
+ private void recordImmediateTypeRelations(Iterable<JDeclaredType> types) {
referenceTypesByName.clear();
for (JReferenceType type : types) {
referenceTypesByName.put(type.getName(), type);
@@ -1173,16 +1200,15 @@
dualImpls.clear();
// Create dual mappings for any jso interface with a Java implementor.
for (String jsoIntfName : jsoSingleImpls.keySet()) {
- JInterfaceType jsoIntf = (JInterfaceType) referenceTypesByName.get(jsoIntfName);
- Set<JReferenceType> implementors = getTypes(isImplementedMap, jsoIntf);
- for (JReferenceType implementor : implementors) {
+ Set<String> implementors = get(isImplementedMap, jsoIntfName);
+ for (String implementor : implementors) {
if (!hasWholeWorldKnowledge || !isJavaScriptObject(implementor)) {
// Assume always dualImpl for separate compilation. Due to the nature of separate
// compilation, the compiler can not know if a specific interface is implemented in a
// different module unless it is a monolithic whole world compile.
// TODO(rluble): Jso devirtualization should be an normalization pass before optimization
// JTypeOracle should be mostly unaware of JSOs.
- dualImpls.add(jsoIntf.getName());
+ dualImpls.add(jsoIntfName);
break;
}
}
@@ -1389,7 +1415,7 @@
*/
for (JInterfaceType intf : type.getImplements()) {
computeVirtualUpRefs(type, intf);
- for (JReferenceType superIntf : getTypes(superInterfaceMap, intf)) {
+ for (JReferenceType superIntf : getTypes(superInterfaceMap, intf.getName())) {
computeVirtualUpRefs(type, (JInterfaceType) superIntf);
}
}
@@ -1464,12 +1490,12 @@
}
private Set<JReferenceType> getTypes(Map<String, Set<String>> typeNamesByTypeName,
- JReferenceType type) {
- Set<String> typeNames = get(typeNamesByTypeName, type.getName());
+ String typeName) {
+ Set<String> typeNames = get(typeNamesByTypeName, typeName);
IdentityHashSet<JReferenceType> types = new IdentityHashSet<JReferenceType>();
- for (String typeName : typeNames) {
- JReferenceType referenceType = referenceTypesByName.get(typeName);
+ for (String localTypeName : typeNames) {
+ JReferenceType referenceType = referenceTypesByName.get(localTypeName);
assert referenceType != null;
types.add(referenceType);
}
diff --git a/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java b/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
index 7412912..9a03166 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/JjsTypeTest.java
@@ -16,8 +16,10 @@
package com.google.gwt.dev.jjs;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.jjs.ast.JArrayType;
import com.google.gwt.dev.jjs.ast.JClassType;
+import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JNonNullType;
import com.google.gwt.dev.jjs.ast.JNullType;
@@ -29,8 +31,11 @@
import junit.framework.TestCase;
+import org.junit.Assert;
+
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -244,6 +249,28 @@
assertSuperHierarchy(arrayOfArrayOfB, arrayOfArrayOfB, arrayOfArrayOfBase, arrayOfArrayOfObject,
arrayOfArrayOfIntfI, arrayOfArrayOfIntfIBase, classObject);
assertSuperHierarchy(arrayOfInt, arrayOfInt, classObject);
+
+ intfCollection = createInterface("java.util.Collection");
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(classArrayList, intfList, intfCollection, classObject),
+ Sets.<JDeclaredType> newHashSet(intfIterable));
+
+ assertSuperHierarchy(intfCollection, intfCollection);
+ assertSuperHierarchy(intfList, intfList, intfCollection);
+ assertSuperHierarchy(classArrayList, classArrayList, intfList, classObject,
+ intfCollection);
+
+ classA = createClass("A", classObject, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(classA, classObject),
+ Sets.<JDeclaredType> newHashSet(classBase));
+ assertSuperHierarchy(classA, classA, classObject);
+
+ JClassType classASub = createClass("ASub", classA, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(classASub, classA, classObject),
+ Sets.<JDeclaredType> newHashSet());
+ assertSuperHierarchy(classASub, classASub, classA, classObject);
}
public void testJavahSignatures() {
@@ -272,9 +299,126 @@
assertSame(arrayOfA, program.strongerType(intfCloneable, arrayOfA));
}
+ public void testUpdateTypeInformation_isJavaScriptObject() {
+ program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
+ program.getDeclaredTypes());
+
+ JClassType jso = createClass("SomeJSO", classJso, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(jso),
+ Collections.<JDeclaredType> emptySet());
+ Assert.assertTrue(program.typeOracle.isJavaScriptObject(jso));
+ program.typeOracle.updateImmediateTypeRelations(
+ Collections.<JDeclaredType> emptySet(),
+ Sets.<JDeclaredType> newHashSet(jso));
+ Assert.assertFalse(program.typeOracle.isJavaScriptObject(jso));
+
+ jso = createClass("SomeJSO", classJso, false, false);
+ JClassType jsoChild = createClass("SomeJSOChild", jso, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(jso, jsoChild),
+ Collections.<JDeclaredType> emptySet());
+ Assert.assertTrue(program.typeOracle.isJavaScriptObject(jsoChild));
+ jsoChild = createClass("SomeJSOChild", classObject, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(jsoChild),
+ Collections.<JDeclaredType> emptySet());
+ Assert.assertFalse(program.typeOracle.isJavaScriptObject(jsoChild));
+
+ jso = createClass("SomeJSO", classJso, false, false);
+ jsoChild = createClass("SomeJSOChild", jso, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(jsoChild),
+ Collections.<JDeclaredType> emptySet());
+ Assert.assertTrue(program.typeOracle.isJavaScriptObject(jsoChild));
+ Assert.assertTrue(program.typeOracle.isJavaScriptObject(jso));
+ jso = createClass("SomeJSO", classObject, false, false);
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType> newHashSet(jso),
+ Collections.<JDeclaredType> emptySet());
+ Assert.assertFalse(program.typeOracle.isJavaScriptObject(jsoChild));
+ Assert.assertFalse(program.typeOracle.isJavaScriptObject(jso));
+ }
+
+ public void testUpdateTypeInformation_JSODualImpl() {
+ program.typeOracle.computeBeforeAST(StandardTypes.createFrom(program),
+ program.getDeclaredTypes());
+
+ Assert.assertFalse(program.typeOracle.isDualJsoInterface(intfJ));
+
+ JClassType javaIntfImplementor = createClass("JavaImplementor", classObject, false, false);
+ javaIntfImplementor.addImplements(intfJ);
+
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType>newHashSet(javaIntfImplementor),
+ Collections.<JDeclaredType>emptySet());
+ Assert.assertTrue(program.typeOracle.isDualJsoInterface(intfJ));
+ program.typeOracle.updateImmediateTypeRelations(
+ Collections.<JDeclaredType>emptySet(),
+ Sets.<JDeclaredType>newHashSet(javaIntfImplementor));
+ Assert.assertFalse(program.typeOracle.isDualJsoInterface(intfJ));
+ }
+
+ public void testUpdateTypeInformation_SubClasses() {
+ JClassType baseAll = createClass("IncrementalBaseAll", classObject, false, false);
+ JClassType sub1 = createClass("IncrementalSub1", baseAll, false, false);
+ JClassType sub2 = createClass("IncrementalSub2", baseAll, false, false);
+ JClassType sub1_2 = createClass("IncrementalSub1_2", sub1, false, false);
+
+ Assert.assertFalse(program.typeOracle.isSubClass(baseAll, sub1));
+
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType>newHashSet(baseAll, sub1, sub2, sub1_2),
+ Collections.<JDeclaredType>emptySet());
+
+ Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1));
+ Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub2));
+ Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1_2));
+ Assert.assertTrue(program.typeOracle.isSubClass(sub1, sub1_2));
+
+ sub1_2 = createClass("IncrementalSub1_2", baseAll, false, false);
+
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType>newHashSet(baseAll, sub2, sub1_2),
+ Sets.<JDeclaredType>newHashSet(sub1));
+
+ Assert.assertFalse(program.typeOracle.isSubClass(baseAll, sub1));
+ Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub2));
+ Assert.assertTrue(program.typeOracle.isSubClass(baseAll, sub1_2));
+ }
+
+ public void testUpdateTypeInformation_SuperClasses() {
+ JClassType baseAll = createClass("IncrementalBaseAll", classObject, false, false);
+ JClassType sub1 = createClass("IncrementalSub1", baseAll, false, false);
+ JClassType sub2 = createClass("IncrementalSub2", baseAll, false, false);
+ JClassType sub1_2 = createClass("IncrementalSub1_2", sub1, false, false);
+
+ Assert.assertFalse(program.typeOracle.isSuperClass(sub1, baseAll));
+
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType>newHashSet(baseAll, sub1, sub2, sub1_2),
+ Collections.<JDeclaredType>emptySet());
+
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub1, baseAll));
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub2, baseAll));
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, baseAll));
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, sub1));
+
+ sub1_2 = createClass("IncrementalSub1_2", baseAll, false, false);
+
+ program.typeOracle.updateImmediateTypeRelations(
+ Sets.<JDeclaredType>newHashSet(baseAll, sub2, sub1_2),
+ Sets.<JDeclaredType>newHashSet(sub1));
+
+ Assert.assertFalse(program.typeOracle.isSuperClass(sub1, baseAll));
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub2, baseAll));
+ Assert.assertFalse(program.typeOracle.isSuperClass(sub1_2, sub1));
+ Assert.assertTrue(program.typeOracle.isSuperClass(sub1_2, baseAll));
+ }
+
@Override
protected void setUp() {
- createSampleProgram();
+ createSampleProgram(new MinimalRebuildCache());
}
private void assertSuperHierarchy(JReferenceType type, JReferenceType... superHierarchyTypes) {
@@ -296,9 +440,9 @@
return x;
}
- private void createSampleProgram() {
+ private void createSampleProgram(MinimalRebuildCache minimalRebuildCache) {
// Make the program itself
- program = new JProgram();
+ program = new JProgram(minimalRebuildCache);
typeOracle = program.typeOracle;
synthSource = SourceOrigin.UNKNOWN;
diff --git a/dev/core/test/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompilerTest.java b/dev/core/test/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompilerTest.java
index ffc4797..008abf1 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/LibraryJavaToJavaScriptCompilerTest.java
@@ -22,6 +22,7 @@
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.CompilerOptionsImpl;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.PrecompileTaskOptions;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.Condition;
@@ -298,7 +299,7 @@
public void testBuildLocalRuntimeRebindRules() throws UnableToCompleteException {
// Sets up environment.
Set<String> allRootTypes = Sets.newHashSet();
- compiler.jprogram = new JProgram();
+ compiler.jprogram = new JProgram(new MinimalRebuildCache());
Map<String, String> runtimeRebindRuleSourcesByShortName =
RuntimeRebindRuleGenerator.RUNTIME_REBIND_RULE_SOURCES_BY_SHORT_NAME;
Rules rules = new Rules();
@@ -372,7 +373,7 @@
ConfigurationProperty emulateStackProperty =
properties.createConfiguration("emulateStack", false);
emulateStackProperty.setValue("TRUE");
- compiler.jprogram = new JProgram();
+ compiler.jprogram = new JProgram(new MinimalRebuildCache());
// Builds property provider classes and a property provider registrator to register them.
precompiler.buildPropertyProviderRegistrator(allRootTypes,
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 81c0357..d6a5d1f 100644
--- a/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java
+++ b/dev/core/test/com/google/gwt/dev/js/JsStackEmulatorTest.java
@@ -19,6 +19,7 @@
import com.google.gwt.core.ext.linker.SymbolData;
import com.google.gwt.core.ext.linker.impl.StandardSymbolData;
import com.google.gwt.dev.CompilerContext;
+import com.google.gwt.dev.MinimalRebuildCache;
import com.google.gwt.dev.PrecompileTaskOptions;
import com.google.gwt.dev.PrecompileTaskOptionsImpl;
import com.google.gwt.dev.cfg.BindingProperty;
@@ -227,7 +228,8 @@
PrecompileTaskOptions options = new PrecompileTaskOptionsImpl();
options.setOutput(JsOutputOption.PRETTY);
options.setRunAsyncEnabled(false);
- CompilerContext context = new CompilerContext.Builder().options(options).build();
+ CompilerContext context = new CompilerContext.Builder().options(options)
+ .minimalRebuildCache(new MinimalRebuildCache()).build();
ConfigProps config = new ConfigProps(Arrays.asList(recordFileNamesProp,
recordLineNumbersProp));
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
index 4975a71..b00f008 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
@@ -27,7 +27,12 @@
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.shared.impl.StringCase;
-import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
+import com.google.gwt.dev.jjs.ast.JCharLiteral;
+import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
+import com.google.gwt.dev.jjs.ast.JFloatLiteral;
+import com.google.gwt.dev.jjs.ast.JIntLiteral;
+import com.google.gwt.dev.jjs.ast.JLongLiteral;
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.base.Functions;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
@@ -138,7 +143,6 @@
*/
public static String asLiteral(Object value) throws IllegalArgumentException {
Class<?> clazz = value.getClass();
- JProgram jProgram = new JProgram();
if (clazz.isArray()) {
StringBuilder sb = new StringBuilder();
@@ -160,27 +164,27 @@
}
if (value instanceof Boolean) {
- return jProgram.getLiteralBoolean(((Boolean) value).booleanValue())
+ return JBooleanLiteral.get(((Boolean) value).booleanValue())
.toSource();
} else if (value instanceof Byte) {
- return jProgram.getLiteralInt(((Byte) value).byteValue()).toSource();
+ return JIntLiteral.get(((Byte) value).byteValue()).toSource();
} else if (value instanceof Character) {
- return jProgram.getLiteralChar(((Character) value).charValue())
+ return JCharLiteral.get(((Character) value).charValue())
.toSource();
} else if (value instanceof Class<?>) {
return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
} else if (value instanceof Double) {
- return jProgram.getLiteralDouble(((Double) value).doubleValue())
+ return JDoubleLiteral.get(((Double) value).doubleValue())
.toSource();
} else if (value instanceof Enum) {
return value.getClass().getCanonicalName() + "."
+ ((Enum<?>) value).name();
} else if (value instanceof Float) {
- return jProgram.getLiteralFloat(((Float) value).floatValue()).toSource();
+ return JFloatLiteral.get(((Float) value).floatValue()).toSource();
} else if (value instanceof Integer) {
- return jProgram.getLiteralInt(((Integer) value).intValue()).toSource();
+ return JIntLiteral.get(((Integer) value).intValue()).toSource();
} else if (value instanceof Long) {
- return jProgram.getLiteralLong(((Long) value).intValue()).toSource();
+ return JLongLiteral.get(((Long) value).intValue()).toSource();
} else if (value instanceof String) {
return '"' + Generator.escape((String) value) + '"';
} else {
diff --git a/user/test/com/google/gwt/dev/StrictModeTest.java b/user/test/com/google/gwt/dev/StrictModeTest.java
index 9671956..b9ef065 100644
--- a/user/test/com/google/gwt/dev/StrictModeTest.java
+++ b/user/test/com/google/gwt/dev/StrictModeTest.java
@@ -47,7 +47,8 @@
private CompilerContext compilerContext = new CompilerContext();
public StrictModeTest() {
- compilerContext = compilerContextBuilder.build();
+ compilerContext = compilerContextBuilder.minimalRebuildCache(new MinimalRebuildCache())
+ .build();
}
/**