Search in sources :

Example 91 with Launcher

use of spoon.Launcher in project spoon by INRIA.

the class TemplateTest method testTemplateC1.

@Test
public void testTemplateC1() throws Exception {
    Launcher spoon = new Launcher();
    Factory factory = spoon.createFactory();
    spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/C1.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/TemplateWithConstructor.java", "./src/test/java/spoon/test/template/testclasses/constructors/TemplateWithFieldsAndMethods.java")).build();
    CtClass<?> c1 = factory.Class().get(C1.class);
    // before template: 1 constructor
    assertEquals(// this is the default implicit constructor
    1, c1.getConstructors().size());
    // the actual substitution
    new TemplateWithConstructor(factory.Type().createReference(Date.class)).apply(c1);
    // after template: 3 constructors
    // System.out.println("==>"+c1.getConstructors());
    assertEquals(3, c1.getConstructors().size());
    CtField<?> toBeInserted = c1.getElements(new NamedElementFilter<>(CtField.class, "toBeInserted")).get(0);
    assertEquals(Date.class, toBeInserted.getType().getActualTypeArguments().get(0).getActualClass());
    assertEquals("java.util.List<java.util.Date> toBeInserted = new java.util.ArrayList<java.util.Date>();", toBeInserted.toString());
    new TemplateWithFieldsAndMethods("testparam", factory.Code().createLiteral("testparam2")).apply(c1);
    assertEquals(3, c1.getConstructors().size());
    assertNotNull(c1.getField("fieldToBeInserted"));
    CtMethod<?> m = c1.getMethod("methodToBeInserted");
    assertNotNull(m);
    assertEquals("return \"testparam\"", m.getBody().getStatement(0).toString());
    CtMethod<?> m2 = c1.getMethod("methodToBeInserted2");
    assertNotNull(m2);
    assertEquals("return \"testparam2\"", m2.getBody().getStatement(0).toString());
    new ModelConsistencyChecker(factory.getEnvironment(), false, true).scan(c1);
    assertEquals(0, factory.getEnvironment().getErrorCount());
    assertEquals(0, factory.getEnvironment().getWarningCount());
}
Also used : NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) TemplateWithConstructor(spoon.test.template.testclasses.constructors.TemplateWithConstructor) ModelConsistencyChecker(spoon.reflect.visitor.ModelConsistencyChecker) TemplateWithFieldsAndMethods(spoon.test.template.testclasses.constructors.TemplateWithFieldsAndMethods) Test(org.junit.Test)

Example 92 with Launcher

use of spoon.Launcher in project spoon by INRIA.

the class TemplateTest method testTemplateInheritance.

