Search in sources :

Example 1 with SubstitutionVisitor

use of spoon.support.template.SubstitutionVisitor in project spoon by INRIA.

the class TemplateTest method testExtensionDecoupledSubstitutionVisitor.

@Test
public void testExtensionDecoupledSubstitutionVisitor() throws Exception {
    // contract: substitution can be done on model, which is not based on Template
    final Launcher launcher = new Launcher();
    launcher.setArgs(new String[] { "--output-type", "nooutput" });
    launcher.addInputResource("./src/test/java/spoon/test/template/testclasses/logger/Logger.java");
    launcher.addTemplateResource(new FileSystemFile("./src/test/java/spoon/test/template/testclasses/LoggerModel.java"));
    launcher.buildModel();
    Factory factory = launcher.getFactory();
    final CtClass<?> aTemplateModelType = launcher.getFactory().Class().get(LoggerModel.class);
    final CtMethod<?> aTemplateModel = aTemplateModelType.getMethod("block");
    final CtClass<?> aTargetType = launcher.getFactory().Class().get(Logger.class);
    final CtMethod<?> toBeLoggedMethod = aTargetType.getMethodsByName("enter").get(0);
    Map<String, Object> params = new HashMap<>();
    params.put("_classname_", factory.Code().createLiteral(aTargetType.getSimpleName()));
    params.put("_methodName_", factory.Code().createLiteral(toBeLoggedMethod.getSimpleName()));
    params.put("_block_", toBeLoggedMethod.getBody());
    final List<CtMethod<?>> aMethods = new SubstitutionVisitor(factory, params).substitute(aTemplateModel.clone());
    assertEquals(1, aMethods.size());
    final CtMethod<?> aMethod = aMethods.get(0);
    assertTrue(aMethod.getBody().getStatement(0) instanceof CtTry);
    final CtTry aTry = (CtTry) aMethod.getBody().getStatement(0);
    assertTrue(aTry.getFinalizer().getStatement(0) instanceof CtInvocation);
    assertEquals("spoon.test.template.testclasses.logger.Logger.exit(\"enter\")", aTry.getFinalizer().getStatement(0).toString());
    assertTrue(aTry.getBody().getStatement(0) instanceof CtInvocation);
    assertEquals("spoon.test.template.testclasses.logger.Logger.enter(\"Logger\", \"enter\")", aTry.getBody().getStatement(0).toString());
    assertTrue(aTry.getBody().getStatements().size() > 1);
}
Also used : IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Factory(spoon.reflect.factory.Factory) FileSystemFile(spoon.support.compiler.FileSystemFile) CtTry(spoon.reflect.code.CtTry) SubstitutionVisitor(spoon.support.template.SubstitutionVisitor) CtInvocation(spoon.reflect.code.CtInvocation) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 2 with SubstitutionVisitor

use of spoon.support.template.SubstitutionVisitor in project spoon by INRIA.

the class StatementTemplate method apply.

public CtStatement apply(CtType<?> targetType) {
    CtClass<?> c = Substitution.getTemplateCtClass(targetType, this);
    // we substitute the first statement of method statement
    CtStatement result = c.getMethod("statement").getBody().getStatements().get(0).clone();
    List<CtStatement> statements = new SubstitutionVisitor(c.getFactory(), targetType, this).substitute(result);
    if (statements.size() > 1) {
        throw new SpoonException("StatementTemplate cannot return more then one statement");
    }
    return statements.isEmpty() ? null : statements.get(0);
}
Also used : SubstitutionVisitor(spoon.support.template.SubstitutionVisitor) CtStatement(spoon.reflect.code.CtStatement) SpoonException(spoon.SpoonException)

Example 3 with SubstitutionVisitor

use of spoon.support.template.SubstitutionVisitor in project spoon by INRIA.

the class Substitution method substitute.

/**
 * Substitutes all the template parameters in a random piece of code.
 *
 * @param targetType
 * 		the target type
 * @param template
 * 		the template instance
 * @param code
 * 		the code
 * @return the code where all the template parameters has been substituted
 * by their values
 */
public static <E extends CtElement> E substitute(CtType<?> targetType, Template<?> template, E code) {
    if (code == null) {
        return null;
    }
    if (targetType == null) {
        throw new RuntimeException("target is null in substitution");
    }
    E result = (E) code.clone();
    List<E> results = new SubstitutionVisitor(targetType.getFactory(), targetType, template).substitute(result);
    if (results.size() > 1) {
        throw new SpoonException("StatementTemplate cannot return more then one statement");
    }
    return results.isEmpty() ? null : results.get(0);
}
Also used : SubstitutionVisitor(spoon.support.template.SubstitutionVisitor) SpoonException(spoon.SpoonException)

