Search in sources :

Example 16 with SpoonModelBuilder

use of spoon.SpoonModelBuilder in project spoon by INRIA.

the class TypeReferenceTest method doNotCloseLoader.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void doNotCloseLoader() throws Exception {
    /* Given the following scenario:
		 * 	- ClassA has a field of ClassB.
		 *	- ClassB has a field of ClassC.
		 * 	- Spoon only models ClassA.
		 *
		 * We want to get the field of ClassB, which should be accessible because
		 * the definitions of ClassB and ClassC were provided in the class path.
		 */
    SpoonModelBuilder comp = new Launcher().createCompiler();
    Factory factory = comp.getFactory();
    String qualifiedName = "spoontest.a.ClassA";
    String referenceQualifiedName = "spoontest.b.ClassB";
    // we only create the model for ClassA
    List<SpoonResource> fileToBeSpooned = SpoonResourceHelper.resources("./src/test/resources/reference-test-2/" + qualifiedName.replace('.', '/') + ".java");
    comp.addInputSources(fileToBeSpooned);
    // for ClassA
    assertEquals(1, fileToBeSpooned.size());
    // Spoon requires the binary version of dependencies
    List<SpoonResource> classpath = SpoonResourceHelper.resources("./src/test/resources/reference-test-2/ReferenceTest2.jar");
    String[] dependencyClasspath = new String[] { classpath.get(0).getPath() };
    factory.getEnvironment().setSourceClasspath(dependencyClasspath);
    assertEquals(1, classpath.size());
    // now we can build the model
    comp.build();
    // we can get the model of ClassA
    CtType<?> theClass = factory.Type().get(qualifiedName);
    // we get ClassA's field of type ClassB
    List<CtField<?>> fields = theClass.getFields();
    assertEquals(1, fields.size());
    CtField<?> bField = fields.get(0);
    CtTypeReference referencedType = bField.getType();
    assertEquals(referenceQualifiedName, referencedType.getQualifiedName());
    // we get ClassB's field of type ClassC
    Collection<CtFieldReference<?>> fieldsOfB = referencedType.getAllFields();
    if (fieldsOfB.size() == 2) {
        // Jacoco instruments all dependencies with an agent.
        // So, when we use reflection on ClassB, we don't have one field but two fields.
        // First, it is the field of ClassB. Second, it is the field of Jacoco.
        final CtFieldReference<?> potentialJacoco = (CtFieldReference<?>) fieldsOfB.toArray()[1];
        if ("$jacocoData".equals(potentialJacoco.getSimpleName())) {
            fieldsOfB.remove(potentialJacoco);
        }
    }
    assertEquals(1, fieldsOfB.size());
    CtFieldReference<?> cField = fieldsOfB.iterator().next();
    assertEquals("spoontest.c.ClassC", cField.getType().getQualifiedName());
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Factory(spoon.reflect.factory.Factory) CtFieldReference(spoon.reflect.reference.CtFieldReference) CtField(spoon.reflect.declaration.CtField) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) SpoonResource(spoon.compiler.SpoonResource) Test(org.junit.Test)

Example 17 with SpoonModelBuilder

use of spoon.SpoonModelBuilder in project spoon by INRIA.

the class CtRenameLocalVariableRefactoringTest method testRenameAllLocalVariablesOfRenameTestSubject.

/**
 * The {@link CtRenameLocalVariableRefactoringTestSubject} class is loaded as spoon model. Then:
 * - It looks for each CtVariable and it's CtAnnotation and tries to rename that variable to the name defined by annotation.
 * - If the annotation name is prefixed with "-", then that refactoring should fail.
 * - If the annotation name is not prefixed, then that refactoring should pass.
 * If it behaves different then expected, then this test fails
 */
