/* * 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.javac.typemodel; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.dev.javac.typemodel.test.GenericClass; import com.google.gwt.dev.javac.typemodel.test.GenericClassWithDependentTypeBounds; import com.google.gwt.dev.javac.typemodel.test.GenericClassWithTypeBound; import com.google.gwt.dev.util.log.PrintWriterTreeLogger; import junit.framework.TestCase; import java.io.Serializable; /** * Tests for {@link JGenericType}. */ public class JGenericTypeTest 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 JGenericTypeTest() throws UnableToCompleteException { } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getTypeParameters()}. * This test goes beyond * {@link com.google.gwt.core.ext.typeinfo.JGenericTypeTest#testGetTypeParameters()} * by testing generic types that have type parameters which are dependent on * one another. * * NOTE: This test does not make use of the * {@link com.google.gwt.core.ext.typeinfo.JGenericTypeTest#getTestType()} * method. The test types used are: * {@link GenericClassWithDependentTypeBounds} * {@link GenericClassWithTypeBound} * * @throws NotFoundException */ public void testGetDependentTypeParameters() throws NotFoundException { TypeOracle oracle = moduleContext.getOracle(); // Get the generic type JClassType type = oracle.getType(GenericClassWithDependentTypeBounds.class.getName()); JGenericType genericType = type.isGenericType(); assertNotNull(genericType); // Get its type parameters JTypeParameter[] typeParameters = genericType.getTypeParameters(); assertEquals(2, typeParameters.length); // Examine the first type parameter. Its name should be 'C'. JTypeParameter typeParameter = typeParameters[0]; assertEquals("C", typeParameter.getName()); // Check the bound of the first type parameter. It should be a single // upper bound. JClassType[] genericTypeBounds = typeParameter.getBounds(); assertEquals(1, genericTypeBounds.length); // Check to see that the upper bound is a parameterized type. JClassType upperBoundType = genericTypeBounds[0]; JParameterizedType upperBoundParameterizedType = upperBoundType.isParameterized(); assertNotNull(upperBoundParameterizedType); // Examine the parameterized type. Its name should be // 'GenericClassWithTypeBound'. The base type of the parameterized type // should be a reference to the class 'GenericClassWithTypeBound'. assertEquals("GenericClassWithTypeBound", upperBoundParameterizedType.getName()); assertEquals(upperBoundParameterizedType.getBaseType(), oracle.getType(GenericClassWithTypeBound.class.getName())); // Check the type arguments for the parameterized type. There should be a // single type argument. JClassType[] typeArgs = upperBoundParameterizedType.getTypeArgs(); assertEquals(1, typeArgs.length); // Examine the first type argument. It should be a type parameter. JClassType typeArg = typeArgs[0]; JTypeParameter typeArgTypeParameter = typeArg.isTypeParameter(); assertNotNull(typeArgTypeParameter); // Check the name of the type parameter. It should be 'M'. assertEquals("M", typeArgTypeParameter.getName()); // Check the bound of the type parameter. It should have a single upper // bound. JClassType[] typeArgBounds = typeArgTypeParameter.getBounds(); assertEquals(1, typeArgBounds.length); // Verify that the bound type is actually a reference to // java.io.Serializable. JClassType typeArgUpperBoundType = typeArgBounds[0]; assertEquals(typeArgUpperBoundType, oracle.getType(Serializable.class.getName())); // Now look at the second type parameter on the generic type. It should // be identical to the type argument of the the first type parameter // (remember, the first type parameter was a paramaterized type). JTypeParameter secondTypeParameter = typeParameters[1]; assertEquals(secondTypeParameter, typeArgTypeParameter); } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getErasedType()}. * * @throws NotFoundException */ public void testGetErasedType() throws NotFoundException { JGenericType genericClass = getTestType(); assertEquals(genericClass.getRawType(), genericClass.getErasedType()); } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getRawType()}. * * @throws NotFoundException */ public void testGetRawType() throws NotFoundException { JGenericType genericClass = getTestType(); JDelegatingClassTypeTestBase.validateTypeSubstitution(genericClass, genericClass.getRawType(), new Substitution() { public JClassType getSubstitution(JClassType type) { return type.getErasedType(); } }); } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getTypeParameters()}. * * @throws NotFoundException */ public void testGetTypeParameters() throws NotFoundException { JGenericType genericType = getTestType(); JTypeParameter[] typeParameters = genericType.getTypeParameters(); assertEquals(1, typeParameters.length); JTypeParameter typeParameter = typeParameters[0]; assertEquals("T", typeParameter.getName()); JClassType[] bounds = typeParameter.getBounds(); assertEquals(1, bounds.length); assertEquals( moduleContext.getOracle().getType(Serializable.class.getName()), bounds[0]); } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#isAssignableFrom(JClassType)} * . * * @throws NotFoundException */ public void testIsAssignableFrom() throws NotFoundException { JGenericType genericType = getTestType(); // Check that the generic type's superclass is assignable from the generic // type assertTrue(genericType.getSuperclass().isAssignableFrom(genericType)); // Check that each implemented interface is assignable from the generic type JClassType[] implementedInterfaces = genericType.getImplementedInterfaces(); for (JClassType implementedInterface : implementedInterfaces) { assertTrue(implementedInterface.isAssignableFrom(genericType)); assertTrue(implementedInterface.isAssignableFrom(genericType.getRawType())); } } /** * Test method for * {@link com.google.gwt.core.ext.typeinfo.JGenericType#isAssignableTo(JClassType)} * . * * @throws NotFoundException */ public void testIsAssignableTo() throws NotFoundException { JGenericType genericType = getTestType(); // Check that generic type is assignable to its superclass assertTrue(genericType.isAssignableTo(genericType.getSuperclass())); // Check that the generic class is assignable to any implemented interface JClassType[] implementedInterfaces = genericType.getImplementedInterfaces(); for (JClassType implementedInterface : implementedInterfaces) { assertTrue(genericType.isAssignableTo(implementedInterface)); if (implementedInterface.isParameterized() != null) { assertTrue(genericType.isAssignableTo(implementedInterface.isParameterized().getRawType())); } } } /** * Returns the generic version of {@link GenericClass}. */ protected JGenericType getTestType() throws NotFoundException { JClassType type = moduleContext.getOracle().getType( GenericClass.class.getName()); JGenericType genericType = type.isGenericType(); assertNotNull(genericType); return genericType; } }