Fixed a cause of non-deterministic builds.
Change-Id: I1304b00048830ef7f93427c2f4628cad5b81a7dd
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 8b252cf..9703b96 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
@@ -26,8 +26,8 @@
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.collect.HashMultiset;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMultiset;
+import com.google.gwt.thirdparty.guava.common.collect.LinkedHashMultiset;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Multiset;
@@ -115,7 +115,7 @@
// TODO(rluble): Maybe this pass should insert the defineClass in Java.
private class RuntimeTypeCollectorVisitor extends JVisitor {
- private final Multiset<JReferenceType> typesRequiringRuntimeIds = HashMultiset.create();
+ private final Multiset<JReferenceType> typesRequiringRuntimeIds = LinkedHashMultiset.create();
@Override
public void endVisit(JRuntimeTypeReference x, Context ctx) {
diff --git a/dev/core/test/com/google/gwt/dev/CompilerTest.java b/dev/core/test/com/google/gwt/dev/CompilerTest.java
index ed988fc..af9a5d0 100644
--- a/dev/core/test/com/google/gwt/dev/CompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/CompilerTest.java
@@ -16,17 +16,24 @@
package com.google.gwt.dev;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.jjs.JsOutputOption;
+import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.SourceLevel;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.util.tools.Utility;
import java.io.File;
+import java.io.IOException;
+import java.util.Set;
/**
* Test for {@link Compiler}.
*/
public class CompilerTest extends ArgProcessorTestBase {
+ public static final String GWT_PERSISTENTUNITCACHE = "gwt.persistentunitcache";
private final Compiler.ArgProcessor argProcessor;
private final CompilerOptionsImpl options = new CompilerOptionsImpl();
@@ -125,4 +132,51 @@
assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.6b3"));
assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.7b3"));
}
+
+ public void testDeterministicBuild_Draft() throws UnableToCompleteException, IOException {
+ final CompilerOptionsImpl options = new CompilerOptionsImpl();
+ options.setOptimizationLevel(0);
+ assertDeterministicBuild(options);
+ }
+
+ public void testDeterministicBuild_Optimized() throws UnableToCompleteException, IOException {
+ final CompilerOptionsImpl options = new CompilerOptionsImpl();
+ options.setOptimizationLevel(9);
+ assertDeterministicBuild(options);
+ }
+
+ public void assertDeterministicBuild(CompilerOptions options)
+ throws UnableToCompleteException, IOException {
+ File firstCompileWorkDir = Utility.makeTemporaryDirectory(null, "hellowork");
+ File secondCompileWorkDir = Utility.makeTemporaryDirectory(null, "hellowork");
+ String oldPersistentUnitCacheValue = System.setProperty(GWT_PERSISTENTUNITCACHE, "false");
+ try {
+ options.addModuleName("com.google.gwt.sample.hello.Hello");
+ options.setWarDir(new File(firstCompileWorkDir, "war"));
+ options.setExtraDir(new File(firstCompileWorkDir, "extra"));
+ PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
+ logger.setMaxDetail(TreeLogger.ERROR);
+
+ // Run the compiler once here.
+ new Compiler(options).run(logger);
+ Set<String> firstTimeOutput =
+ Sets.newHashSet(new File(options.getWarDir() + "/hello").list());
+
+ options.setWarDir(new File(secondCompileWorkDir, "war"));
+ options.setExtraDir(new File(secondCompileWorkDir, "extra"));
+ // Run the compiler for a second time here.
+ new Compiler(options).run(logger);
+ Set<String> secondTimeOutput =
+ Sets.newHashSet(new File(options.getWarDir() + "/hello").list());
+
+ // It is only necessary to check that the filenames in the output directory are the same
+ // because the names of the files for the JavaScript outputs are the hash of its contents.
+ assertEquals("First and second compile produced different outputs",
+ firstTimeOutput, secondTimeOutput);
+ } finally {
+ System.setProperty(GWT_PERSISTENTUNITCACHE, oldPersistentUnitCacheValue);
+ Util.recursiveDelete(firstCompileWorkDir, false);
+ Util.recursiveDelete(secondCompileWorkDir, false);
+ }
+ }
}