blob: 57c8026563c653cb2f78c0373637cc10d7d7de39 [file] [log] [blame]
/*
* 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.core.ext.TreeLogger;
import com.google.gwt.dev.jjs.ast.JTypeOracle;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import junit.framework.TestCase;
import java.util.Map;
/**
* Tests for {@link MinimalRebuildCache}.
*/
public class MinimalRebuildCacheTest extends TestCase {
private MinimalRebuildCache minimalRebuildCache;
public void testComputeAndClearStale() {
// These three compilation units exist.
Map<String, Long> currentModifiedBySourcePath = new ImmutableMap.Builder<String, Long>().put(
"Foo.java", 0L).put("Bar.java", 0L).put("Baz.java", 0L).build();
minimalRebuildCache.recordDiskSourceResources(currentModifiedBySourcePath);
// They each contain a type and nested type.
StringAnalyzableTypeEnvironment typeEnvironment = minimalRebuildCache.getTypeEnvironment();
minimalRebuildCache.recordNestedTypeName("Foo", "Foo");
typeEnvironment.recordTypeEnclosesMethod("Foo", "Foo::$clinit()V");
minimalRebuildCache.recordNestedTypeName("Foo", "Foo$Inner");
typeEnvironment.recordTypeEnclosesMethod("Foo$Inner", "Foo$Inner::$clinit()V");
minimalRebuildCache.recordNestedTypeName("Bar", "Bar");
typeEnvironment.recordTypeEnclosesMethod("Bar", "Bar::$clinit()V");
minimalRebuildCache.recordNestedTypeName("Bar", "Bar$Inner");
typeEnvironment.recordTypeEnclosesMethod("Bar$Inner", "Bar$Inner::$clinit()V");
minimalRebuildCache.recordNestedTypeName("Baz", "Baz");
typeEnvironment.recordTypeEnclosesMethod("Baz", "Baz::$clinit()V");
minimalRebuildCache.recordNestedTypeName("Baz", "Baz$Inner");
typeEnvironment.recordTypeEnclosesMethod("Baz$Inner", "Baz$Inner::$clinit()V");
// There's some JS for each type.
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Foo", "Some Js for Foo");
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Foo$Inner", "Some Js for Foo");
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Bar", "Some Js for Bar");
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Bar$Inner", "Some Js for Bar");
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Baz", "Some Js for Baz");
minimalRebuildCache.setJsForType(TreeLogger.NULL, "Baz$Inner", "Some Js for Baz");
// Record that Bar references Foo and Baz subclasses Foo.
minimalRebuildCache.addTypeReference("Bar", "Foo");
typeEnvironment.recordMethodCallsMethod("Bar::start()", "Foo::run()");
typeEnvironment.recordStaticReferenceInMethod("Foo", "Bar::start()");
typeEnvironment.recordTypeEnclosesMethod("Bar", "Bar::start()");
typeEnvironment.recordTypeEnclosesMethod("Foo", "Foo::run()");
minimalRebuildCache.getImmediateTypeRelations().getImmediateSuperclassesByClass().put("Baz",
"Foo");
typeEnvironment.recordMethodCallsMethod("Foo::run()", "Baz::run()");
typeEnvironment.recordStaticReferenceInMethod("Baz", "Foo::run()");
typeEnvironment.recordTypeEnclosesMethod("Baz", "Baz::run()");
// Record that these types reference their inner classes.
minimalRebuildCache.addTypeReference("Foo", "Foo$Inner");
minimalRebuildCache.addTypeReference("Bar", "Bar$Inner");
minimalRebuildCache.addTypeReference("Baz", "Baz$Inner");
typeEnvironment.recordStaticReferenceInMethod("Bar$Inner", "Bar::start()");
typeEnvironment.recordStaticReferenceInMethod("Foo$Inner", "Foo::run()");
typeEnvironment.recordStaticReferenceInMethod("Baz$Inner", "Baz::run()");
// In the next compile only Foo is modified.
Map<String, Long> laterModifiedBySourcePath = new ImmutableMap.Builder<String, Long>().put(
"Foo.java", 9999L).put("Bar.java", 0L).put("Baz.java", 0L).build();
minimalRebuildCache.recordDiskSourceResources(laterModifiedBySourcePath);
// Ensure the types are known to be reachable.
minimalRebuildCache.setRootTypeNames(Sets.newHashSet("Foo", "Bar", "Baz"));
minimalRebuildCache.setEntryMethodNames(Lists.newArrayList("Bar::start()"));
minimalRebuildCache.computeReachableTypeNames();
// Request clearing of cache related to stale types.
minimalRebuildCache.computeAndClearStaleTypesCache(TreeLogger.NULL,
new JTypeOracle(null, minimalRebuildCache));
// Has the expected JS been cleared?
assertNull(minimalRebuildCache.getJs("Foo"));
assertNull(minimalRebuildCache.getJs("Foo$Inner"));
assertNull(minimalRebuildCache.getJs("Bar"));
assertNull(minimalRebuildCache.getJs("Baz"));
assertNotNull(minimalRebuildCache.getJs("Bar$Inner"));
assertNotNull(minimalRebuildCache.getJs("Baz$Inner"));
}
public void testComputeDeletedTypes() {
// These three compilation units exist.
Map<String, Long> currentModifiedBySourcePath = new ImmutableMap.Builder<String, Long>().put(
"Foo.java", 0L).put("Bar.java", 0L).put("Baz.java", 0L).build();
minimalRebuildCache.recordDiskSourceResources(currentModifiedBySourcePath);
// They each contain a type and nested type.
minimalRebuildCache.recordNestedTypeName("Foo", "Foo");
minimalRebuildCache.recordNestedTypeName("Foo", "Foo$Inner");
minimalRebuildCache.recordNestedTypeName("Bar", "Bar");
minimalRebuildCache.recordNestedTypeName("Bar", "Bar$Inner");
minimalRebuildCache.recordNestedTypeName("Baz", "Baz");
minimalRebuildCache.recordNestedTypeName("Baz", "Baz$Inner");
// In the next compile it turns out there are fewer compilation units, Baz is gone.
Map<String, Long> laterModifiedBySourcePath =
new ImmutableMap.Builder<String, Long>().put("Foo.java", 0L).put("Bar.java", 0L).build();
minimalRebuildCache.recordDiskSourceResources(laterModifiedBySourcePath);
// Is the correct deleted type set calculated?
assertEquals(Sets.newHashSet("Baz", "Baz$Inner"),
minimalRebuildCache.computeDeletedTypeNames());
}
@Override
protected void setUp() throws Exception {
super.setUp();
minimalRebuildCache = new MinimalRebuildCache();
}
}