Example 4 with SubstitutionVisitor

use of spoon.support.template.SubstitutionVisitor in project spoon by INRIA.

the class Substitution method createTypeFromTemplate.

/**
 * Generates a type (class, interface, enum, ...) from the template model `templateOfType`
 * by by substituting all the template parameters by their values.
 *
 * Inserts all the methods, fields, constructors, initialization blocks (if
 * target is a class), inner types, super class and super interfaces.
 *
 * Note!
 * This algorithm does NOT handle interfaces or annotations
 * {@link Template}, {@link spoon.template.Local}, {@link TemplateParameter} or {@link Parameter}
 * in a special way, it means they all will be added to the generated type too.
 * If you do not want to add them then clone your templateOfType and remove these nodes from that model before.
 *
 * @param qualifiedTypeName
 * 		the qualified name of the new type
 * @param templateOfType
 * 		the model used as source of generation.
 * @param templateParameters
 * 		the substitution parameters
 */
@SuppressWarnings("unchecked")
public static <T extends CtType<?>> T createTypeFromTemplate(String qualifiedTypeName, CtType<?> templateOfType, Map<String, Object> templateParameters) {
    final Factory f = templateOfType.getFactory();
    CtTypeReference<T> typeRef = f.Type().createReference(qualifiedTypeName);
    CtPackage targetPackage = f.Package().getOrCreate(typeRef.getPackage().getSimpleName());
    final Map<String, Object> extendedParams = new HashMap<String, Object>(templateParameters);
    extendedParams.put(templateOfType.getSimpleName(), typeRef);
    List<CtType<?>> generated = (List) new SubstitutionVisitor(f, extendedParams).substitute(templateOfType.clone());
    for (CtType<?> ctType : generated) {
        targetPackage.addType(ctType);
    }
    return (T) typeRef.getTypeDeclaration();
}
Also used : HashMap(java.util.HashMap) Factory(spoon.reflect.factory.Factory) SubstitutionVisitor(spoon.support.template.SubstitutionVisitor) CtType(spoon.reflect.declaration.CtType) CtPackage(spoon.reflect.declaration.CtPackage) List(java.util.List)

Example 5 with SubstitutionVisitor

use of spoon.support.template.SubstitutionVisitor in project spoon by INRIA.

the class Substitution method substitute.

/**
 * Substitutes all the template parameters in the first template element
 * annotated with an instance of the given annotation type.
 *
 * @param targetType
 *            the target type
 * @param template
 *            the template instance
 * @param annotationType
 *            the annotation type
 * @return the element where all the template parameters has be substituted
 *         by their values
 */
// public static <E extends CtElement> E substitute(
// CtSimpleType<?> targetType, Template template,
// Class<? extends Annotation> annotationType) {
// CtClass<? extends Template> c = targetType.getFactory().Class
// .get(template.getClass());
// E element = (E) c.getAnnotatedChildren(annotationType).get(0);
// if (element == null)
// return null;
// if (targetType == null)
// throw new RuntimeException("target is null in substitution");
// E result = CtCloner.clone(element);
// new SubstitutionVisitor(targetType.getFactory(), targetType, template)
// .scan(result);
// return result;
// }
/**
 * Substitutes all the template parameters in a given template type and
 * returns the resulting type.
 *
 * @param template
 * 		the template instance (holds the parameter values)
 * @param templateType
 * 		the template type
 * @return a copy of the template type where all the parameters has been
 * substituted
 */
public static <T extends CtType<?>> T substitute(Template<?> template, T templateType) {
    T result = (T) templateType.clone();
    result.setPositions(null);
    // result.setParent(templateType.getParent());
    new SubstitutionVisitor(templateType.getFactory(), result, template).substitute(result);
    return result;
}
Also used : SubstitutionVisitor(spoon.support.template.SubstitutionVisitor)

Aggregations

SubstitutionVisitor (spoon.support.template.SubstitutionVisitor)5 HashMap (java.util.HashMap)2 SpoonException (spoon.SpoonException)2 Factory (spoon.reflect.factory.Factory)2 IdentityHashMap (java.util.IdentityHashMap)1 List (java.util.List)1 Test (org.junit.Test)1 Launcher (spoon.Launcher)1 CtInvocation (spoon.reflect.code.CtInvocation)1 CtStatement (spoon.reflect.code.CtStatement)1 CtTry (spoon.reflect.code.CtTry)1 CtMethod (spoon.reflect.declaration.CtMethod)1 CtPackage (spoon.reflect.declaration.CtPackage)1 CtType (spoon.reflect.declaration.CtType)1 FileSystemFile (spoon.support.compiler.FileSystemFile)1