package net.bytebuddy.description.type;
import net.bytebuddy.description.TypeVariableSource;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.dynamic.loading.ByteArrayClassLoader;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.test.utility.JavaVersionRule;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.objectweb.asm.*;
import java.io.IOException;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import static net.bytebuddy.matcher.ElementMatchers.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
public abstract class AbstractTypeDescriptionGenericTest {
@Rule
public MethodRule javaVersionRule = new JavaVersionRule();
private static final String FOO = "foo", BAR = "bar", QUX = "qux", BAZ = "baz";
private static final String T = "T", S = "S", U = "U", V = "V";
private static final String TYPE_ANNOTATION = "net.bytebuddy.test.precompiled.TypeAnnotation";
private static final String OTHER_TYPE_ANNOTATION = "net.bytebuddy.test.precompiled.OtherTypeAnnotation";
private static final String TYPE_ANNOTATION_SAMPLES = "net.bytebuddy.test.precompiled.TypeAnnotationSamples";
private static final String TYPE_ANNOTATION_OTHER_SAMPLES = "net.bytebuddy.test.precompiled.TypeAnnotationOtherSamples";
protected abstract TypeDescription.Generic describeType(Field field);
protected abstract TypeDescription.Generic describeReturnType(Method method);
protected abstract TypeDescription.Generic describeParameterType(Method method, int index);
protected abstract TypeDescription.Generic describeExceptionType(Method method, int index);
protected abstract TypeDescription.Generic describeSuperClass(Class<?> type);
protected abstract TypeDescription.Generic describeInterfaceType(Class<?> type, int index);
@Test
public void testNonGenericTypeOwnerType() throws Exception {
assertThat(describeType(NonGeneric.class.getDeclaredField(FOO)).getOwnerType(), nullValue(TypeDescription.Generic.class));
assertThat(describeType(NonGeneric.class.getDeclaredField(BAR)).getOwnerType(), is(TypeDefinition.Sort.describe(NonGeneric.class)));
}
@Test(expected = IllegalStateException.class)
public void testNonGenericTypeNoTypeArguments() throws Exception {
describeType(NonGeneric.class.getDeclaredField(FOO)).getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testNonGenericTypeNoBindLocation() throws Exception {
describeType(NonGeneric.class.getDeclaredField(FOO)).findBindingOf(mock(TypeDescription.Generic.class));
}
@Test(expected = IllegalStateException.class)
public void testNonGenericTypeNoUpperBounds() throws Exception {
describeType(NonGeneric.class.getDeclaredField(FOO)).getUpperBounds();
}
@Test(expected = IllegalStateException.class)
public void testNonGenericTypeNoLowerBounds() throws Exception {
describeType(NonGeneric.class.getDeclaredField(FOO)).getLowerBounds();
}
@Test(expected = IllegalStateException.class)
public void testNonGenericTypeNoSymbol() throws Exception {
describeType(NonGeneric.class.getDeclaredField(FOO)).getSymbol();
}
@Test
public void testSimpleParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(SimpleParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getActualName(), is(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription, is(TypeDefinition.Sort.describe(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription, CoreMatchers.not(TypeDefinition.Sort.describe(SimpleGenericArrayType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().asErasure().represents(String.class), is(true));
assertThat(typeDescription.getTypeName(), is(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getOwnerType(), nullValue(TypeDescription.Generic.class));
}
@Test
public void testParameterizedTypeIterator() throws Exception {
TypeDescription.Generic typeDescription = describeType(SimpleParameterizedType.class.getDeclaredField(FOO));
Iterator<TypeDefinition> iterator = typeDescription.iterator();
assertThat(iterator.hasNext(), is(true));
assertThat(iterator.next(), is((TypeDefinition) typeDescription));
assertThat(iterator.hasNext(), is(false));
}
@Test(expected = IllegalStateException.class)
public void testParameterizedTypeNoComponentType() throws Exception {
describeType(SimpleParameterizedType.class.getDeclaredField(FOO)).getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testParameterizedTypeNoVariableSource() throws Exception {
describeType(SimpleParameterizedType.class.getDeclaredField(FOO)).getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testParameterizedTypeNoSymbol() throws Exception {
describeType(SimpleParameterizedType.class.getDeclaredField(FOO)).getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testParameterizedTypeNoUpperBounds() throws Exception {
describeType(SimpleParameterizedType.class.getDeclaredField(FOO)).getUpperBounds();
}
@Test(expected = IllegalStateException.class)
public void testParameterizedTypeNoLowerBounds() throws Exception {
describeType(SimpleParameterizedType.class.getDeclaredField(FOO)).getLowerBounds();
}
@Test
public void testUpperBoundWildcardParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getActualName(), is(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription,
is(TypeDefinition.Sort.describe(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription,
CoreMatchers.not(TypeDefinition.Sort.describe(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.WILDCARD));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().asErasure().represents(String.class), is(true));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().size(), is(0));
assertThat(typeDescription.getTypeName(), is(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoComponentType() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoOwnerType() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getOwnerType();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoVariableSource() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoSymbol() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoErasure() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().asErasure();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoStackSize() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getStackSize();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoSuperClass() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSuperClass();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoInterfaces() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getInterfaces();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoFields() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredFields();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoMethods() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredMethods();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardParameterizedTypeNoIterator() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().iterator();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardTypeNoTypeArguments() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testUpperBoundWildcardTypeNoBindLocation() throws Exception {
describeType(UpperBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testLowerBoundWildcardParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getActualName(), is(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription,
is(TypeDefinition.Sort.describe(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription,
CoreMatchers.not(TypeDefinition.Sort.describe(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.WILDCARD));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().getOnly().asErasure().represents(String.class), is(true));
assertThat(typeDescription.getTypeName(), is(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoComponentType() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoOwnerType() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getOwnerType();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoVariableSource() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoSymbol() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoErasure() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().asErasure();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoStackSize() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getStackSize();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoSuperClass() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSuperClass();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoInterfaces() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getInterfaces();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoFields() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredFields();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoMethods() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredMethods();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardParameterizedTypeNoIterator() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().iterator();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardTypeNoTypeArguments() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testLowerBoundWildcardTypeNoBindLocation() throws Exception {
describeType(LowerBoundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testUnboundWildcardParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getActualName(), is(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription,
is(TypeDefinition.Sort.describe(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription,
CoreMatchers.not(TypeDefinition.Sort.describe(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.WILDCARD));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().asErasure().represents(Object.class), is(true));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().size(), is(0));
assertThat(typeDescription.getTypeName(), is(UnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoComponentType() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoOwnerType() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getOwnerType();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoVariableSource() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoSymbol() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoErasure() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().asErasure();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoStackSize() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getStackSize();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoSuperClass() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSuperClass();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardParameterizedTypeNoInterfaces() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getInterfaces();
}
@Test(expected = IllegalStateException.class)
public void testUnboundBoundWildcardParameterizedTypeNoFields() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredFields();
}
@Test(expected = IllegalStateException.class)
public void testUnboundBoundWildcardParameterizedTypeNoMethods() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredMethods();
}
@Test(expected = IllegalStateException.class)
public void testUnboundBoundWildcardParameterizedTypeNoIterator() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().iterator();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardTypeNoTypeArguments() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testUnboundWildcardTypeNoBindLocation() throws Exception {
describeType(UnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testExplicitlyUnboundWildcardParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getActualName(),
is(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(),
is(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(),
is(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription,
is(TypeDefinition.Sort.describe(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription,
CoreMatchers.not(TypeDefinition.Sort.describe(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.WILDCARD));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getUpperBounds().getOnly().asErasure().represents(Object.class), is(true));
assertThat(typeDescription.getTypeArguments().getOnly().getLowerBounds().size(), is(0));
assertThat(typeDescription.getTypeName(), is(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoComponentType() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoOwnerType() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getOwnerType();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoVariableSource() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoSymbol() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoErasure() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().asErasure();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoStackSize() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getStackSize();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoSuperClass() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getSuperClass();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardParameterizedTypeNoInterfaces() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getInterfaces();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundBoundWildcardParameterizedTypeNoFields() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredFields();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundBoundWildcardParameterizedTypeNoMethods() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getDeclaredMethods();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundBoundWildcardParameterizedTypeNoIterator() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().iterator();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardTypeNoTypeArguments() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testExplicitlyUnboundWildcardTypeNoBindLocation() throws Exception {
describeType(ExplicitlyUnboundWildcardParameterizedType.class.getDeclaredField(FOO)).getTypeArguments().getOnly().findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testNestedParameterizedType() throws Exception {
TypeDescription.Generic typeDescription = describeType(NestedParameterizedType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().getOnly().getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().getOnly().getTypeArguments().getOnly().asErasure().represents(Foo.class), is(true));
}
@Test
public void testGenericArrayType() throws Exception {
TypeDescription.Generic typeDescription = describeType(SimpleGenericArrayType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getDeclaredFields().size(), is(0));
assertThat(typeDescription.getDeclaredMethods().size(), is(0));
assertThat(typeDescription.getSuperClass(), is(TypeDescription.Generic.OBJECT));
assertThat(typeDescription.getInterfaces(), is(TypeDescription.ARRAY_INTERFACES));
assertThat(typeDescription.getActualName(), is(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription, is(TypeDefinition.Sort.describe(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription, CoreMatchers.not(TypeDefinition.Sort.describe(SimpleGenericArrayType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getComponentType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getComponentType().getTypeArguments().size(), is(1));
assertThat(typeDescription.getComponentType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getComponentType().getTypeArguments().getOnly().asErasure().represents(String.class), is(true));
assertThat(typeDescription.getTypeName(), is(SimpleGenericArrayType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test
public void testGenericArrayTypeIterator() throws Exception {
TypeDescription.Generic typeDescription = describeType(SimpleGenericArrayType.class.getDeclaredField(FOO));
Iterator<TypeDefinition> iterator = typeDescription.iterator();
assertThat(iterator.hasNext(), is(true));
assertThat(iterator.next(), is((TypeDefinition) typeDescription));
assertThat(iterator.hasNext(), is(true));
assertThat(iterator.next(), is((TypeDefinition) TypeDescription.OBJECT));
assertThat(iterator.hasNext(), is(false));
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoVariableSource() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoSymbol() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoUpperBounds() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).getUpperBounds();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoLowerBounds() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).getLowerBounds();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoTypeArguments() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayTypeNoBindLocation() throws Exception {
describeType(SimpleGenericArrayType.class.getDeclaredField(FOO)).findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testGenericArrayOfGenericComponentType() throws Exception {
TypeDescription.Generic typeDescription = describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getDeclaredFields().size(), is(0));
assertThat(typeDescription.getDeclaredMethods().size(), is(0));
assertThat(typeDescription.getOwnerType(), nullValue(TypeDescription.Generic.class));
assertThat(typeDescription.getSuperClass(), is(TypeDescription.Generic.OBJECT));
assertThat(typeDescription.getInterfaces(), is(TypeDescription.ARRAY_INTERFACES));
assertThat(typeDescription.getActualName(), is(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription, is(TypeDefinition.Sort.describe(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription, CoreMatchers.not(TypeDefinition.Sort.describe(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getComponentType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getComponentType().getTypeArguments().size(), is(1));
assertThat(typeDescription.getComponentType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getComponentType().getTypeArguments().getOnly().asErasure().represents(String.class), is(true));
assertThat(typeDescription.getTypeName(), is(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO).getGenericType().toString()));
}
@Test
public void testGenericArrayOfGenericComponentTypeIterator() throws Exception {
TypeDescription.Generic typeDescription = describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO));
Iterator<TypeDefinition> iterator = typeDescription.iterator();
assertThat(iterator.hasNext(), is(true));
assertThat(iterator.next(), is((TypeDefinition) typeDescription));
assertThat(iterator.hasNext(), is(true));
assertThat(iterator.next(), is((TypeDefinition) TypeDescription.OBJECT));
assertThat(iterator.hasNext(), is(false));
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayOfGenericComponentTypeNoVariableSource() throws Exception {
describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO)).getTypeVariableSource();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayOfGenericComponentTypeNoSymbol() throws Exception {
describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO)).getSymbol();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayOfGenericComponentTypeNoUpperBounds() throws Exception {
describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO)).getUpperBounds();
}
@Test(expected = IllegalStateException.class)
public void testGenericArrayOfGenericComponentTypeNoLowerBounds() throws Exception {
describeType(GenericArrayOfGenericComponentType.class.getDeclaredField(FOO)).getLowerBounds();
}
@Test
public void testTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(SimpleTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getActualName(), is(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeName(), is(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.toString(), is(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.hashCode(),
is(TypeDefinition.Sort.describe(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType()).hashCode()));
assertThat(typeDescription, is(TypeDefinition.Sort.describe(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType())));
assertThat(typeDescription,
CoreMatchers.not(TypeDefinition.Sort.describe(SimpleTypeVariableType.class.getDeclaredField(FOO).getType())));
assertThat(typeDescription, CoreMatchers.not(new Object()));
assertThat(typeDescription.equals(null), is(false));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getUpperBounds().size(), is(1));
assertThat(typeDescription.getUpperBounds().getOnly(), is(TypeDescription.Generic.OBJECT));
assertThat(typeDescription.getUpperBounds().getOnly().getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getTypeName(), is(SimpleTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
MatcherAssert.assertThat(typeDescription.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(SimpleTypeVariableType.class)));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().size(), is(1));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().getOnly(), is(typeDescription));
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableNoLowerBounds() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getLowerBounds();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableNoComponentType() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getComponentType();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableNoOwnerType() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getOwnerType();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableTypeNoSuperClass() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getSuperClass();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableTypeNoInterfaceTypes() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getInterfaces();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableTypeNoFields() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getDeclaredFields();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableTypeNoMethods() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getDeclaredMethods();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableTypeNoIterator() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).iterator();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableNoTypeArguments() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).getTypeArguments();
}
@Test(expected = IllegalStateException.class)
public void testTypeVariableNoBindLocation() throws Exception {
describeType(SimpleTypeVariableType.class.getDeclaredField(FOO)).findBindingOf(mock(TypeDescription.Generic.class));
}
@Test
public void testSingleUpperBoundTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(SingleUpperBoundTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getUpperBounds().size(), is(1));
assertThat(typeDescription.getUpperBounds().getOnly(), is((TypeDefinition) new TypeDescription.ForLoadedType(String.class)));
assertThat(typeDescription.getUpperBounds().getOnly().getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getTypeName(), is(SingleUpperBoundTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(SingleUpperBoundTypeVariableType.class)));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().size(), is(1));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().getOnly(), is(typeDescription));
}
@Test
public void testMultipleUpperBoundTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(MultipleUpperBoundTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getUpperBounds().size(), is(3));
assertThat(typeDescription.getUpperBounds().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(String.class)));
assertThat(typeDescription.getUpperBounds().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(typeDescription.getUpperBounds().get(2), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(typeDescription.getTypeName(), is(MultipleUpperBoundTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(MultipleUpperBoundTypeVariableType.class)));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().size(), is(1));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().getOnly(), is(typeDescription));
}
@Test
public void testInterfaceOnlyMultipleUpperBoundTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(InterfaceOnlyMultipleUpperBoundTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getUpperBounds().size(), is(2));
assertThat(typeDescription.getUpperBounds().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(typeDescription.getUpperBounds().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(typeDescription.getTypeName(), is(InterfaceOnlyMultipleUpperBoundTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(InterfaceOnlyMultipleUpperBoundTypeVariableType.class)));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().size(), is(1));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().getOnly(), is(typeDescription));
}
@Test
public void testShadowedTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeReturnType(ShadowingTypeVariableType.class.getDeclaredMethod(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getUpperBounds().size(), is(1));
assertThat(typeDescription.getUpperBounds().getOnly(), is(TypeDescription.Generic.OBJECT));
assertThat(typeDescription.getTypeName(), is(ShadowingTypeVariableType.class.getDeclaredMethod(FOO).getGenericReturnType().toString()));
assertThat(typeDescription.getTypeVariableSource(), is((TypeVariableSource) new MethodDescription.ForLoadedMethod(ShadowingTypeVariableType.class.getDeclaredMethod(FOO))));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().size(), is(1));
assertThat(typeDescription.getTypeVariableSource().getTypeVariables().getOnly(), is(typeDescription));
}
@Test
public void testNestedTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(NestedTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getTypeName(), is(NestedTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getTypeArguments().size(), is(0));
Type ownerType = ((ParameterizedType) NestedTypeVariableType.class.getDeclaredField(FOO).getGenericType()).getOwnerType();
assertThat(typeDescription.getOwnerType(), is(TypeDefinition.Sort.describe(ownerType)));
assertThat(typeDescription.getOwnerType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getOwnerType().getTypeArguments().size(), is(1));
assertThat(typeDescription.getOwnerType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getOwnerType().getTypeArguments().getOnly().getSymbol(), is(T));
}
@Test
public void testNestedSpecifiedTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(NestedSpecifiedTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getTypeName(), is(NestedSpecifiedTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getTypeArguments().size(), is(0));
Type ownerType = ((ParameterizedType) NestedSpecifiedTypeVariableType.class.getDeclaredField(FOO).getGenericType()).getOwnerType();
assertThat(typeDescription.getOwnerType(), is(TypeDefinition.Sort.describe(ownerType)));
assertThat(typeDescription.getOwnerType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getOwnerType().getTypeArguments().size(), is(1));
assertThat(typeDescription.getOwnerType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getOwnerType().getTypeArguments().getOnly(), is((TypeDefinition) new TypeDescription.ForLoadedType(String.class)));
}
@Test
public void testNestedStaticTypeVariableType() throws Exception {
TypeDescription.Generic typeDescription = describeType(NestedStaticTypeVariableType.class.getDeclaredField(FOO));
assertThat(typeDescription.getTypeName(), is(NestedStaticTypeVariableType.class.getDeclaredField(FOO).getGenericType().toString()));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getStackSize(), is(StackSize.SINGLE));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getTypeArguments().getOnly(), is((TypeDefinition) new TypeDescription.ForLoadedType(String.class)));
Type ownerType = ((ParameterizedType) NestedStaticTypeVariableType.class.getDeclaredField(FOO).getGenericType()).getOwnerType();
assertThat(typeDescription.getOwnerType(), is(TypeDefinition.Sort.describe(ownerType)));
assertThat(typeDescription.getOwnerType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
}
@Test
public void testNestedInnerType() throws Exception {
TypeDescription.Generic foo = describeReturnType(NestedInnerType.InnerType.class.getDeclaredMethod(FOO));
assertThat(foo.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(foo.getSymbol(), is(T));
assertThat(foo.getUpperBounds().size(), is(1));
assertThat(foo.getUpperBounds().getOnly(), is(TypeDescription.Generic.OBJECT));
assertThat(foo.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(NestedInnerType.class)));
TypeDescription.Generic bar = describeReturnType(NestedInnerType.InnerType.class.getDeclaredMethod(BAR));
assertThat(bar.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(bar.getSymbol(), is(S));
assertThat(bar.getUpperBounds().size(), is(1));
assertThat(bar.getUpperBounds().getOnly(), is(foo));
assertThat(bar.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(NestedInnerType.InnerType.class)));
TypeDescription.Generic qux = describeReturnType(NestedInnerType.InnerType.class.getDeclaredMethod(QUX));
assertThat(qux.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(qux.getSymbol(), is(U));
assertThat(qux.getUpperBounds().size(), is(1));
assertThat(qux.getUpperBounds().getOnly(), is(bar));
MethodDescription quxMethod = new MethodDescription.ForLoadedMethod(NestedInnerType.InnerType.class.getDeclaredMethod(QUX));
assertThat(qux.getTypeVariableSource(), is((TypeVariableSource) quxMethod));
}
@Test
public void testNestedInnerMethod() throws Exception {
Class<?> innerType = new NestedInnerMethod().foo();
TypeDescription.Generic foo = describeReturnType(innerType.getDeclaredMethod(FOO));
assertThat(foo.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(foo.getSymbol(), is(T));
assertThat(foo.getUpperBounds().size(), is(1));
assertThat(foo.getUpperBounds().getOnly(), is(TypeDescription.Generic.OBJECT));
assertThat(foo.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(NestedInnerMethod.class)));
TypeDescription.Generic bar = describeReturnType(innerType.getDeclaredMethod(BAR));
assertThat(bar.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(bar.getSymbol(), is(S));
assertThat(bar.getUpperBounds().size(), is(1));
assertThat(bar.getUpperBounds().getOnly(), is(foo));
assertThat(bar.getTypeVariableSource(), is((TypeVariableSource) new MethodDescription.ForLoadedMethod(NestedInnerMethod.class.getDeclaredMethod(FOO))));
TypeDescription.Generic qux = describeReturnType(innerType.getDeclaredMethod(QUX));
assertThat(qux.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(qux.getSymbol(), is(U));
assertThat(qux.getUpperBounds().size(), is(1));
assertThat(qux.getUpperBounds().getOnly(), is(bar));
assertThat(qux.getTypeVariableSource(), is((TypeVariableSource) new TypeDescription.ForLoadedType(innerType)));
TypeDescription.Generic baz = describeReturnType(innerType.getDeclaredMethod(BAZ));
assertThat(baz.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(baz.getSymbol(), is(V));
assertThat(baz.getUpperBounds().size(), is(1));
assertThat(baz.getUpperBounds().getOnly(), is(qux));
assertThat(baz.getTypeVariableSource(), is((TypeVariableSource) new MethodDescription.ForLoadedMethod(innerType.getDeclaredMethod(BAZ))));
}
@Test
public void testRecursiveTypeVariable() throws Exception {
TypeDescription.Generic typeDescription = describeType(RecursiveTypeVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(typeDescription.getSymbol(), is(T));
assertThat(typeDescription.getUpperBounds().size(), is(1));
TypeDescription.Generic upperBound = typeDescription.getUpperBounds().getOnly();
assertThat(upperBound.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(upperBound.asErasure(), is(typeDescription.asErasure()));
assertThat(upperBound.getTypeArguments().size(), is(1));
assertThat(upperBound.getTypeArguments().getOnly(), is(typeDescription));
}
@Test
public void testBackwardsReferenceTypeVariable() throws Exception {
TypeDescription.Generic foo = describeType(BackwardsReferenceTypeVariable.class.getDeclaredField(FOO));
assertThat(foo.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(foo.getSymbol(), is(S));
assertThat(foo.getUpperBounds().size(), is(1));
TypeDescription backwardsReference = new TypeDescription.ForLoadedType(BackwardsReferenceTypeVariable.class);
assertThat(foo.getUpperBounds().getOnly(), is(backwardsReference.getTypeVariables().filter(named(T)).getOnly()));
TypeDescription.Generic bar = describeType(BackwardsReferenceTypeVariable.class.getDeclaredField(BAR));
assertThat(bar.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(bar.getSymbol(), is(T));
assertThat(bar.getUpperBounds().size(), is(1));
assertThat(bar.getUpperBounds().getOnly(), is(TypeDescription.Generic.OBJECT));
}
@Test
public void testParameterizedTypeSuperClassResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Base.class)));
assertThat(superClass.getTypeArguments().size(), is(2));
assertThat(superClass.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(superClass.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(superClass.getDeclaredFields().size(), is(1));
assertThat(superClass.getDeclaredFields().getOnly().getDeclaringType(), is(superClass));
TypeDescription.Generic fieldType = superClass.getDeclaredFields().getOnly().getType();
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(fieldType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(fieldType.getTypeArguments().size(), is(2));
assertThat(fieldType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(fieldType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(superClass.getDeclaredMethods().filter(isConstructor()).size(), is(1));
assertThat(superClass.getDeclaredMethods().filter(isMethod()).size(), is(1));
assertThat(superClass.getDeclaredMethods().filter(isMethod()).getOnly().getDeclaringType(), is((superClass)));
assertThat(superClass.getDeclaredMethods().filter(isConstructor()).getOnly().getDeclaringType(), is((superClass)));
TypeDescription.Generic methodReturnType = superClass.getDeclaredMethods().filter(isMethod()).getOnly().getReturnType();
assertThat(methodReturnType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(methodReturnType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(methodReturnType.getTypeArguments().size(), is(2));
assertThat(methodReturnType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(methodReturnType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
TypeDescription.Generic methodParameterType = superClass.getDeclaredMethods().filter(isMethod()).getOnly().getParameters().asTypeList().getOnly();
assertThat(methodParameterType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(methodParameterType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(methodParameterType.getTypeArguments().size(), is(2));
assertThat(methodParameterType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(methodParameterType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
}
@Test
public void testParameterizedTypeFindBoundValue() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(FOO));
assertThat(typeDescription.findBindingOf(typeDescription.asErasure().getTypeVariables().getOnly()),
is(typeDescription.getTypeArguments().getOnly()));
assertThat(typeDescription.findBindingOf(typeDescription.getOwnerType().asErasure().getTypeVariables().getOnly()),
is(typeDescription.getOwnerType().getTypeArguments().getOnly()));
assertThat(typeDescription.findBindingOf(mock(TypeDescription.Generic.class)),
nullValue(TypeDescription.Generic.class));
}
@Test
public void testParameterizedTypeInterfaceResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
assertThat(typeDescription.getInterfaces().size(), is(1));
TypeDescription.Generic interfaceType = typeDescription.getInterfaces().getOnly();
assertThat(interfaceType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(interfaceType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.BaseInterface.class)));
assertThat(interfaceType.getTypeArguments().size(), is(2));
assertThat(interfaceType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(interfaceType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(interfaceType.getDeclaredFields().size(), is(0));
assertThat(interfaceType.getDeclaredMethods().filter(isConstructor()).size(), is(0));
assertThat(interfaceType.getDeclaredMethods().filter(isMethod()).size(), is(1));
assertThat(interfaceType.getDeclaredMethods().filter(isMethod()).getOnly().getDeclaringType(), is((interfaceType)));
TypeDescription.Generic methodReturnType = interfaceType.getDeclaredMethods().filter(isMethod()).getOnly().getReturnType();
assertThat(methodReturnType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(methodReturnType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(methodReturnType.getTypeArguments().size(), is(2));
assertThat(methodReturnType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(methodReturnType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
TypeDescription.Generic methodParameterType = interfaceType.getDeclaredMethods().filter(isMethod()).getOnly().getParameters().asTypeList().getOnly();
assertThat(methodParameterType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(methodParameterType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(methodParameterType.getTypeArguments().size(), is(2));
assertThat(methodParameterType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
assertThat(methodParameterType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
}
@Test
public void testParameterizedTypeRawSuperClassResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(BAR));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Base.class)));
assertThat(superClass.getDeclaredFields().size(), is(1));
assertThat(superClass.getDeclaredFields().getOnly().getDeclaringType().getDeclaredFields().getOnly().getType(),
is(superClass.getDeclaredFields().getOnly().getType()));
TypeDescription.Generic fieldType = superClass.getDeclaredFields().getOnly().getType();
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
TypeDescription.Generic methodReturnType = superClass.getDeclaredMethods().filter(isMethod()).getOnly().getReturnType();
assertThat(methodReturnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodReturnType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
TypeDescription.Generic methodParameterType = superClass.getDeclaredMethods().filter(isMethod()).getOnly().getParameters().asTypeList().getOnly();
assertThat(methodParameterType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodParameterType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(superClass.getDeclaredMethods().filter(isMethod()).getOnly().getDeclaringType().getDeclaredMethods().filter(isMethod()).getOnly().getReturnType(),
is(superClass.getDeclaredMethods().filter(isMethod()).getOnly().getReturnType()));
assertThat(superClass.getDeclaredMethods().filter(isMethod()).getOnly().getDeclaringType().getDeclaredMethods().filter(isMethod()).getOnly().getParameters().getOnly().getType(),
is(superClass.getDeclaredMethods().filter(isMethod()).getOnly().getParameters().getOnly().getType()));
}
@Test
public void testParameterizedTypeRawInterfaceTypeResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(BAR));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic interfaceType = typeDescription.getInterfaces().getOnly();
assertThat(interfaceType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(interfaceType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.BaseInterface.class)));
assertThat(interfaceType.getDeclaredFields().size(), is(0));
TypeDescription.Generic methodReturnType = interfaceType.getDeclaredMethods().filter(isMethod()).getOnly().getReturnType();
assertThat(methodReturnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodReturnType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
TypeDescription.Generic methodParameterType = interfaceType.getDeclaredMethods().filter(isMethod()).getOnly().getParameters().asTypeList().getOnly();
assertThat(methodParameterType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodParameterType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Qux.class)));
assertThat(interfaceType.getDeclaredMethods().getOnly().getDeclaringType().getDeclaredMethods().getOnly().getReturnType(),
is(interfaceType.getDeclaredMethods().getOnly().getReturnType()));
assertThat(interfaceType.getDeclaredMethods().getOnly().getDeclaringType().getDeclaredMethods().getOnly().getParameters().getOnly().getType(),
is(interfaceType.getDeclaredMethods().getOnly().getParameters().getOnly().getType()));
}
@Test
public void testParameterizedTypePartiallyRawSuperClassResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(QUX));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Intermediate.class)));
TypeDescription.Generic superSuperClass = superClass.getSuperClass();
assertThat(superSuperClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superSuperClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Base.class)));
}
@Test
public void testParameterizedTypePartiallyRawInterfaceTypeResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(QUX));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Intermediate.class)));
TypeDescription.Generic superInterfaceType = superClass.getInterfaces().getOnly();
assertThat(superInterfaceType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superInterfaceType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.BaseInterface.class)));
}
@Test
public void testParameterizedTypeNestedPartiallyRawSuperClassResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(BAZ));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.NestedIntermediate.class)));
TypeDescription.Generic superSuperClass = superClass.getSuperClass();
assertThat(superSuperClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superSuperClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.Base.class)));
}
@Test
public void testParameterizedTypeNestedPartiallyRawInterfaceTypeResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(BAZ));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(1));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.NestedIntermediate.class)));
TypeDescription.Generic superInterfaceType = superClass.getInterfaces().getOnly();
assertThat(superInterfaceType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superInterfaceType.asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(TypeResolution.BaseInterface.class)));
}
@Test
public void testShadowedTypeSuperClassResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(FOO + BAR));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(2));
TypeDescription.Generic superClass = typeDescription.getSuperClass();
assertThat(superClass.getTypeArguments().size(), is(2));
assertThat(superClass.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(superClass.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
}
@Test
public void testShadowedTypeInterfaceTypeResolution() throws Exception {
TypeDescription.Generic typeDescription = describeType(TypeResolution.class.getDeclaredField(FOO + BAR));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(2));
TypeDescription.Generic interfaceType = typeDescription.getInterfaces().getOnly();
assertThat(interfaceType.getTypeArguments().size(), is(2));
assertThat(interfaceType.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(interfaceType.getTypeArguments().get(0), is((TypeDefinition) new TypeDescription.ForLoadedType(Bar.class)));
assertThat(interfaceType.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(interfaceType.getTypeArguments().get(1), is((TypeDefinition) new TypeDescription.ForLoadedType(Foo.class)));
}
@Test
public void testMethodTypeVariableIsRetained() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(2));
assertThat(typeDescription.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(0).asErasure().represents(Number.class), is(true));
assertThat(typeDescription.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(1).asErasure().represents(Integer.class), is(true));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly();
assertThat(methodDescription.getReturnType().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(methodDescription.getReturnType().getSymbol(), is("S"));
assertThat(methodDescription.getReturnType().getTypeVariableSource(), is((TypeVariableSource) methodDescription.asDefined()));
}
@Test
public void testShadowedMethodTypeVariableIsRetained() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(2));
assertThat(typeDescription.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(0).asErasure().represents(Number.class), is(true));
assertThat(typeDescription.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(1).asErasure().represents(Integer.class), is(true));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(named(BAR)).getOnly();
assertThat(methodDescription.getReturnType().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(methodDescription.getReturnType().getSymbol(), is("T"));
assertThat(methodDescription.getReturnType().getTypeVariableSource(), is((TypeVariableSource) methodDescription.asDefined()));
}
@Test
public void testMethodTypeVariableWithExtensionIsRetained() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(typeDescription.getTypeArguments().size(), is(2));
assertThat(typeDescription.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(0).asErasure().represents(Number.class), is(true));
assertThat(typeDescription.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(typeDescription.getTypeArguments().get(1).asErasure().represents(Integer.class), is(true));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(named(QUX)).getOnly();
assertThat(methodDescription.getReturnType().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(methodDescription.getReturnType().getSymbol(), is("S"));
assertThat(methodDescription.getReturnType().getTypeVariableSource(), is((TypeVariableSource) methodDescription.asDefined()));
assertThat(methodDescription.getReturnType().getUpperBounds().size(), is(1));
assertThat(methodDescription.getReturnType().getUpperBounds().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodDescription.getReturnType().getUpperBounds().getOnly().asErasure().represents(Number.class), is(true));
}
@Test
public void testMethodTypeVariableErasedBound() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(BAR)).getSuperClass();
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly();
assertThat(methodDescription.getReturnType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodDescription.getReturnType().asErasure(), is(TypeDescription.OBJECT));
}
@Test
public void testMethodTypeVariableWithExtensionErasedBound() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(BAR)).getSuperClass();
assertThat(typeDescription.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
MethodDescription methodDescription = typeDescription.getDeclaredMethods().filter(named(QUX)).getOnly();
assertThat(methodDescription.getReturnType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(methodDescription.getReturnType().asErasure(), is(TypeDescription.OBJECT));
}
@Test
public void testGenericFieldHashCode() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredFields().filter(named(FOO)).getOnly().hashCode(),
CoreMatchers.not(new FieldDescription.ForLoadedField(MemberVariable.class.getDeclaredField(FOO)).hashCode()));
assertThat(typeDescription.getDeclaredFields().filter(named(FOO)).getOnly().asDefined().hashCode(),
is(new FieldDescription.ForLoadedField(MemberVariable.class.getDeclaredField(FOO)).hashCode()));
}
@Test
public void testGenericFieldEquality() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredFields().filter(named(FOO)).getOnly(),
CoreMatchers.not((FieldDescription) new FieldDescription.ForLoadedField(MemberVariable.class.getDeclaredField(FOO))));
assertThat(typeDescription.getDeclaredFields().filter(named(FOO)).getOnly().asDefined(),
is((FieldDescription) new FieldDescription.ForLoadedField(MemberVariable.class.getDeclaredField(FOO))));
}
@Test
public void testGenericMethodHashCode() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().hashCode(),
CoreMatchers.not(new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(FOO)).hashCode()));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().asDefined().hashCode(),
is(new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(FOO)).hashCode()));
}
@Test
public void testGenericMethodEquality() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly(),
CoreMatchers.not((MethodDescription) new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(FOO))));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().asDefined(),
is((MethodDescription) new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(FOO))));
}
@Test
public void testGenericParameterHashCode() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredMethods().filter(named(BAZ)).getOnly().getParameters().getOnly().hashCode(), CoreMatchers.not(
new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(BAZ, Object.class)).getParameters().getOnly().hashCode()));
assertThat(typeDescription.getDeclaredMethods().filter(named(BAZ)).getOnly().getParameters().getOnly().asDefined().hashCode(), is(
new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(BAZ, Object.class)).getParameters().getOnly().hashCode()));
}
@Test
public void testGenericParameterEquality() throws Exception {
TypeDescription.Generic typeDescription = describeType(MemberVariable.class.getDeclaredField(FOO));
assertThat(typeDescription.getDeclaredMethods().filter(named(BAZ)).getOnly().getParameters().getOnly(), CoreMatchers.not((ParameterDescription)
new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(BAZ, Object.class)).getParameters().getOnly()));
assertThat(typeDescription.getDeclaredMethods().filter(named(BAZ)).getOnly().getParameters().getOnly().asDefined(), is((ParameterDescription)
new MethodDescription.ForLoadedMethod(MemberVariable.class.getDeclaredMethod(BAZ, Object.class)).getParameters().getOnly()));
}
@Test
public void testGenericTypeInconsistency() throws Exception {
TypeDescription.Generic typeDescription = describeType(GenericDisintegrator.make());
assertThat(typeDescription.getInterfaces().size(), is(2));
assertThat(typeDescription.getInterfaces().get(0).getSort(), is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getInterfaces().get(0).asErasure().represents(Callable.class), is(true));
assertThat(typeDescription.getInterfaces().get(1).getSort(), is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getInterfaces().get(1).represents(Serializable.class), is(true));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getParameters().size(), is(2));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getParameters().get(0).getType().getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getParameters().get(0).getType().asErasure().represents(Exception.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getParameters().get(1).getType().getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getParameters().get(1).getType().represents(Void.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getExceptionTypes().size(), is(2));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getExceptionTypes().get(0).getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getExceptionTypes().get(0).asErasure().represents(Exception.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getExceptionTypes().get(1).getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(named(FOO)).getOnly().getExceptionTypes().get(1).represents(RuntimeException.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getParameters().size(), is(2));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getParameters().get(0).getType().getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getParameters().get(0).getType().asErasure().represents(Exception.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getParameters().get(1).getType().getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getParameters().get(1).getType().represents(Void.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getExceptionTypes().size(), is(2));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getExceptionTypes().get(0).getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getExceptionTypes().get(0).asErasure().represents(Exception.class),
is(true));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getExceptionTypes().get(1).getSort(),
is(TypeDescription.Generic.Sort.NON_GENERIC));
assertThat(typeDescription.getDeclaredMethods().filter(isConstructor()).getOnly().getExceptionTypes().get(1).represents(RuntimeException.class),
is(true));
}
@Test
public void testRepresents() throws Exception {
assertThat(describeType(SimpleParameterizedType.class.getDeclaredField(FOO))
.represents(SimpleParameterizedType.class.getDeclaredField(FOO).getGenericType()), is(true));
assertThat(describeType(SimpleParameterizedType.class.getDeclaredField(FOO))
.represents(List.class), is(false));
}
@Test
public void testRawType() throws Exception {
TypeDescription.Generic type = describeType(RawType.class.getDeclaredField(FOO)).getSuperClass().getSuperClass();
FieldDescription fieldDescription = type.getDeclaredFields().filter(named(BAR)).getOnly();
assertThat(fieldDescription.getType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldDescription.getType().asErasure(), is(TypeDescription.OBJECT));
}
@Test
public void testIntermediateRawType() throws Exception {
TypeDescription.Generic type = describeType(IntermediateRaw.class.getDeclaredField(FOO)).getSuperClass().getSuperClass().getSuperClass();
FieldDescription fieldDescription = type.getDeclaredFields().filter(named(BAR)).getOnly();
assertThat(fieldDescription.getType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldDescription.getType().asErasure(), is((TypeDescription) new TypeDescription.ForLoadedType(Integer.class)));
}
@Test
public void testMixedTypeVariables() throws Exception {
MethodDescription methodDescription = describeInterfaceType(MixedTypeVariables.Inner.class, 0).getDeclaredMethods().getOnly();
assertThat(methodDescription.getParameters().getOnly().getType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(methodDescription.getParameters().getOnly().getType().asRawType().represents(MixedTypeVariables.SampleType.class), is(true));
assertThat(methodDescription.getParameters().getOnly().getType().getTypeArguments().get(0), is(methodDescription.getTypeVariables().getOnly()));
assertThat(methodDescription.getParameters().getOnly().getType().getTypeArguments().get(1).represents(Void.class), is(true));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationsFieldType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic fieldType = describeType(samples.getDeclaredField(FOO));
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(fieldType.getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(24));
assertThat(fieldType.getComponentType().getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(fieldType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(25));
assertThat(fieldType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(fieldType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(22));
assertThat(fieldType.getComponentType().getComponentType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.WILDCARD));
assertThat(fieldType.getComponentType().getComponentType().getTypeArguments().getOnly().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getComponentType().getComponentType().getTypeArguments().getOnly().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getComponentType().getComponentType().getTypeArguments().getOnly().getDeclaredAnnotations()
.ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(23));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationsMethodReturnType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic returnType = describeReturnType(samples.getDeclaredMethod(FOO, Exception[][].class));
assertThat(returnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(28));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationsMethodParameterType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic parameterType = describeParameterType(samples.getDeclaredMethod(FOO, Exception[][].class), 0);
assertThat(parameterType.getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(parameterType.getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(30));
assertThat(parameterType.getComponentType().getSort(), is(TypeDefinition.Sort.GENERIC_ARRAY));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(31));
assertThat(parameterType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(29));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationsSuperType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic superClass = describeSuperClass(samples);
assertThat(superClass.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(superClass.getDeclaredAnnotations().size(), is(1));
assertThat(superClass.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(superClass.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(18));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationsInterfaceType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic firstInterfaceType = describeInterfaceType(samples, 0);
assertThat(firstInterfaceType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(firstInterfaceType.getDeclaredAnnotations().size(), is(1));
assertThat(firstInterfaceType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(firstInterfaceType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(19));
assertThat(firstInterfaceType.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(firstInterfaceType.getTypeArguments().getOnly().getDeclaredAnnotations().size(), is(1));
assertThat(firstInterfaceType.getTypeArguments().getOnly().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(firstInterfaceType.getTypeArguments().getOnly().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(20));
TypeDescription.Generic secondInterfaceType = describeInterfaceType(samples, 1);
assertThat(secondInterfaceType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(secondInterfaceType.getDeclaredAnnotations().size(), is(0));
assertThat(secondInterfaceType.getTypeArguments().get(0).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(secondInterfaceType.getTypeArguments().get(0).getDeclaredAnnotations().size(), is(1));
assertThat(secondInterfaceType.getTypeArguments().get(0).getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(secondInterfaceType.getTypeArguments().get(0).getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(21));
assertThat(secondInterfaceType.getTypeArguments().get(1).getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(secondInterfaceType.getTypeArguments().get(1).getDeclaredAnnotations().size(), is(0));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationExceptionType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic firstExceptionType = describeExceptionType(samples.getDeclaredMethod(FOO, Exception[][].class), 0);
assertThat(firstExceptionType.getSort(), is(TypeDefinition.Sort.VARIABLE));
assertThat(firstExceptionType.getDeclaredAnnotations().size(), is(1));
assertThat(firstExceptionType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(firstExceptionType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(32));
TypeDescription.Generic secondExceptionType = describeExceptionType(samples.getDeclaredMethod(FOO, Exception[][].class), 1);
assertThat(secondExceptionType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(secondExceptionType.getDeclaredAnnotations().size(), is(1));
assertThat(secondExceptionType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(secondExceptionType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(33));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericField() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic fieldType = describeType(samples.getDeclaredField(FOO));
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(0));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericReturnType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic returnType = describeReturnType(samples.getDeclaredMethod(FOO, Void.class));
assertThat(returnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(9));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericParameterType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic parameterType = describeParameterType(samples.getDeclaredMethod(FOO, Void.class), 0);
assertThat(parameterType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(10));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericExceptionType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic exceptionType = describeExceptionType(samples.getDeclaredMethod(FOO, Void.class), 0);
assertThat(exceptionType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(exceptionType.getDeclaredAnnotations().size(), is(1));
assertThat(exceptionType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(exceptionType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(11));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericArrayType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic returnType = describeReturnType(samples.getDeclaredMethod(BAR, Void[][].class));
assertThat(returnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(35));
assertThat(returnType.getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(36));
assertThat(returnType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(34));
TypeDescription.Generic parameterType = describeParameterType(samples.getDeclaredMethod(BAR, Void[][].class), 0);
assertThat(parameterType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(38));
assertThat(parameterType.getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(39));
assertThat(parameterType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(37));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOnNonGenericArrayTypeWithGenericSignature() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_SAMPLES);
TypeDescription.Generic returnType = describeReturnType(samples.getDeclaredMethod(QUX, Void[][].class));
assertThat(returnType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(41));
assertThat(returnType.getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(42));
assertThat(returnType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(returnType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(40));
TypeDescription.Generic parameterType = describeParameterType(samples.getDeclaredMethod(QUX, Void[][].class), 0);
assertThat(parameterType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(44));
assertThat(parameterType.getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(45));
assertThat(parameterType.getComponentType().getComponentType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().size(), is(1));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(parameterType.getComponentType().getComponentType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(43));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationOwnerType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic fieldType = describeType(samples.getDeclaredField(BAR));
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(fieldType.getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(3));
assertThat(fieldType.getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getTypeArguments().getOnly().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getTypeArguments().getOnly().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getTypeArguments().getOnly().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(4));
assertThat(fieldType.getOwnerType().getSort(), is(TypeDefinition.Sort.PARAMETERIZED));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(1));
assertThat(fieldType.getOwnerType().getTypeArguments().getOnly().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getOwnerType().getTypeArguments().getOnly().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getOwnerType().getTypeArguments().getOnly().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getOwnerType().getTypeArguments().getOnly().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(2));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationTwoAnnotations() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<? extends Annotation> otherTypeAnnotation = (Class<? extends Annotation>) Class.forName(OTHER_TYPE_ANNOTATION);
MethodDescription.InDefinedShape otherValue = new TypeDescription.ForLoadedType(otherTypeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic fieldType = describeType(samples.getDeclaredField(QUX));
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getDeclaredAnnotations().size(), is(2));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(5));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(otherTypeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(otherTypeAnnotation).getValue(otherValue).resolve(Integer.class), is(6));
}
@Test
@JavaVersionRule.Enforce(8)
@SuppressWarnings("unchecked")
public void testTypeAnnotationNonGenericInnerType() throws Exception {
Class<? extends Annotation> typeAnnotation = (Class<? extends Annotation>) Class.forName(TYPE_ANNOTATION);
MethodDescription.InDefinedShape value = new TypeDescription.ForLoadedType(typeAnnotation).getDeclaredMethods().getOnly();
Class<?> samples = Class.forName(TYPE_ANNOTATION_OTHER_SAMPLES);
TypeDescription.Generic fieldType = describeType(samples.getDeclaredField(BAZ));
assertThat(fieldType.getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(8));
assertThat(fieldType.getOwnerType().getSort(), is(TypeDefinition.Sort.NON_GENERIC));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().size(), is(1));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().isAnnotationPresent(typeAnnotation), is(true));
assertThat(fieldType.getOwnerType().getDeclaredAnnotations().ofType(typeAnnotation).getValue(value).resolve(Integer.class), is(7));
}
@SuppressWarnings("unused")
public interface Foo {
/* empty */
}
@SuppressWarnings("unused")
public interface Bar {
/* empty */
}
@SuppressWarnings("unused")
public interface Qux<T, U> {
/* empty */
}
@SuppressWarnings("unused")
public static class NonGeneric {
Object foo;
Inner bar;
class Inner {
/* empty */
}
}
@SuppressWarnings("unused")
public static class SimpleParameterizedType {
List<String> foo;
}
@SuppressWarnings("unused")
public static class UpperBoundWildcardParameterizedType {
List<? extends String> foo;
}
@SuppressWarnings("unused")
public static class LowerBoundWildcardParameterizedType {
List<? super String> foo;
}
@SuppressWarnings("unused")
public static class UnboundWildcardParameterizedType {
List<?> foo;
}
@SuppressWarnings("all")
public static class ExplicitlyUnboundWildcardParameterizedType {
List<? extends Object> foo;
}
@SuppressWarnings("unused")
public static class NestedParameterizedType {
List<List<Foo>> foo;
}
@SuppressWarnings("unused")
public static class SimpleGenericArrayType {
List<String>[] foo;
}
@SuppressWarnings("unused")
public static class GenericArrayOfGenericComponentType<T extends String> {
List<T>[] foo;
}
@SuppressWarnings("unused")
public static class SimpleTypeVariableType<T> {
T foo;
}
@SuppressWarnings("unused")
public static class SingleUpperBoundTypeVariableType<T extends String> {
T foo;
}
@SuppressWarnings("unused")
public static class MultipleUpperBoundTypeVariableType<T extends String & Foo & Bar> {
T foo;
}
@SuppressWarnings("unused")
public static class InterfaceOnlyMultipleUpperBoundTypeVariableType<T extends Foo & Bar> {
T foo;
}
@SuppressWarnings("unused")
public static class ShadowingTypeVariableType<T> {
@SuppressWarnings("all")
<T> T foo() {
return null;
}
}
@SuppressWarnings("unused")
public static class NestedTypeVariableType<T> {
Placeholder foo;
class Placeholder {
/* empty */
}
}
@SuppressWarnings("unused")
public static class NestedSpecifiedTypeVariableType<T> {
NestedSpecifiedTypeVariableType<String>.Placeholder foo;
class Placeholder {
/* empty */
}
}
@SuppressWarnings("unused")
public static class NestedStaticTypeVariableType<T> {
NestedStaticTypeVariableType.Placeholder<String> foo;
static class Placeholder<S> {
/* empty */
}
}
@SuppressWarnings("unused")
public static class NestedInnerType<T> {
class InnerType<S extends T> {
<U extends S> T foo() {
return null;
}
<U extends S> S bar() {
return null;
}
<U extends S> U qux() {
return null;
}
}
}
@SuppressWarnings("unused")
public static class NestedInnerMethod<T> {
<S extends T> Class<?> foo() {
class InnerType<U extends S> {
<V extends U> T foo() {
return null;
}
<V extends U> S bar() {
return null;
}
<V extends U> U qux() {
return null;
}
<V extends U> V baz() {
return null;
}
}
return InnerType.class;
}
}
@SuppressWarnings("unused")
public static class RecursiveTypeVariable<T extends RecursiveTypeVariable<T>> {
T foo;
}
@SuppressWarnings("unused")
public static class BackwardsReferenceTypeVariable<T, S extends T> {
S foo;
T bar;
}
@SuppressWarnings("unused")
public static class TypeResolution<T> {
private TypeResolution<Foo>.Inner<Bar> foo;
private TypeResolution<Foo>.Raw<Bar> bar;
private TypeResolution<Foo>.PartiallyRaw<Bar> qux;
private TypeResolution<Foo>.NestedPartiallyRaw<Bar> baz;
private TypeResolution<Foo>.Shadowed<Bar, Foo> foobar;
public interface BaseInterface<V, W> {
Qux<V, W> qux(Qux<V, W> qux);
}
public static class Intermediate<V, W> extends Base<List<V>, List<? extends W>> implements BaseInterface<List<V>, List<? extends W>> {
/* empty */
}
public static class NestedIntermediate<V, W> extends Base<List<List<V>>, List<String>> implements BaseInterface<List<List<V>>, List<String>> {
/* empty */
}
public static class Base<V, W> {
Qux<V, W> qux;
public Qux<V, W> qux(Qux<V, W> qux) {
return null;
}
}
public class Inner<S> extends Base<T, S> implements BaseInterface<T, S> {
/* empty */
}
@SuppressWarnings("unchecked")
public class Raw<S> extends Base implements BaseInterface {
/* empty */
}
@SuppressWarnings("unchecked")
public class PartiallyRaw<S> extends Intermediate {
/* empty */
}
@SuppressWarnings("unchecked")
public class NestedPartiallyRaw<S> extends NestedIntermediate {
/* empty */
}
@SuppressWarnings("all")
public class Shadowed<T, S> extends Base<T, S> implements BaseInterface<T, S> {
/* empty */
}
}
public static class RawType<T> {
Extension foo;
T bar;
public static class Intermediate<T extends Number> extends RawType<T> {
/* empty */
}
public static class Extension extends Intermediate {
/* empty */
}
}
public static class IntermediateRaw<T> {
Extension foo;
T bar;
public static class NonGenericIntermediate extends IntermediateRaw<Integer> {
/* empty */
}
public static class GenericIntermediate<T> extends NonGenericIntermediate {
/* empty */
}
public static class Extension extends GenericIntermediate {
/* empty */
}
}
@SuppressWarnings("unused")
public static class MemberVariable<U, T extends U> {
public MemberVariable<Number, Integer> foo;
public Raw bar;
public <S> S foo() {
return null;
}
@SuppressWarnings("all")
public <T> T bar() {
return null;
}
@SuppressWarnings("all")
public <S extends U> S qux() {
return null;
}
public U baz(U u) {
return u;
}
@SuppressWarnings("unchecked")
public static class Raw extends MemberVariable {
/* empty */
}
}
interface MixedTypeVariables<T> {
interface Inner extends MixedTypeVariables<Void> {
/* empty */
}
<S> void qux(SampleType<S, T> arg);
interface SampleType<U, V> {
/* empty */
}
}
@SuppressWarnings("unused")
public abstract static class InconsistentGenerics<T extends Exception> implements Callable<T> {
InconsistentGenerics(T t) throws T {
/* empty */
}
abstract void foo(T t) throws T;
private InconsistentGenerics<T> foo;
}
public static class GenericDisintegrator extends ClassVisitor {
public static Field make() throws IOException, ClassNotFoundException, NoSuchFieldException {
ClassReader classReader = new ClassReader(InconsistentGenerics.class.getName());
ClassWriter classWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS);
classReader.accept(new GenericDisintegrator(classWriter), 0);
return new ByteArrayClassLoader(ClassLoadingStrategy.BOOTSTRAP_LOADER,
Collections.singletonMap(InconsistentGenerics.class.getName(), classWriter.toByteArray()),
ByteArrayClassLoader.PersistenceHandler.MANIFEST)
.loadClass(InconsistentGenerics.class.getName()).getDeclaredField(FOO);
}
public GenericDisintegrator(ClassVisitor classVisitor) {
super(Opcodes.ASM5, classVisitor);
}
@Override
public void visit(int version, int modifiers, String name, String signature, String superName, String[] interfaces) {
super.visit(version,
modifiers,
name,
signature,
superName,
new String[]{Callable.class.getName().replace('.', '/'), Serializable.class.getName().replace('.', '/')});
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
/* do nothing */
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
/* do nothing */
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
return super.visitMethod(access,
name,
"(L" + Exception.class.getName().replace('.', '/') + ";L" + Void.class.getName().replace('.', '/') + ";)V",
signature,
new String[]{Exception.class.getName().replace('.', '/'), RuntimeException.class.getName().replace('.', '/')});
}
}
}