package spoon.support.visitor.java;
import org.junit.Test;
import spoon.reflect.code.CtLambda;
import spoon.reflect.declaration.CtAnnotationType;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtEnum;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.reflect.reference.CtArrayTypeReference;
import spoon.reflect.reference.CtTypeParameterReference;
import spoon.support.compiler.jdt.JDTSnippetCompiler;
import spoon.test.generics.ComparableComparatorBug;
import java.io.ObjectInputStream;
import java.net.CookieManager;
import java.net.URLClassLoader;
import java.time.format.TextStyle;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static spoon.testing.utils.ModelUtils.createFactory;
public class JavaReflectionTreeBuilderTest {
@Test
public void testScannerClass() throws Exception {
final CtClass<Class> aClass = new JavaReflectionTreeBuilder(createFactory()).scan(Class.class);
assertNotNull(aClass);
assertEquals("java.lang.Class", aClass.getQualifiedName());
assertNotNull(aClass.getSuperclass());
assertTrue(aClass.getSuperInterfaces().size() > 0);
assertTrue(aClass.getFields().size() > 0);
assertTrue(aClass.getMethods().size() > 0);
assertTrue(aClass.getNestedTypes().size() > 0);
assertTrue(aClass.isShadow());
}
@Test
public void testScannerEnum() throws Exception {
final CtEnum<TextStyle> anEnum = new JavaReflectionTreeBuilder(createFactory()).scan(TextStyle.class);
assertNotNull(anEnum);
assertEquals("java.time.format.TextStyle", anEnum.getQualifiedName());
assertNotNull(anEnum.getSuperclass());
assertTrue(anEnum.getFields().size() > 0);
assertTrue(anEnum.getEnumValues().size() > 0);
assertTrue(anEnum.getMethods().size() > 0);
assertTrue(anEnum.isShadow());
}
@Test
public void testScannerInterface() throws Exception {
final CtInterface<CtLambda> anInterface = new JavaReflectionTreeBuilder(createFactory()).scan(CtLambda.class);
assertNotNull(anInterface);
assertEquals("spoon.reflect.code.CtLambda", anInterface.getQualifiedName());
assertNull(anInterface.getSuperclass());
assertTrue(anInterface.getSuperInterfaces().size() > 0);
assertTrue(anInterface.getMethods().size() > 0);
assertTrue(anInterface.isShadow());
}
@Test
public void testScannerAnnotation() throws Exception {
final CtAnnotationType<SuppressWarnings> anAnnotation = new JavaReflectionTreeBuilder(createFactory()).scan(SuppressWarnings.class);
assertNotNull(anAnnotation);
assertEquals("java.lang.SuppressWarnings", anAnnotation.getQualifiedName());
assertTrue(anAnnotation.getAnnotations().size() > 0);
assertTrue(anAnnotation.getFields().size() > 0);
assertTrue(anAnnotation.isShadow());
}
@Test
public void testScannerGenericsInClass() throws Exception {
final CtType<ComparableComparatorBug> aType = new JavaReflectionTreeBuilder(createFactory()).scan(ComparableComparatorBug.class);
assertNotNull(aType);
// New type parameter declaration.
assertEquals(1, aType.getFormalCtTypeParameters().size());
CtTypeParameter ctTypeParameter = aType.getFormalCtTypeParameters().get(0);
assertEquals("E extends java.lang.Comparable<? super E>", ctTypeParameter.toString());
assertEquals(1, ctTypeParameter.getSuperclass().getActualTypeArguments().size());
assertTrue(ctTypeParameter.getSuperclass().getActualTypeArguments().get(0) instanceof CtTypeParameterReference);
assertEquals("? super E", ctTypeParameter.getSuperclass().getActualTypeArguments().get(0).toString());
}
@Test
public void testScannerArrayReference() throws Exception {
final CtType<URLClassLoader> aType = new JavaReflectionTreeBuilder(createFactory()).scan(URLClassLoader.class);
assertNotNull(aType);
final CtMethod<Object> aMethod = aType.getMethod("getURLs");
assertTrue(aMethod.getType() instanceof CtArrayTypeReference);
final CtArrayTypeReference<Object> arrayRef = (CtArrayTypeReference<Object>) aMethod.getType();
assertNull(arrayRef.getPackage());
assertNull(arrayRef.getDeclaringType());
assertNotNull(arrayRef.getComponentType());
}
@Test
public void testDeclaredMethods() throws Exception {
final CtType<StringBuilder> type = new JavaReflectionTreeBuilder(createFactory()).scan(StringBuilder.class);
assertNotNull(type);
// All methods overridden from AbstractStringBuilder and with a type changed have been removed.
assertEquals(0, type.getMethods().stream().filter(ctMethod -> "java.lang.AbstractStringBuilder".equals(ctMethod.getType().getQualifiedName())).collect(Collectors.toList()).size());
// reverse is declared in AbstractStringBuilder and overridden in StringBuilder but the type is the same.
assertNotNull(type.getMethod("reverse"));
// readObject is declared in StringBuilder.
assertNotNull(type.getMethod("readObject", type.getFactory().Type().createReference(ObjectInputStream.class)));
}
@Test
public void testDeclaredField() throws Exception {
final CtType<CookieManager> aType = new JavaReflectionTreeBuilder(createFactory()).scan(CookieManager.class);
assertNotNull(aType);
// CookieManager have only 2 fields. Java reflection doesn't give us field of its superclass.
assertEquals(2, aType.getFields().size());
}
@Test
public void testDeclaredConstructor() throws Exception {
final CtType<JDTSnippetCompiler> aType = new JavaReflectionTreeBuilder(createFactory()).scan(JDTSnippetCompiler.class);
assertNotNull(aType);
// JDTSnippetCompiler have only 1 constructor with 2 arguments but its super class have 1 constructor with 1 argument.
assertEquals(1, ((CtClass<JDTSnippetCompiler>) aType).getConstructors().size());
}
}