@Test
public void testRenameAllLocalVariablesOfRenameTestSubject() throws Exception {
    final Launcher launcher = new Launcher();
    final SpoonModelBuilder comp = launcher.createCompiler();
    comp.addInputSources(SpoonResourceHelper.resources("./src/test/java/" + CtRenameLocalVariableRefactoringTestSubject.class.getName().replace('.', '/') + ".java"));
    comp.build();
    final Factory factory = comp.getFactory();
    CtClass<?> varRenameClass = (CtClass<?>) factory.Type().get(CtRenameLocalVariableRefactoringTestSubject.class);
    CtTypeReference<TestTryRename> tryRename = varRenameClass.getFactory().createCtTypeReference(TestTryRename.class);
    varRenameClass.getMethods().forEach(method -> {
        // debugging support
        if (DEBUG.length == 3 && DEBUG[0].equals(method.getSimpleName()) == false)
            return;
        method.filterChildren((CtVariable var) -> true).map((CtVariable var) -> var.getAnnotation(tryRename)).forEach((CtAnnotation<TestTryRename> annotation) -> {
            String[] newNames = annotation.getActualAnnotation().value();
            CtVariable<?> targetVariable = (CtVariable<?>) annotation.getAnnotatedElement();
            for (String newName : newNames) {
                boolean renameShouldPass = newName.startsWith("-") == false;
                if (!renameShouldPass) {
                    newName = newName.substring(1);
                }
                if (targetVariable instanceof CtLocalVariable<?>) {
                    // debugging support
                    if (DEBUG.length == 3 && DEBUG[1].equals(targetVariable.getSimpleName()) && DEBUG[2].equals(newName)) {
                        // put breakpoint here and continue debugging of the buggy case
                        this.getClass();
                    }
                    checkLocalVariableRename(launcher, (CtLocalVariable<?>) targetVariable, newName, renameShouldPass);
                } else {
                // TODO test rename of other variables, e.g. parameters and catch... later
                }
            }
        });
    });
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) CtAnnotation(spoon.reflect.declaration.CtAnnotation) Factory(spoon.reflect.factory.Factory) CtLocalVariable(spoon.reflect.code.CtLocalVariable) CtClass(spoon.reflect.declaration.CtClass) TestTryRename(spoon.test.refactoring.testclasses.TestTryRename) CtVariable(spoon.reflect.declaration.CtVariable) Launcher(spoon.Launcher) CtRenameLocalVariableRefactoringTestSubject(spoon.test.refactoring.testclasses.CtRenameLocalVariableRefactoringTestSubject) Test(org.junit.Test)

Example 18 with SpoonModelBuilder

use of spoon.SpoonModelBuilder in project spoon by INRIA.

the class DefaultPrettyPrinterTest method printerCanPrintInvocationWithoutException.

@Test
public void printerCanPrintInvocationWithoutException() throws Exception {
    String packageName = "spoon.test.subclass.prettyprinter";
    String className = "DefaultPrettyPrinterExample";
    String qualifiedName = packageName + "." + className;
    SpoonModelBuilder comp = new Launcher().createCompiler();
    List<SpoonResource> fileToBeSpooned = SpoonResourceHelper.resources("./src/test/resources/printer-test/" + qualifiedName.replace('.', '/') + ".java");
    assertEquals(1, fileToBeSpooned.size());
    comp.addInputSources(fileToBeSpooned);
    List<SpoonResource> classpath = SpoonResourceHelper.resources("./src/test/resources/printer-test/DefaultPrettyPrinterDependency.jar");
    assertEquals(1, classpath.size());
    comp.setSourceClasspath(classpath.get(0).getPath());
    comp.build();
    Factory factory = comp.getFactory();
    CtType<?> theClass = factory.Type().get(qualifiedName);
    List<CtInvocation<?>> elements = Query.getElements(theClass, new TypeFilter<CtInvocation<?>>(CtInvocation.class));
    assertEquals(3, elements.size());
    CtInvocation<?> mathAbsInvocation = elements.get(1);
    assertEquals("java.lang.Math.abs(message.length())", mathAbsInvocation.toString());
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) CtInvocation(spoon.reflect.code.CtInvocation) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) SpoonResource(spoon.compiler.SpoonResource) Test(org.junit.Test)

Example 19 with SpoonModelBuilder

use of spoon.SpoonModelBuilder in project spoon by INRIA.

the class DefaultPrettyPrinterTest method superInvocationWithEnclosingInstance.

@Test
public void superInvocationWithEnclosingInstance() throws Exception {
    /**
     * To extend a nested class an enclosing instance must be provided
     * to call the super constructor.
     */
    String sourcePath = "./src/test/resources/spoon/test/prettyprinter/NestedSuperCall.java";
    List<SpoonResource> files = SpoonResourceHelper.resources(sourcePath);
    assertEquals(1, files.size());
    SpoonModelBuilder comp = new Launcher().createCompiler();
    comp.addInputSources(files);
    comp.build();
    Factory factory = comp.getFactory();
    CtType<?> theClass = factory.Type().get("spoon.test.prettyprinter.NestedSuperCall");
    assertTrue(theClass.toString().contains("nc.super(\"a\")"));
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) SpoonResource(spoon.compiler.SpoonResource) Test(org.junit.Test)

Example 20 with SpoonModelBuilder

use of spoon.SpoonModelBuilder in project spoon by INRIA.

