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);
}
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);
}
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);
}
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();
}
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;
}
Aggregations