Skip to content

Commit

Permalink
refactor: check everywhere that Template is on source path of builder (
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky authored and monperrus committed Nov 17, 2016
1 parent cac5ade commit 204d9aa
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 45 deletions.
13 changes: 1 addition & 12 deletions src/main/java/spoon/template/AbstractTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.lang.reflect.Field;

import spoon.SpoonException;
import spoon.processing.FactoryAccessor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.factory.Factory;
import spoon.support.template.Parameters;
Expand Down Expand Up @@ -56,16 +55,6 @@ public boolean isValid() {
* returns a Spoon factory object from the first template parameter that contains one
*/
public Factory getFactory() {
try {
for (Field f : Parameters.getAllTemplateParameterFields(this.getClass())) {
if (f.get(this) != null && f.get(this) instanceof FactoryAccessor) {
return ((FactoryAccessor) f.get(this)).getFactory();
}
}
} catch (Exception e) {
throw new SpoonException(e);
}
throw new TemplateException("no factory found in this template");
return Substitution.getFactory(this);
}

}
3 changes: 1 addition & 2 deletions src/main/java/spoon/template/BlockTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ public BlockTemplate() {
}

public CtBlock<?> apply(CtType<?> targetType) {
CtClass<? extends BlockTemplate> c;
c = targetType.getFactory().Class().get(this.getClass());
CtClass<? extends BlockTemplate> c = Substitution.getTemplateCtClass(targetType, this);
return Substitution.substitute(targetType, this, getBlock(c));
}

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/spoon/template/ExpressionTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,8 @@ public ExpressionTemplate() {

@SuppressWarnings("unchecked")
public CtExpression<T> apply(CtType<?> targetType) {
CtClass<? extends ExpressionTemplate<?>> c;
CtBlock<?> b;
c = targetType.getFactory().Class().get(this.getClass());
b = Substitution.substitute(targetType, this, getExpressionBlock(c));
CtClass<? extends ExpressionTemplate<?>> c = Substitution.getTemplateCtClass(targetType, this);
CtBlock<?> b = Substitution.substitute(targetType, this, getExpressionBlock(c));
return ((CtReturn<T>) b.getStatements().get(0)).getReturnedExpression();
}

Expand Down
21 changes: 2 additions & 19 deletions src/main/java/spoon/template/StatementTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
*/
package spoon.template;

import spoon.SpoonException;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.support.template.SubstitutionVisitor;

/**
Expand All @@ -42,25 +40,10 @@ public StatementTemplate() {
}

public CtStatement apply(CtType<?> targetType) {
CtClass<?> c;
Factory factory;

// we first need a factory
if (targetType != null) {
// if it's template with reference replacement
factory = targetType.getFactory();
} else {
// else we have at least one template parameter with a factory
factory = getFactory();
}

c = factory.Class().get(this.getClass());
if (c.isShadow()) {
throw new SpoonException("The template " + this.getClass().getName() + " is not part of model. Add template sources to spoon template path.");
}
CtClass<?> c = Substitution.getTemplateCtClass(targetType, this);
// we substitute the first statement of method statement
CtStatement result = c.getMethod("statement").getBody().getStatements().get(0).clone();
new SubstitutionVisitor(factory, targetType, this).scan(result);
new SubstitutionVisitor(c.getFactory(), targetType, this).scan(result);
return result;
}

Expand Down
71 changes: 63 additions & 8 deletions src/main/java/spoon/template/Substitution.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package spoon.template;

import spoon.SpoonException;
import spoon.processing.FactoryAccessor;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtStatement;
Expand All @@ -29,13 +31,15 @@
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeMember;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtPackageReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.filter.ReferenceTypeFilter;
import spoon.support.template.Parameters;
import spoon.support.template.SubstitutionVisitor;

import java.lang.reflect.Field;
import java.util.List;

/**
Expand All @@ -60,7 +64,7 @@ private Substitution() {
*/
public static <T extends Template<?>> void insertAll(CtType<?> targetType, T template) {

CtClass<T> templateClass = targetType.getFactory().Class().get(template.getClass());
CtClass<T> templateClass = getTemplateCtClass(targetType, template);
// insert all the interfaces
for (CtTypeReference<?> t : templateClass.getSuperInterfaces()) {
if (!t.equals(targetType.getFactory().Type().createReference(Template.class))) {
Expand Down Expand Up @@ -154,7 +158,7 @@ public static <T extends Template<?>> void insertAll(CtType<?> targetType, T tem
*/
public static void insertAllSuperInterfaces(CtType<?> targetType, Template<?> template) {

CtClass<? extends Template<?>> sourceClass = targetType.getFactory().Class().get(template.getClass());
CtClass<? extends Template<?>> sourceClass = getTemplateCtClass(targetType, template);
// insert all the interfaces
for (CtTypeReference<?> t : sourceClass.getSuperInterfaces()) {
if (!t.equals(targetType.getFactory().Type().createReference(Template.class))) {
Expand Down Expand Up @@ -195,7 +199,7 @@ public static void insertAllSuperInterfaces(CtType<?> targetType, Template<?> te
*/
public static void insertAllMethods(CtType<?> targetType, Template<?> template) {

CtClass<?> sourceClass = targetType.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetType, template);
// insert all the methods
for (CtMethod<?> m : sourceClass.getMethods()) {
if (m.getAnnotation(Local.class) != null) {
Expand All @@ -220,7 +224,7 @@ public static void insertAllMethods(CtType<?> targetType, Template<?> template)
*/
public static void insertAllFields(CtType<?> targetType, Template<?> template) {

CtClass<?> sourceClass = targetType.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetType, template);
// insert all the fields
for (CtTypeMember typeMember: sourceClass.getTypeMembers()) {
if (!(typeMember instanceof CtField)) {
Expand Down Expand Up @@ -251,7 +255,7 @@ public static void insertAllFields(CtType<?> targetType, Template<?> template) {
*/
public static void insertAllConstructors(CtType<?> targetType, Template<?> template) {

CtClass<?> sourceClass = targetType.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetType, template);
// insert all the constructors
if (targetType instanceof CtClass) {
for (CtConstructor<?> c : sourceClass.getConstructors()) {
Expand Down Expand Up @@ -368,7 +372,7 @@ public static <T> CtConstructor<T> insertConstructor(CtClass<T> targetClass, Tem
* the template parameters substituted
*/
public static CtBlock<?> substituteMethodBody(CtClass<?> targetClass, Template<?> template, String executableName, CtTypeReference<?>... parameterTypes) {
CtClass<?> sourceClass = targetClass.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetClass, template);
CtExecutable<?> sourceExecutable = executableName.equals(template.getClass().getSimpleName())
? sourceClass.getConstructor(parameterTypes)
: sourceClass.getMethod(executableName, parameterTypes);
Expand All @@ -393,7 +397,7 @@ public static CtBlock<?> substituteMethodBody(CtClass<?> targetClass, Template<?
* the template parameters substituted
*/
public static CtStatement substituteStatement(CtClass<?> targetClass, Template<?> template, int statementIndex, String executableName, CtTypeReference<?>... parameterTypes) {
CtClass<?> sourceClass = targetClass.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetClass, template);
CtExecutable<?> sourceExecutable = executableName.equals(template.getClass().getSimpleName())
? sourceClass.getConstructor(parameterTypes)
: sourceClass.getMethod(executableName, parameterTypes);
Expand All @@ -415,7 +419,7 @@ public static CtStatement substituteStatement(CtClass<?> targetClass, Template<?
*/

public static CtExpression<?> substituteFieldDefaultExpression(CtType<?> targetType, Template<?> template, String fieldName) {
CtClass<?> sourceClass = targetType.getFactory().Class().get(template.getClass());
CtClass<?> sourceClass = getTemplateCtClass(targetType, template);
CtField<?> sourceField = sourceClass.getField(fieldName);
return substitute(targetType, template, sourceField.getDefaultExpression());
}
Expand Down Expand Up @@ -533,4 +537,55 @@ public static void redirectTypeReferences(CtElement element, CtTypeReference<?>
}
}

/**
* @param targetType - the element which is going to receive the model produced by the template.
* It is needed here just to provide the spoon factory, which contains the model of the template
*
* @param template - java instance of the template
*
* @return - CtClass from the already built spoon model, which represents the template
*/
static <T> CtClass<T> getTemplateCtClass(CtType<?> targetType, Template<?> template) {
Factory factory;
// we first need a factory
if (targetType != null) {
// if it's template with reference replacement
factory = targetType.getFactory();
} else {
// else we have at least one template parameter with a factory
factory = getFactory(template);
}
return getTemplateCtClass(factory, template);
}

/**
* @param factory - the factory, which contains the model of the template
*
* @param template - java instance of the template
*
* @return - CtClass from the already built spoon model, which represents the template
*/
static <T> CtClass<T> getTemplateCtClass(Factory factory, Template<?> template) {
CtClass<T> c = factory.Class().get(template.getClass());
if (c.isShadow()) {
throw new SpoonException("The template " + template.getClass().getName() + " is not part of model. Add template sources to spoon template path.");
}
return c;
}

/**
* returns a Spoon factory object from the first template parameter that contains one
*/
static Factory getFactory(Template<?> template) {
try {
for (Field f : Parameters.getAllTemplateParameterFields(template.getClass())) {
if (f.get(template) != null && f.get(template) instanceof FactoryAccessor) {
return ((FactoryAccessor) f.get(template)).getFactory();
}
}
} catch (Exception e) {
throw new SpoonException(e);
}
throw new TemplateException("no factory found in template " + template.getClass().getName());
}
}

0 comments on commit 204d9aa

Please sign in to comment.