@Test
public void testTemplateInheritance() throws Exception {
    Launcher spoon = new Launcher();
    Factory factory = spoon.getFactory();
    spoon.getEnvironment().setCommentEnabled(true);
    spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubClass.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperClass.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/inheritance/SubTemplate.java", "./src/test/java/spoon/test/template/testclasses/inheritance/SuperTemplate.java")).build();
    // Collects type members which should contain generated by comment
    final Map<CtElement, String> elementToGeneratedByMember = new IdentityHashMap<>();
    CtClass<?> superc = factory.Class().get(SuperClass.class);
    new SuperTemplate().addGeneratedBy(true).apply(superc);
    CtMethod<?> addedMethod = superc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
    assertEquals("toBeOverriden", addedMethod.getSimpleName());
    elementToGeneratedByMember.put(addedMethod, "#toBeOverriden");
    CtClass<?> subc = factory.Class().get(SubClass.class);
    SubTemplate template = new SubTemplate();
    template.addGeneratedBy(true);
    template.params = new ArrayList<>();
    CtParameter<Integer> parameter = factory.Core().createParameter();
    parameter.setSimpleName("x");
    parameter.setType(factory.Type().createReference(int.class));
    template.params.add(parameter);
    // templating the invocation
    template.invocation = factory.Code().createInvocation(null, addedMethod.getReference());
    // templating the foreach
    template.intValues = new CtExpression[2];
    template.intValues[0] = factory.Code().createLiteral(0);
    template.intValues[1] = factory.Code().createLiteral(1);
    // we apply the extension template to subc
    template.apply(subc);
    CtMethod<?> addedMethod2 = subc.getElements(new NamedElementFilter<>(CtMethod.class, "toBeOverriden")).get(0);
    assertEquals("toBeOverriden", addedMethod2.getSimpleName());
    assertEquals("super.toBeOverriden()", addedMethod2.getBody().getStatements().get(0).toString());
    elementToGeneratedByMember.put(addedMethod2, "#toBeOverriden");
    // contract; method parameter templates are handled
    CtMethod<?> methodWithTemplatedParameters = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithTemplatedParameters")).get(0);
    assertEquals("methodWithTemplatedParameters", methodWithTemplatedParameters.getSimpleName());
    assertEquals("x", methodWithTemplatedParameters.getParameters().get(0).getSimpleName());
    assertEquals("int x", methodWithTemplatedParameters.getParameters().get(0).toString());
    elementToGeneratedByMember.put(methodWithTemplatedParameters, "#methodWithTemplatedParameters");
    // contract: nested types of the templates are copied
    assertEquals(1, subc.getNestedTypes().size());
    elementToGeneratedByMember.put(subc.getNestedTypes().iterator().next(), "$InnerClass");
    // contract: methods are renamed
    assertEquals(1, subc.getMethodsByName("newVarName").size());
    CtMethod<?> varMethod = subc.getMethodsByName("newVarName").get(0);
    elementToGeneratedByMember.put(varMethod, "#var");
    // contract: parameters are replaced in comments too. The Class parameter value is converted to String
    assertEquals("newVarName", varMethod.getComments().get(0).getContent().split("[\\n\\r]+")[0]);
    assertEquals("{@link LinkedList}", varMethod.getComments().get(1).getContent());
    assertEquals("{@link SuperClass#toBeOverriden()}", varMethod.getComments().get(2).getContent());
    // contract: variable are renamed
    assertEquals("java.util.List newVarName = null", methodWithTemplatedParameters.getBody().getStatement(0).toString());
    // contract: types are replaced by other types
    assertEquals("java.util.LinkedList l = null", methodWithTemplatedParameters.getBody().getStatement(1).toString());
    // contract: casts are replaced by substitution types
    assertEquals("java.util.List o = ((java.util.LinkedList) (new java.util.LinkedList()))", methodWithTemplatedParameters.getBody().getStatement(2).toString());
    // contract: invocations are replaced by actual invocations
    assertEquals("toBeOverriden()", methodWithTemplatedParameters.getBody().getStatement(3).toString());
    // contract: foreach in block is inlined into that wrapping block
    CtBlock templatedForEach = methodWithTemplatedParameters.getBody().getStatement(4);
    assertEquals("java.lang.System.out.println(0)", templatedForEach.getStatement(0).toString());
    assertEquals("java.lang.System.out.println(1)", templatedForEach.getStatement(1).toString());
    // contract: foreach with single body block are inlined without extra block
    assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(5).toString());
    assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(6).toString());
    // contract: foreach with double body block are inlined with one extra block for each inlined statement
    assertEquals("java.lang.System.out.println(0)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(7)).getStatement(0).toString());
    assertEquals("java.lang.System.out.println(1)", ((CtBlock) methodWithTemplatedParameters.getBody().getStatement(8)).getStatement(0).toString());
    // contract: foreach with statement are inlined without extra (implicit) block
    assertFalse(methodWithTemplatedParameters.getBody().getStatement(9) instanceof CtBlock);
    assertEquals("java.lang.System.out.println(0)", methodWithTemplatedParameters.getBody().getStatement(9).toString());
    assertFalse(methodWithTemplatedParameters.getBody().getStatement(10) instanceof CtBlock);
    assertEquals("java.lang.System.out.println(1)", methodWithTemplatedParameters.getBody().getStatement(10).toString());
    // contract: for each whose expression is not a template parameter is not inlined
    assertTrue(methodWithTemplatedParameters.getBody().getStatement(11) instanceof CtForEach);
    // contract: local variable write are replaced by local variable write with modified local variable name
    assertEquals("newVarName = o", methodWithTemplatedParameters.getBody().getStatement(12).toString());
    // contract: local variable read are replaced by local variable read with modified local variable name
    assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithTemplatedParameters.getBody().getStatement(13).toString());
    // contract; field access is handled same like local variable access
    CtMethod<?> methodWithFieldAccess = subc.getElements(new NamedElementFilter<>(CtMethod.class, "methodWithFieldAccess")).get(0);
    elementToGeneratedByMember.put(methodWithFieldAccess, "#methodWithFieldAccess");
    elementToGeneratedByMember.put(subc.getField("newVarName"), "#var");
    // contract: field write are replaced by field write with modified field name
    assertEquals("newVarName = o", methodWithFieldAccess.getBody().getStatement(2).toString());
    // contract: field read are replaced by field read with modified field name
    assertEquals("l = ((java.util.LinkedList) (newVarName))", methodWithFieldAccess.getBody().getStatement(3).toString());
    class Context {

        int nrTypeMembers = 0;

        int nrOthers = 0;
    }
    final Context ctx = new Context();
    // contract: each CtTypeMember has `Generated by ` with appropriate template class name, member name and line number
    superc.filterChildren(null).forEach((CtElement e) -> {
        if (e instanceof CtTypeMember) {
            ctx.nrTypeMembers++;
            assertCommentHasGeneratedBy(e, SuperTemplate.class.getName(), elementToGeneratedByMember);
        } else {
            ctx.nrOthers++;
            assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
        }
    });
    assertTrue(ctx.nrTypeMembers > 0);
    assertTrue(ctx.nrOthers > 0);
    ctx.nrTypeMembers = 0;
    ctx.nrOthers = 0;
    subc.filterChildren(null).forEach((CtElement e) -> {
        if (e instanceof CtTypeMember) {
            ctx.nrTypeMembers++;
            assertCommentHasGeneratedBy(e, SubTemplate.class.getName(), elementToGeneratedByMember);
        } else {
            ctx.nrOthers++;
            assertTrue(e.getDocComment() == null || e.getDocComment().indexOf("Generated by") == -1);
        }
    });
    assertTrue(ctx.nrTypeMembers > 0);
    assertTrue(ctx.nrOthers > 0);
}
Also used : SubTemplate(spoon.test.template.testclasses.inheritance.SubTemplate) CtElement(spoon.reflect.declaration.CtElement) IdentityHashMap(java.util.IdentityHashMap) Factory(spoon.reflect.factory.Factory) CtForEach(spoon.reflect.code.CtForEach) CtBlock(spoon.reflect.code.CtBlock) CtTypeMember(spoon.reflect.declaration.CtTypeMember) SuperTemplate(spoon.test.template.testclasses.inheritance.SuperTemplate) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) Launcher(spoon.Launcher) Test(org.junit.Test)

