This repository has been archived on 2023-06-18. You can view files and clone it, but cannot push or open issues or pull requests.
ima02/resources/defects4j-checkout-closure-1f/test/com/google/javascript/jscomp/PhaseOptimizerTest.java

227 lines
6.9 KiB
Java
Raw Permalink Normal View History

2023-04-25 11:33:41 +00:00
/*
* Copyright 2009 The Closure Compiler Authors.
*
* 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.javascript.jscomp;
import com.google.common.collect.Lists;
import com.google.javascript.jscomp.CompilerOptions.TracerMode;
import com.google.javascript.jscomp.PhaseOptimizer.Loop;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;
import junit.framework.TestCase;
import java.util.List;
import java.util.Random;
/**
* Tests for {@link PhaseOptimizer}.
* @author nicksantos@google.com (Nick Santos)
*/
public class PhaseOptimizerTest extends TestCase {
private final List<String> passesRun = Lists.newArrayList();
private PhaseOptimizer optimizer;
private Compiler compiler;
private PerformanceTracker tracker;
@Override
public void setUp() {
passesRun.clear();
compiler = new Compiler();
compiler.initCompilerOptionsIfTesting();
tracker = new PerformanceTracker(
new Node(Token.BLOCK), TracerMode.TIMING_ONLY);
optimizer = new PhaseOptimizer(compiler, tracker, null);
}
public void testOneRun() {
addOneTimePass("x");
assertPasses("x");
}
public void testLoop1() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 0);
assertPasses("x");
}
public void testLoop2() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 3);
assertPasses("x", "x", "x", "x");
}
public void testLoop3() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 3);
addLoopedPass(loop, "y", 1);
assertPasses("x", "y", "x", "y", "x", "x", "y");
}
public void testNotInfiniteLoop() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", PhaseOptimizer.MAX_LOOPS - 1);
optimizer.process(null, null);
assertEquals("There should be no errors.", 0, compiler.getErrorCount());
}
public void testInfiniteLoop() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", PhaseOptimizer.MAX_LOOPS + 1);
try {
optimizer.process(null, null);
fail("Expected RuntimeException");
} catch (RuntimeException e) {
assertTrue(e.getMessage().contains(PhaseOptimizer.OPTIMIZE_LOOP_ERROR));
}
}
public void testCombined() {
addOneTimePass("a");
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 3);
addLoopedPass(loop, "y", 1);
addOneTimePass("z");
assertPasses("a", "x", "y", "x", "y", "x", "x", "y", "z");
}
public void testSanityCheck() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 1);
addOneTimePass("z");
optimizer.setSanityCheck(
createPassFactory("sanity", createPass("sanity", 0), false));
assertPasses("x", "sanity", "x", "sanity", "z", "sanity");
}
public void testConsumption1() {
optimizer.consume(
Lists.newArrayList(
createPassFactory("a", 0, true),
createPassFactory("b", 1, false),
createPassFactory("c", 2, false),
createPassFactory("d", 1, false),
createPassFactory("e", 1, true),
createPassFactory("f", 0, true)));
assertPasses("a", "b", "c", "d", "b", "c", "d", "c", "b", "d", "e", "f");
}
public void testConsumption2() {
optimizer.consume(
Lists.newArrayList(
createPassFactory("a", 2, false),
createPassFactory("b", 1, true),
createPassFactory("c", 1, false)));
assertPasses("a", "a", "a", "b", "c", "c");
}
public void testConsumption3() {
optimizer.consume(
Lists.newArrayList(
createPassFactory("a", 2, true),
createPassFactory("b", 0, false),
createPassFactory("c", 0, false)));
assertPasses("a", "b", "c");
}
public void testDuplicateLoop() {
Loop loop = optimizer.addFixedPointLoop();
addLoopedPass(loop, "x", 1);
try {
addLoopedPass(loop, "x", 1);
fail("Expected exception");
} catch (IllegalArgumentException e) {}
}
public void testPassOrdering() {
Loop loop = optimizer.addFixedPointLoop();
List<String> optimalOrder = Lists.newArrayList(
PhaseOptimizer.OPTIMAL_ORDER);
Random random = new Random();
while (optimalOrder.size() > 0) {
addLoopedPass(
loop, optimalOrder.remove(random.nextInt(optimalOrder.size())), 0);
}
optimizer.process(null, null);
assertEquals(PhaseOptimizer.OPTIMAL_ORDER, passesRun);
}
public void testProgress() {
final List<Double> progressList = Lists.newArrayList();
compiler = new Compiler() {
@Override void setProgress(double p, String name) {
progressList.add(p);
}
};
compiler.initCompilerOptionsIfTesting();
optimizer = new PhaseOptimizer(compiler, null,
new PhaseOptimizer.ProgressRange(0, 100));
addOneTimePass("x1");
addOneTimePass("x2");
addOneTimePass("x3");
addOneTimePass("x4");
optimizer.process(null, null);
assertEquals(4, progressList.size());
assertEquals(25, Math.round(progressList.get(0)));
assertEquals(50, Math.round(progressList.get(1)));
assertEquals(75, Math.round(progressList.get(2)));
assertEquals(100, Math.round(progressList.get(3)));
}
public void assertPasses(String ... names) {
optimizer.process(null, null);
assertEquals(Lists.newArrayList(names), passesRun);
}
private void addOneTimePass(String name) {
optimizer.addOneTimePass(
createPassFactory(name, 0, true));
}
private void addLoopedPass(Loop loop, String name, int numChanges) {
loop.addLoopedPass(
createPassFactory(name, numChanges, false));
}
private PassFactory createPassFactory(
String name, int numChanges, boolean isOneTime) {
return createPassFactory(name, createPass(name, numChanges), isOneTime);
}
private PassFactory createPassFactory(
String name, final CompilerPass pass, boolean isOneTime) {
return new PassFactory(name, isOneTime) {
@Override
protected CompilerPass create(AbstractCompiler compiler) {
return pass;
}
};
}
private CompilerPass createPass(final String name, int numChanges) {
final int[] numChangesClosure = new int[] {numChanges};
return new CompilerPass() {
@Override public void process(Node externs, Node root) {
passesRun.add(name);
if (numChangesClosure[0] > 0) {
compiler.reportCodeChange();
numChangesClosure[0] = numChangesClosure[0] - 1;
}
}
};
}
}