blob: 8ba7d901a664086964f9aacd5e42cde78b34c045 [file] [log] [blame]
/*
* Copyright 2007 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.javac.typemodel;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracleException;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import junit.framework.TestCase;
/**
* Tests related to JClassType. See individual test methods to details.
*/
public class JClassTypeTest extends TestCase {
private final boolean logToConsole = false;
private final ModuleContext moduleContext = new ModuleContext(logToConsole
? new PrintWriterTreeLogger() : TreeLogger.NULL,
"com.google.gwt.dev.javac.typemodel.TypeOracleTest");
public JClassTypeTest() throws UnableToCompleteException {
}
public void testGetInheritableOrOverridableMethods()
throws TypeOracleException {
TypeOracle typeOracle = moduleContext.getOracle();
// TypeOracle typeOracle = buildOracleFromTestPackage(logger);
String[] noParams = new String[0];
String[] intObjectParams = new String[]{"int", "java.lang.Object"};
// Verify IA.
{
JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IA");
JMethod[] leafMethods = type.getOverridableMethods();
assertEquals(3, leafMethods.length);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IA", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IA", "ia", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IA", "foo", noParams);
}
// Verify IB.
{
JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IB");
JMethod[] leafMethods = type.getOverridableMethods();
assertEquals(5, leafMethods.length);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IB", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IB", "ia", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.IB", "ib", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.IB", "ib", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.IB", "foo", noParams);
}
// Verify IC.
{
JClassType type = typeOracle.getType("com.google.gwt.dev.javac.typemodel.test.IC");
JMethod[] leafMethods = type.getOverridableMethods();
assertEquals(7, leafMethods.length);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IC", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.IC", "ia", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.IC", "ib", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.IC", "ib", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.IC", "ic", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.IC", "ic", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.IC", "foo", noParams);
}
// Both overloads of ia are only declared in IA, so all searches should find
// them there.
{
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CA", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CB", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CC", "ia", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CA", "ia", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CB", "ia", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CC", "ia", intObjectParams);
}
// Both overloads of ib are declared in both IB and IC, so
// - searching for ib in CB will return IB
// - searching for ib in CC will return IC
{
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.CB", "ib", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.CC", "ib", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.CB", "ib", intObjectParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.CC", "ib", intObjectParams);
}
// Both overloads of ic are declared only in IC, but ic() is also declared
// in CB, so
// - searching for ic() in CB will return CB
// - searching for ic() in CC will return CB
// - searching for ic(int, Object) in CC will return IC
{
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CB",
"com.google.gwt.dev.javac.typemodel.test.CB", "ic", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CB",
"com.google.gwt.dev.javac.typemodel.test.CC", "ic", noParams);
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IC",
"com.google.gwt.dev.javac.typemodel.test.CC", "ic", intObjectParams);
}
// Both IA and IB define foo(), and searching for foo() on IC should return
// IB.foo(). This matters because IC also extends IA, so a naive algorithm
// for getLeafMethods() might prefer IA.foo() to IB.foo().
{
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IB",
"com.google.gwt.dev.javac.typemodel.test.IC", "foo", noParams);
}
// Both IA and CB define foo(), foo() being final in CB, so searching for
// foo() on CA should return IA.foo() as overridable, while searching for
// foo() on CB or CC should return CB.foo() as inheritable but not
// overridable.
{
assertMethodOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.IA",
"com.google.gwt.dev.javac.typemodel.test.CA", "foo", noParams);
assertMethodInheritableNotOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CB",
"com.google.gwt.dev.javac.typemodel.test.CB", "foo", noParams);
assertMethodInheritableNotOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CB",
"com.google.gwt.dev.javac.typemodel.test.CC", "foo", noParams);
// Check that we aren't including methods that aren't actually overridable
// (but are inheritable) because they are final (but non-private).
assertMethodInheritableNotOverridable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CA",
"com.google.gwt.dev.javac.typemodel.test.CA",
"caNotOverridableFinal", noParams);
// Check that we aren't including methods that aren't actually inheritable
// because they are private.
assertMethodNotInheritable(typeOracle,
"com.google.gwt.dev.javac.typemodel.test.CA",
"com.google.gwt.dev.javac.typemodel.test.CA",
"caNotOverridablePrivate", noParams);
}
}
private void assertMethodInheritableNotOverridable(TypeOracle typeOracle,
String expectedTypeName, String searchTypeName, String methodName,
String[] paramTypeNames) throws TypeOracleException {
assertInheritableOrOverridableMethod(true, false, typeOracle,
expectedTypeName, searchTypeName, methodName, paramTypeNames);
}
private void assertMethodNotInheritable(TypeOracle typeOracle,
String expectedTypeName, String searchTypeName, String methodName,
String[] paramTypeNames) throws TypeOracleException {
assertInheritableOrOverridableMethod(false, false, typeOracle,
expectedTypeName, searchTypeName, methodName, paramTypeNames);
}
private void assertMethodOverridable(TypeOracle typeOracle,
String expectedTypeName, String searchTypeName, String methodName,
String[] paramTypeNames) throws TypeOracleException {
assertInheritableOrOverridableMethod(true, true, typeOracle,
expectedTypeName, searchTypeName, methodName, paramTypeNames);
}
private void assertInheritableOrOverridableMethod(
boolean shouldBeInheritable, boolean shouldBeOverridable,
TypeOracle oracle, String expectedTypeName, String searchTypeName,
String methodName, String[] paramTypeNames) throws TypeOracleException {
JType[] paramTypes = new JType[paramTypeNames.length];
for (int i = 0; i < paramTypeNames.length; i++) {
String paramTypeName = paramTypeNames[i];
paramTypes[i] = oracle.parse(paramTypeName);
}
JClassType expectedType = oracle.getType(expectedTypeName);
JClassType searchType = oracle.getType(searchTypeName);
assertMethodInclusion(shouldBeInheritable,
searchType.getInheritableMethods(), methodName, expectedType,
paramTypes);
assertMethodInclusion(shouldBeOverridable,
searchType.getOverridableMethods(), methodName, expectedType,
paramTypes);
}
private void assertMethodInclusion(boolean shouldBeFound,
JMethod[] leafMethods, String methodName, JClassType expectedType,
JType[] paramTypes) {
boolean wasFound = false;
for (JMethod method : leafMethods) {
if (method.getName().equals(methodName)) {
if (method.hasParamTypes(paramTypes)) {
assertEquals(expectedType, method.getEnclosingType());
wasFound = true;
break;
}
}
}
if (shouldBeFound) {
if (wasFound) {
// Good. We wanted to find it and we did.
} else {
fail("Did not find expected method '" + methodName + "' on type '"
+ expectedType.getQualifiedSourceName() + "'");
}
} else {
// We want to *not* find it.
if (wasFound) {
fail("Did not expect to find method '" + methodName + "' on type '"
+ expectedType.getQualifiedSourceName() + "'");
} else {
// Good. We didn't want to find it and didn't.
}
}
}
}