Example 93 with Launcher

use of spoon.Launcher in project spoon by INRIA.

the class TemplateTest method testTemplateWithWrongUsedStringParam.

@Test
public void testTemplateWithWrongUsedStringParam() throws Exception {
    Launcher spoon = new Launcher();
    Factory factory = spoon.createFactory();
    spoon.createCompiler(factory, SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/C1.java"), SpoonResourceHelper.resources("./src/test/java/spoon/test/template/testclasses/constructors/TemplateWithFieldsAndMethods_Wrong.java")).build();
    CtClass<?> c1 = factory.Class().get(C1.class);
    new TemplateWithFieldsAndMethods_Wrong("testparam").apply(c1);
    CtMethod<?> m = c1.getMethod("methodToBeInserted");
    assertNotNull(m);
    // contract: printing of code which contains invalid field reference, fails with nice exception
    try {
        m.getBody().getStatement(0).toString();
    } catch (SpoonException e) {
        assertTrue("The error description doesn't contain name of invalid field. There is:\n" + e.getMessage(), e.getMessage().indexOf("testparam") >= 0);
    }
}
Also used : SpoonException(spoon.SpoonException) TemplateWithFieldsAndMethods_Wrong(spoon.test.template.testclasses.constructors.TemplateWithFieldsAndMethods_Wrong) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) Test(org.junit.Test)

Example 94 with Launcher

use of spoon.Launcher in project spoon by INRIA.

the class SourcePositionTest method testSourcePosition.

