package fr.inria.gforge.spoon.transformation.bound.processing;

import fr.inria.gforge.spoon.transformation.bound.annotation.Bound;
import fr.inria.gforge.spoon.transformation.bound.template.BoundTemplate;
import spoon.processing.AbstractAnnotationProcessor;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtParameter;
import spoon.template.Template;

public class BoundTemplateProcessor extends AbstractAnnotationProcessor<Bound, CtParameter<?>> {

	public void process(Bound annotation, CtParameter<?> element) {
		// Is to be process?
		CtExecutable<?> e = element.getParent();
		if (e.getBody() == null) {
			return;
		}

		// Use template.
		CtClass<?> type = e.getParent(CtClass.class);
		Template t = new BoundTemplate(getFactory().Type().createReference(Double.class), element.getSimpleName(), annotation.min(), annotation.max());
		final CtBlock apply = (CtBlock) t.apply(type);

		// Apply transformation.
		for (int i = apply.getStatements().size() - 1; i >= 0; i--) {
			final CtStatement statement = apply.getStatement(i);
			statement.delete();
			e.getBody().insertBegin(statement);
		}
	}
}