package spoon.test.visibility; import org.junit.Test; import spoon.Launcher; import spoon.OutputType; import spoon.SpoonAPI; import spoon.SpoonModelBuilder; import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtFieldAccess; import spoon.reflect.code.CtInvocation; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtField; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; import spoon.reflect.factory.Factory; import spoon.reflect.reference.CtFieldReference; import spoon.reflect.visitor.Query; import spoon.reflect.visitor.filter.AbstractReferenceFilter; import spoon.reflect.visitor.filter.TypeFilter; import spoon.test.visibility.testclasses.A; import spoon.test.visibility.testclasses.A2; import java.io.File; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static spoon.testing.utils.ModelUtils.build; import static spoon.testing.utils.ModelUtils.canBeBuilt; public class VisibilityTest { @Test public void testMethodeWithNonAccessibleTypeArgument() throws Exception { Factory f = build(spoon.test.visibility.MethodeWithNonAccessibleTypeArgument.class, spoon.test.visibility.packageprotected.AccessibleClassFromNonAccessibleInterf.class, Class.forName("spoon.test.visibility.packageprotected.NonAccessibleInterf") ); CtClass<?> type = f.Class().get(spoon.test.visibility.MethodeWithNonAccessibleTypeArgument.class); assertEquals("MethodeWithNonAccessibleTypeArgument", type.getSimpleName()); CtMethod<?> m = type.getMethodsByName("method").get(0); assertEquals( "new spoon.test.visibility.packageprotected.AccessibleClassFromNonAccessibleInterf().method(new spoon.test.visibility.packageprotected.AccessibleClassFromNonAccessibleInterf())", m.getBody().getStatement(0).toString() ); } @Test public void testVisibilityOfClassesNamedByClassesInJavaLangPackage() throws Exception { final File sourceOutputDir = new File("target/spooned/spoon/test/visibility_package/testclasses"); final Launcher launcher = new Launcher(); launcher.getEnvironment().setAutoImports(true); launcher.getEnvironment().setDefaultFileGenerator(launcher.createOutputWriter(sourceOutputDir, launcher.getEnvironment())); final Factory factory = launcher.getFactory(); final SpoonModelBuilder compiler = launcher.createCompiler(); compiler.addInputSource(new File("./src/test/java/spoon/test/visibility/testclasses/")); compiler.setSourceOutputDirectory(sourceOutputDir); compiler.build(); compiler.generateProcessedSourceFiles(OutputType.CLASSES); // Class must be imported. final CtClass<?> aDouble = (CtClass<?>) factory.Type().get(spoon.test.visibility.testclasses.internal.Double.class); assertNotNull(aDouble); assertEquals(spoon.test.visibility.testclasses.internal.Double.class, aDouble.getActualClass()); // Class mustn't be imported. final CtClass<?> aFloat = (CtClass<?>) factory.Type().get(spoon.test.visibility.testclasses.Float.class); assertNotNull(aFloat); assertEquals(spoon.test.visibility.testclasses.Float.class, aFloat.getActualClass()); canBeBuilt(new File("./target/spooned/spoon/test/visibility_package/testclasses/"), 7); } @Test public void testFullyQualifiedNameOfTypeReferenceWithGeneric() throws Exception { // contract: Generics are written when there are specified in the return type of a method. final String target = "./target/spooned/spoon/test/visibility_generics/testclasses/"; final SpoonAPI launcher = new Launcher(); launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/A.java"); launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/A2.java"); launcher.addInputResource("./src/test/java/spoon/test/visibility/testclasses/Foo.java"); launcher.setSourceOutputDirectory(target); launcher.run(); final CtClass<A> aClass = launcher.getFactory().Class().get(A.class); CtType<?> nestedB = aClass.getNestedType("B"); List<CtFieldAccess> elements = nestedB.getElements(new TypeFilter<>(CtFieldAccess.class)); assertEquals(1, elements.size()); assertEquals("(spoon.test.visibility.testclasses.A.B.i)", elements.get(0).toString()); CtMethod<?> instanceOf = aClass.getMethodsByName("instanceOf").get(0); List<CtBinaryOperator> elements1 = instanceOf.getElements(new TypeFilter<>(CtBinaryOperator.class)); assertEquals(1, elements1.size()); assertEquals("spoon.test.visibility.testclasses.A.B", elements1.get(0).getRightHandOperand().toString()); CtMethod<?> returnType = aClass.getMethodsByName("returnType").get(0); assertEquals("spoon.test.visibility.testclasses.A<T>.C<T>", returnType.getType().toString()); final CtClass<A2> secondClass = launcher.getFactory().Class().get(A2.class); nestedB = secondClass.getNestedType("B"); elements = nestedB.getElements(new TypeFilter<>(CtFieldAccess.class)); assertEquals(1, elements.size()); assertEquals("(spoon.test.visibility.testclasses.A2.B.i)", elements.get(0).toString()); instanceOf = secondClass.getMethodsByName("instanceOf").get(0); elements1 = instanceOf.getElements(new TypeFilter<>(CtBinaryOperator.class)); assertEquals(1, elements1.size()); assertEquals("spoon.test.visibility.testclasses.A2.B", elements1.get(0).getRightHandOperand().toString()); returnType = secondClass.getMethodsByName("returnType").get(0); assertEquals("spoon.test.visibility.testclasses.A2.C<java.lang.String>", returnType.getType().toString()); returnType = secondClass.getMethodsByName("returnType2").get(0); assertEquals("spoon.test.visibility.testclasses.Foo<java.lang.String>.Bar<java.lang.String>", returnType.getType().toString()); canBeBuilt(target, 8); } @Test public void testName() throws Exception { final SpoonAPI launcher = new Launcher(); launcher.run(new String[] { "-i", "./src/test/java/spoon/test/visibility/testclasses/Tacos.java", "-o", "./target/spooned/visibility" }); final List<CtFieldReference<?>> references = Query.getElements(launcher.getFactory(), new AbstractReferenceFilter<CtFieldReference<?>>(CtFieldReference.class) { @Override public boolean matches(CtFieldReference<?> reference) { return "x".equals(reference.getSimpleName()); } }); assertEquals(1, references.size()); final CtFieldReference<?> field = references.get(0); assertNotNull(field.getDeclaration()); final CtClass<?> tacos = launcher.getFactory().Class().get("spoon.test.visibility.testclasses.Tacos"); assertEquals(tacos, field.getDeclaringType().getDeclaration()); assertEquals(tacos.getFields().get(0), field.getDeclaration()); } @Test public void testInvocationVisibilityInFieldDeclaration() throws Exception { final Launcher launcher = new Launcher(); launcher.getEnvironment().setNoClasspath(true); launcher.addInputResource("./src/test/resources/noclasspath/Solver.java"); launcher.setSourceOutputDirectory("./target/spooned"); launcher.buildModel(); final CtType<Object> aSolver = launcher.getFactory().Type().get("org.sat4j.minisat.core.Solver"); final CtField<?> lbdTimerField = aSolver.getField("lbdTimer"); final CtInvocation<?> ctInvocation = lbdTimerField.getElements(new TypeFilter<CtInvocation<?>>(CtInvocation.class) { @Override public boolean matches(CtInvocation<?> element) { return "bound".equals(element.getExecutable().getSimpleName()) && super.matches(element); } }).get(0); assertNotNull(ctInvocation.getTarget()); assertTrue(ctInvocation.getTarget().isImplicit()); assertEquals("bound()", ctInvocation.toString()); } }