@Test
public void testSourcePosition() throws IOException {
    File modelFile = new File("./src/test/resources/serialization/model");
    Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/resources/serialization/SomeClass.java");
    launcher.buildModel();
    Factory factory = launcher.getFactory();
    saveFactory(factory, modelFile);
    Factory factoryFromFile = loadFactory(modelFile);
    CtType<?> type = factory.Type().get("SomeClass");
    CtType<?> typeFromFile = factoryFromFile.Type().get("SomeClass");
    // Serialized model should have same valid source positions as the original model
    assertTrue(type.getPosition().getFile().equals(typeFromFile.getPosition().getFile()));
    assertTrue(type.getPosition().getLine() == typeFromFile.getPosition().getLine());
    assertTrue(type.getPosition().getColumn() == typeFromFile.getPosition().getColumn());
    CtField<?> elem1 = type.getField("a");
    CtField<?> elem2 = typeFromFile.getField("a");
    assertTrue(elem1.getPosition().getFile().equals(elem2.getPosition().getFile()));
}
Also used : Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) File(java.io.File) Test(org.junit.Test)

Example 95 with Launcher

use of spoon.Launcher in project spoon by INRIA.

the class SignatureTest method testNullSignatureInUnboundVariable.

@Test
public void testNullSignatureInUnboundVariable() throws Exception {
    // Unbound variable access bug fix:
    // Bug description: The signature printer ignored the element Unbound variable reference
    // (as well all Visitor that extend CtVisitor)
    // Fix description: modify CtVisitor (including SignaturePrinter) for visiting unbound variable access.
    Factory factory = new Launcher().createFactory();
    // We want to compile a class with an reference to a class that is not
    // in the classpath
    // As consequence, we set the option NoClasspath as true.
    factory.getEnvironment().setNoClasspath(true);
    String unboundVarAccess = "Complex.I";
    String content = "" + "class X {" + "public Object foo(java.util.List<String> l) {" + " Integer.toString(" + unboundVarAccess + ");" + " return null;" + "}};";
    SpoonModelBuilder builder = new JDTSnippetCompiler(factory, content);
    try {
        builder.build();
        Assert.fail();
    } catch (Exception e) {
    // Must fail due to the unbound element "Complex.I"
    }
    CtClass<?> clazz1 = (CtClass<?>) factory.Type().getAll().get(0);
    Set<CtMethod<?>> methods = clazz1.getMethods();
    CtMethod<?> method = (CtMethod<?>) methods.toArray()[0];
    assertEquals("foo(java.util.List)", method.getSignature());
    CtInvocation<?> invo = (CtInvocation<?>) method.getBody().getStatement(0);
    CtExpression<?> argument1 = invo.getArguments().get(0);
    assertEquals(unboundVarAccess, argument1.toString());
}
Also used : SpoonModelBuilder(spoon.SpoonModelBuilder) DefaultCoreFactory(spoon.support.DefaultCoreFactory) Factory(spoon.reflect.factory.Factory) CtClass(spoon.reflect.declaration.CtClass) CtInvocation(spoon.reflect.code.CtInvocation) JDTSnippetCompiler(spoon.support.compiler.jdt.JDTSnippetCompiler) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Aggregations

Launcher (spoon.Launcher)524 Test (org.junit.Test)486 Factory (spoon.reflect.factory.Factory)163 CtClass (spoon.reflect.declaration.CtClass)111 CtMethod (spoon.reflect.declaration.CtMethod)79 File (java.io.File)75 CtType (spoon.reflect.declaration.CtType)66 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)60 CtTypeReference (spoon.reflect.reference.CtTypeReference)48 SpoonModelBuilder (spoon.SpoonModelBuilder)44 ArrayList (java.util.ArrayList)43 CtAnnotation (spoon.reflect.declaration.CtAnnotation)38 CtInvocation (spoon.reflect.code.CtInvocation)32 CtElement (spoon.reflect.declaration.CtElement)27 CtPackage (spoon.reflect.declaration.CtPackage)27 FileSystemFile (spoon.support.compiler.FileSystemFile)26 CtStatement (spoon.reflect.code.CtStatement)25 CtField (spoon.reflect.declaration.CtField)24 NamedElementFilter (spoon.reflect.visitor.filter.NamedElementFilter)24 SpoonAPI (spoon.SpoonAPI)22