/* * Copyright 2008 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.jjs.impl; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.dev.jjs.ast.JDeclaredType; import com.google.gwt.dev.jjs.ast.JField; import com.google.gwt.dev.jjs.ast.JMethod; import com.google.gwt.dev.jjs.ast.JProgram; import com.google.gwt.dev.util.Preconditions; import com.google.gwt.dev.util.Strings; import java.util.regex.Pattern; /** * Test case for testing Jjs optimizers. Adds a convenient Result class. */ public abstract class OptimizerTestBase extends JJSTestBase { protected boolean runDeadCodeElimination = false; protected final class Result { private final String returnType; private final String originalCode; private final boolean madeChanges; private final JProgram optimizedProgram; private final String methodName; public Result(JProgram optimizedProgram, String returnType, String methodName, String originalCode, boolean madeChanges) { this.optimizedProgram = optimizedProgram; this.returnType = returnType; this.methodName = methodName; this.originalCode = originalCode; this.madeChanges = madeChanges; } public void into(String... expected) throws UnableToCompleteException { // We can't compile expected code into non-main method. Preconditions.checkState(methodName.equals(MAIN_METHOD_NAME)); JProgram program = compileSnippet(returnType, Strings.join(expected, "\n")); String expectedSource = OptimizerTestBase.findMethod(program, methodName).getBody().toSource(); String actualSource = OptimizerTestBase.findMethod(optimizedProgram, methodName). getBody().toSource(); assertEquals(originalCode, expectedSource, actualSource); } public void intoString(String... expected) { String expectedSource = Strings.join(expected, "\n"); String actualSource = OptimizerTestBase.findMethod(optimizedProgram, methodName). getBody().toSource(); // Trim surrounding {} and unindent body once assertTrue(actualSource.startsWith("{")); assertTrue(actualSource.endsWith("}")); actualSource = actualSource.substring(1, actualSource.length() - 2).trim(); actualSource = Pattern.compile("^ ", Pattern.MULTILINE). matcher(actualSource).replaceAll(""); assertEquals(originalCode, expectedSource, actualSource); } public void noChange() { assertFalse(madeChanges); } public JMethod findMethod(String methodName) { return OptimizerTestBase.findMethod(optimizedProgram, methodName); } public JField findField(String fieldName) { return OptimizerTestBase.findField(optimizedProgram, "EntryPoint." + fieldName); } public JDeclaredType findClass(String className) { return OptimizerTestBase.findType(optimizedProgram, className); } } protected final Result optimize(final String returnType, final String... codeSnippet) throws UnableToCompleteException { return optimizeMethod(MAIN_METHOD_NAME, returnType, codeSnippet); } protected final Result optimizeMethod(final String methodName, final String mainMethodReturnType, final String... mainMethodSnippet) throws UnableToCompleteException { String snippet = Strings.join(mainMethodSnippet, "\n"); JProgram program = compileSnippet(mainMethodReturnType, snippet); JMethod method = findMethod(program, methodName); boolean madeChanges = optimizeMethod(program, method); if (madeChanges && runDeadCodeElimination) { DeadCodeElimination.exec(program); } return new Result(program, mainMethodReturnType, methodName, snippet, madeChanges); } protected abstract boolean optimizeMethod(JProgram program, JMethod method); }