the class DefaultPrettyPrinterTest method autoImportUsesFullyQualifiedNameWhenImportedNameAlreadyPresent.

@Test
public void autoImportUsesFullyQualifiedNameWhenImportedNameAlreadyPresent() throws Exception {
    final Launcher launcher = new Launcher();
    final Factory factory = launcher.getFactory();
    factory.getEnvironment().setAutoImports(true);
    final SpoonModelBuilder compiler = launcher.createCompiler();
    compiler.addInputSource(new File("./src/test/java/spoon/test/prettyprinter/testclasses/sub/TypeIdentifierCollision.java"));
    compiler.addInputSource(new File("./src/test/java/spoon/test/prettyprinter/testclasses/TypeIdentifierCollision.java"));
    compiler.build();
    final CtClass<?> aClass = (CtClass<?>) factory.Type().get(spoon.test.prettyprinter.testclasses.TypeIdentifierCollision.class);
    String expected = "public void setFieldUsingExternallyDefinedEnumWithSameNameAsLocal() {" + nl + "    localField = spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.ENUM.E1.ordinal();" + nl + "}";
    String computed = aClass.getMethodsByName("setFieldUsingExternallyDefinedEnumWithSameNameAsLocal").get(0).toString();
    assertEquals("We use FQN for E1", expected, computed);
    // This is correct however it could be more concise.
    expected = "public void setFieldUsingLocallyDefinedEnum() {" + nl + "    localField = TypeIdentifierCollision.ENUM.E1.ordinal();" + nl + "}";
    computed = aClass.getMethodsByName("setFieldUsingLocallyDefinedEnum").get(0).toString();
    assertEquals(expected, computed);
    expected = "public void setFieldOfClassWithSameNameAsTheCompilationUnitClass() {" + nl + "    spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.globalField = localField;" + nl + "}";
    computed = aClass.getMethodsByName("setFieldOfClassWithSameNameAsTheCompilationUnitClass").get(0).toString();
    assertEquals("The static field of an external type with the same identifier as the compilation unit is printed with FQN", expected, computed);
    // This is correct however it could be more concise.
    expected = "public void referToTwoInnerClassesWithTheSameName() {" + nl + "    TypeIdentifierCollision.Class0.ClassA.VAR0 = TypeIdentifierCollision.Class0.ClassA.getNum();" + nl + "    TypeIdentifierCollision.Class1.ClassA.VAR1 = TypeIdentifierCollision.Class1.ClassA.getNum();" + nl + "}";
    // Ensure the ClassA of Class0 takes precedence over an import statement for ClassA in Class1, and it's identifier can be the short version.
    computed = aClass.getMethodsByName("referToTwoInnerClassesWithTheSameName").get(0).toString();
    assertEquals("where inner types have the same identifier only one may be shortened and the other should be fully qualified", expected, computed);
    expected = "public enum ENUM {" + nl + "    E1(spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.globalField,spoon.test.prettyprinter.testclasses.sub.TypeIdentifierCollision.ENUM.E1);" + nl + "    final int NUM;" + nl + nl + "    final Enum<?> e;" + nl + nl + "    private ENUM(int num, Enum<?> e) {" + nl + "        NUM = num;" + nl + "        this.e = e;" + nl + "    }" + nl + "}";
    computed = aClass.getNestedType("ENUM").toString();
    assertEquals(expected, computed);
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) CtClass(spoon.reflect.declaration.CtClass) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) File(java.io.File) Test(org.junit.Test)

Aggregations

SpoonModelBuilder (spoon.SpoonModelBuilder)45 Launcher (spoon.Launcher)43 Test (org.junit.Test)35 Factory (spoon.reflect.factory.Factory)29 File (java.io.File)17 CtClass (spoon.reflect.declaration.CtClass)16 CtMethod (spoon.reflect.declaration.CtMethod)6 SpoonResource (spoon.compiler.SpoonResource)5 CtInvocation (spoon.reflect.code.CtInvocation)5 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)4 DefaultCoreFactory (spoon.support.DefaultCoreFactory)4 JDTSnippetCompiler (spoon.support.compiler.jdt.JDTSnippetCompiler)4 ModelUtils.createFactory (spoon.testing.utils.ModelUtils.createFactory)4 Before (org.junit.Before)3 FileNotFoundException (java.io.FileNotFoundException)2 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)2 CtParameterRemoveRefactoring (spoon.refactoring.CtParameterRemoveRefactoring)2 CtNewClass (spoon.reflect.code.CtNewClass)2 CtExecutable (spoon.reflect.declaration.CtExecutable)2 FactoryImpl (spoon.reflect.factory.FactoryImpl)2